From b834d3ea2c568542c8f1243eb6108022c787f437 Mon Sep 17 00:00:00 2001 From: Midgard Date: Mon, 9 Dec 2024 02:57:36 +0100 Subject: [PATCH] Initial commit --- README | 2 ++ find.py | 57 ++++++++++++++++++++++++++++++++++++++++ found.txt | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+) create mode 100644 README create mode 100755 find.py create mode 100644 found.txt diff --git a/README b/README new file mode 100644 index 0000000..a2db790 --- /dev/null +++ b/README @@ -0,0 +1,2 @@ +Do something like +./find.py ~/dev/mapcomplete > found.txt diff --git a/find.py b/find.py new file mode 100755 index 0000000..5c1a664 --- /dev/null +++ b/find.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 + +import os +import sys +import json +import subprocess + + + +if len(sys.argv) != 2 or sys.argv[1].startswith("-"): + print(f"Usage: {sys.argv[0]} ", file=sys.stderr) + sys.exit(1) + +os.chdir(sys.argv[1]) + +if subprocess.run(["rg", "--version"], check=False, stdout=subprocess.DEVNULL).returncode != 0: + # Regular grep doesn't suffice, we rely on ripgrep's functionality to honour .gitignore + print("rg (ripgrep) is not found in PATH or not functional", file=sys.stderr) + sys.exit(1) + + +with open("langs/en.json", "r", encoding="utf-8") as fh: + translations = json.load(fh) + + +def walk(obj, prefix): + for k, v in obj.items(): + if isinstance(v, str): + yield (f"{prefix}{k}", k) + else: + yield from walk(v, f"{prefix}{k}.") + + +for fqkey, key in walk(translations, ""): + print(f" Checking {key}", file=sys.stderr) + p = subprocess.run( + [ + "rg", + "--no-config", + "--iglob=!langs", + "--fixed-strings", "--max-count=1", + "--", key + ], + check=False, stdout=subprocess.DEVNULL + ) + + if p.returncode == 0: + # String is used + pass + + elif p.returncode == 1: + # String is not used + print(fqkey) + + else: + # grep encountered an error + print(f"Error while checking for {key}", file=sys.stderr) diff --git a/found.txt b/found.txt new file mode 100644 index 0000000..0d02a14 --- /dev/null +++ b/found.txt @@ -0,0 +1,78 @@ +communityIndex.notAvailable +delete.explanations.retagNoOtherThemes +delete.explanations.retagOtherThemes +delete.explanations.selectReason +delete.isChanged +delete.loginToDelete +favourite.loginNeeded +favourite.panelIntro +general.add.confirmButton +general.add.confirmWarning +general.add.warnVisibleForEveryone +general.attribution.mapDataByOsm +general.backToMap +general.fewChangesBefore +general.getStartedLogin +general.getStartedNewAccount +general.goToInbox +general.loginOnlyNeededToEdit +general.morescreen.requestATheme +general.nameInlineQuestion +general.noMatchingMapping +general.noNameCategory +general.notValid +general.openStreetMapIntro +general.openTheMapAtGeolocation +general.opening_hours.on_weekends +general.osmLinkTooltip +general.questions.emailIs +general.questions.emailOf +general.questions.phoneNumberIs +general.questions.phoneNumberOf +general.questions.websiteIs +general.questions.websiteOf +general.readYourMessages +general.search.searchShort +general.sharescreen.openInOtherApplications +general.sharescreen.thanksForSharing +general.welcomeBack +general.wikipedia.addEntry +general.wikipedia.createNewWikidata +general.wikipedia.noWikipediaPage +general.wikipedia.wikipediaboxTitle +hotkeyDocumentation.selectMapnik +image.currentLicense +image.dontDelete +image.panoramax.report.blur_excess +image.panoramax.report.blur_missing +image.panoramax.report.mislocated +image.panoramax.report.picture_low_quality +image.uploadDone +image.uploadMultipleDone +image.uploadingMultiple +image.uploadingPicture +importLayer.alreadyMapped +importLayer.importButton +importLayer.importHandled +importLayer.nearbyImagesIntro +importLayer.popupTitle +index.featuredThemeTitle +index.pickTheme +move.loginToMove +move.moveTitle +move.selectReason +move.whyMove +notes.loginToAddPicture +notes.noteIsPublic +notes.notesLayerMustBeEnabled +plantDetection.seeInfo +reviews.name_required +reviews.title_singular +reviews.write_a_comment +split.splitTitle +translations.allMissing +translations.notImmediate +userinfo.gotoInbox +userinfo.gotoSettings +userinfo.noDescription +validation.slope.inputIncorrect