patch_localizations.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. #!/usr/bin/env python3
  2. import os
  3. import re
  4. base = os.path.join(os.path.dirname(__file__), "..", "App for Indeed")
  5. def set_key(content: str, key: str, value: str) -> str:
  6. esc_key = key.replace("\\", "\\\\").replace('"', '\\"').replace("\n", "\\n")
  7. esc_val = value.replace("\\", "\\\\").replace('"', '\\"').replace("\n", "\\n")
  8. pattern = re.compile(r'"' + re.escape(esc_key) + r'"\s*=\s*"(?:\\.|[^"\\])*"\s*;')
  9. repl = f'"{esc_key}" = "{esc_val}";'
  10. if pattern.search(content):
  11. return pattern.sub(repl, content, count=1)
  12. return content.rstrip() + f'\n"{esc_key}" = "{esc_val}";\n'
  13. LOCALE_PATCHES = {
  14. "ar": {
  15. "App for Indeed": "تطبيق Indeed",
  16. "About %@": "حول %@",
  17. "Hide %@": "إخفاء %@",
  18. "Quit %@": "إنهاء %@",
  19. "Preferences…": "التفضيلات…",
  20. "Assistant is searching": "المساعد يبحث",
  21. "Indeed": "إنديد",
  22. "Google": "جوجل",
  23. "There was nothing to restore for this Apple ID.": "لا يوجد شيء لاستعادته لمعرّف Apple هذا.",
  24. "Check out %@ on the Mac App Store.": "اطّلع على %@ في متجر Mac للتطبيقات.",
  25. "Check out %@ on the Mac App Store:\n%@": "اطّلع على %@ في متجر Mac للتطبيقات:\n%@",
  26. "match": "تطابق",
  27. "matches": "تطابقات",
  28. "Website": "موقع الويب",
  29. "Impact": "الأثر",
  30. "Contact": "التواصل",
  31. "Modern": "عصري",
  32. "System": "النظام",
  33. "Description": "الوصف",
  34. "CV": "السيرة الذاتية",
  35. },
  36. "de": {
  37. "App for Indeed": "App für Indeed",
  38. "About %@": "Über %@",
  39. "Hide %@": "%@ ausblenden",
  40. "Quit %@": "%@ beenden",
  41. "Preferences…": "Einstellungen…",
  42. "Assistant is searching": "Assistent sucht",
  43. "Premium": "Premium-Bereich",
  44. "Pro": "Pro-Version",
  45. "Loading premium plans from the App Store…": "Lade Premium-Pläne aus dem Mac App Store…",
  46. "That subscription isn’t available from the App Store right now.": "Dieses Abonnement ist derzeit nicht im Mac App Store verfügbar.",
  47. "This subscription isn't available in your App Store region.": "Dieses Abonnement ist in Ihrer Mac-App-Store-Region nicht verfügbar.",
  48. "Check out %@ on the Mac App Store.": "Entdecken Sie %@ im Mac App Store.",
  49. "Check out %@ on the Mac App Store:\n%@": "Entdecken Sie %@ im Mac App Store:\n%@",
  50. "e.g., Google": "z. B. Google",
  51. },
  52. "el": {
  53. "App for Indeed": "Εφαρμογή για Indeed",
  54. "About %@": "Σχετικά με %@",
  55. "Hide %@": "Απόκρυψη %@",
  56. "Quit %@": "Έξοδος από %@",
  57. "Preferences…": "Προτιμήσεις…",
  58. "Assistant is searching": "Ο βοηθός αναζητά",
  59. },
  60. "es": {
  61. "App for Indeed": "App para Indeed",
  62. "About %@": "Acerca de %@",
  63. "Hide %@": "Ocultar %@",
  64. "Quit %@": "Salir de %@",
  65. "Preferences…": "Preferencias…",
  66. "Assistant is searching": "El asistente está buscando",
  67. "Premium": "Premium",
  68. "Pro": "Profesional",
  69. "There was nothing to restore for this Apple ID.": "No había nada que restaurar para este ID de Apple.",
  70. "Circuit": "Circuito",
  71. "Quorum": "Quórum",
  72. "Regent": "Regente",
  73. "Description": "Descripción",
  74. "Principal": "Principal",
  75. "Modern": "Moderno",
  76. "System": "Sistema",
  77. },
  78. "es-MX": {
  79. "App for Indeed": "App para Indeed",
  80. "About %@": "Acerca de %@",
  81. "Hide %@": "Ocultar %@",
  82. "Quit %@": "Salir de %@",
  83. "Preferences…": "Preferencias…",
  84. "Assistant is searching": "El asistente está buscando",
  85. "Premium": "Premium",
  86. "Pro": "Profesional",
  87. "There was nothing to restore for this Apple ID.": "No había nada que restaurar para este ID de Apple.",
  88. "Quorum": "Quórum",
  89. "Regent": "Regente",
  90. "Modern": "Moderno",
  91. },
  92. "fi": {
  93. "App for Indeed": "Sovellus Indeedille",
  94. "About %@": "Tietoja: %@",
  95. "Hide %@": "Piilota %@",
  96. "Quit %@": "Lopeta %@",
  97. "Preferences…": "Asetukset…",
  98. "Assistant is searching": "Avustaja hakee",
  99. "match": "osuma",
  100. "matches": "osumaa",
  101. "Website": "Verkkosivusto",
  102. "Modern": "Moderni",
  103. "/ week": "/ viikko",
  104. "Quorum": "Kvoorumi",
  105. "Regent": "Regentti",
  106. },
  107. "fr": {
  108. "App for Indeed": "App pour Indeed",
  109. "About %@": "À propos de %@",
  110. "Hide %@": "Masquer %@",
  111. "Quit %@": "Quitter %@",
  112. "Preferences…": "Réglages…",
  113. "Assistant is searching": "L’assistant recherche",
  114. "Premium": "Abonnement premium",
  115. "Pro": "Version Pro",
  116. "Upgrade to Pro": "Passer à la version Pro",
  117. "You're on Pro": "Vous utilisez la version Pro",
  118. "Try Pro": "Essayer la version Pro",
  119. "Checking your Pro subscription…": "Vérification de votre abonnement Pro…",
  120. "Circuit": "Circuit",
  121. "Conduit": "Conduit",
  122. "Modern": "Moderne",
  123. "System": "Système",
  124. },
  125. "fr-CA": {
  126. "App for Indeed": "App pour Indeed",
  127. "About %@": "À propos de %@",
  128. "Hide %@": "Masquer %@",
  129. "Quit %@": "Quitter %@",
  130. "Preferences…": "Préférences…",
  131. "Assistant is searching": "L’assistant recherche",
  132. "Premium": "Abonnement premium",
  133. "Pro": "Version Pro",
  134. "Upgrade to Pro": "Passer à la version Pro",
  135. "You're on Pro": "Vous utilisez la version Pro",
  136. "Try Pro": "Essayer la version Pro",
  137. "Modern": "Moderne",
  138. },
  139. "he": {
  140. "App for Indeed": "אפליקציה עבור Indeed",
  141. "About %@": "אודות %@",
  142. "Hide %@": "הסתר %@",
  143. "Quit %@": "צא מ-%@",
  144. "Preferences…": "העדפות…",
  145. "Assistant is searching": "העוזר מחפש",
  146. "Indeed": "אינדיד",
  147. "Google": "גוגל",
  148. "There was nothing to restore for this Apple ID.": "לא היה מה לשחזר עבור מזהה Apple זה.",
  149. "Website": "אתר אינטרנט",
  150. "Modern": "מודרני",
  151. },
  152. "it": {
  153. "App for Indeed": "App per Indeed",
  154. "About %@": "Informazioni su %@",
  155. "Hide %@": "Nascondi %@",
  156. "Quit %@": "Esci da %@",
  157. "Preferences…": "Preferenze…",
  158. "Assistant is searching": "L'assistente sta cercando",
  159. "Premium": "Premium",
  160. "There was nothing to restore for this Apple ID.": "Non c'era nulla da ripristinare per questo ID Apple.",
  161. "Atlas": "Atlante",
  162. "Regent": "Reggente",
  163. "Modern": "Moderno",
  164. "Website": "Sito web",
  165. "Impact": "Impatto",
  166. "Contact": "Contatti",
  167. "match": "corrispondenza",
  168. "matches": "corrispondenze",
  169. "/ week": "/ settimana",
  170. },
  171. "ko": {
  172. "App for Indeed": "Indeed용 앱",
  173. "About %@": "%@ 정보",
  174. "Hide %@": "%@ 숨기기",
  175. "Quit %@": "%@ 종료",
  176. "Preferences…": "환경설정…",
  177. "Assistant is searching": "어시스턴트가 검색 중",
  178. "Google": "구글",
  179. "e.g., Google": "예: 구글",
  180. "There was nothing to restore for this Apple ID.": "이 Apple 계정에 복원할 구독이 없습니다.",
  181. },
  182. "nb": {
  183. "App for Indeed": "App for Indeed",
  184. "About %@": "Om %@",
  185. "Hide %@": "Skjul %@",
  186. "Quit %@": "Avslutt %@",
  187. "Preferences…": "Innstillinger…",
  188. "Assistant is searching": "Assistenten søker",
  189. "Premium": "Premium",
  190. "Website": "Nettsted",
  191. "Modern": "Moderne",
  192. "match": "treff",
  193. "matches": "treff",
  194. "/ week": "/ uke",
  195. "Quorum": "Korum",
  196. },
  197. "nl": {
  198. "App for Indeed": "App voor Indeed",
  199. "About %@": "Over %@",
  200. "Hide %@": "Verberg %@",
  201. "Quit %@": "Sluit %@ af",
  202. "Preferences…": "Voorkeuren…",
  203. "Assistant is searching": "Assistent zoekt",
  204. "match": "overeenkomst",
  205. "matches": "overeenkomsten",
  206. "Website": "Webpagina",
  207. "Impact": "Prestaties",
  208. "Contact": "Contactgegevens",
  209. "e.g., Google": "bijv. Google",
  210. },
  211. "pl": {
  212. "App for Indeed": "Aplikacja dla Indeed",
  213. "About %@": "Informacje o %@",
  214. "Hide %@": "Ukryj %@",
  215. "Quit %@": "Zakończ %@",
  216. "Preferences…": "Ustawienia…",
  217. "Assistant is searching": "Asystent wyszukuje",
  218. "Premium": "Premium",
  219. "There was nothing to restore for this Apple ID.": "Nie było nic do przywrócenia dla tego konta Apple.",
  220. "Quorum": "Kworum",
  221. "Website": "Witryna",
  222. "Modern": "Nowoczesny",
  223. "match": "dopasowanie",
  224. "matches": "dopasowania",
  225. "/ week": "/ tydzień",
  226. },
  227. "pt-BR": {
  228. "App for Indeed": "App para Indeed",
  229. "About %@": "Sobre %@",
  230. "Hide %@": "Ocultar %@",
  231. "Quit %@": "Encerrar %@",
  232. "Preferences…": "Preferências…",
  233. "Assistant is searching": "O assistente está pesquisando",
  234. "Premium": "Premium",
  235. "There was nothing to restore for this Apple ID.": "Não havia nada para restaurar para este ID Apple.",
  236. "Quorum": "Quórum",
  237. "Regent": "Regente",
  238. "Website": "Site",
  239. "Modern": "Moderno",
  240. "match": "correspondência",
  241. "matches": "correspondências",
  242. "/ week": "/ semana",
  243. },
  244. "ru": {
  245. "App for Indeed": "Приложение для Indeed",
  246. "About %@": "О программе «%@»",
  247. "Hide %@": "Скрыть %@",
  248. "Quit %@": "Завершить %@",
  249. "Preferences…": "Настройки…",
  250. "Assistant is searching": "Помощник ищет",
  251. "Indeed": "Индид",
  252. "Pro": "Про",
  253. "There was nothing to restore for this Apple ID.": "Нечего восстанавливать для этой учётной записи Apple.",
  254. "Website": "Веб-сайт",
  255. "Modern": "Современный",
  256. "match": "совпадение",
  257. "matches": "совпадения",
  258. "/ week": "/ неделя",
  259. },
  260. "sv": {
  261. "App for Indeed": "App för Indeed",
  262. "About %@": "Om %@",
  263. "Hide %@": "Dölj %@",
  264. "Quit %@": "Avsluta %@",
  265. "Preferences…": "Inställningar…",
  266. "Assistant is searching": "Assistenten söker",
  267. "Premium": "Premium-abonnemang",
  268. "Pro": "Pro-version",
  269. "Upgrade to Pro": "Uppgradera till Pro-versionen",
  270. "You're on Pro": "Du har Pro-versionen",
  271. "Try Pro": "Prova Pro-versionen",
  272. "Website": "Webbplats",
  273. "Modern": "Modern",
  274. "match": "träff",
  275. "matches": "träffar",
  276. "/ week": "/ vecka",
  277. "Quorum": "Korum",
  278. },
  279. "uk": {
  280. "App for Indeed": "Додаток для Indeed",
  281. "About %@": "Про %@",
  282. "Hide %@": "Сховати %@",
  283. "Quit %@": "Завершити %@",
  284. "Preferences…": "Налаштування…",
  285. "Assistant is searching": "Помічник шукає",
  286. "Indeed": "Індід",
  287. "Website": "Вебсайт",
  288. "Modern": "Сучасний",
  289. },
  290. "vi": {
  291. "App for Indeed": "Ứng dụng cho Indeed",
  292. "About %@": "Giới thiệu về %@",
  293. "Hide %@": "Ẩn %@",
  294. "Quit %@": "Thoát %@",
  295. "Preferences…": "Tùy chọn…",
  296. "Assistant is searching": "Trợ lý đang tìm kiếm",
  297. "There was nothing to restore for this Apple ID.": "Không có gì để khôi phục cho ID Apple này.",
  298. "Website": "Trang web",
  299. "Modern": "Hiện đại",
  300. "match": "kết quả phù hợp",
  301. "matches": "kết quả phù hợp",
  302. "/ week": "/ tuần",
  303. },
  304. "zh-Hans": {
  305. "App for Indeed": "Indeed 应用",
  306. "About %@": "关于%@",
  307. "Hide %@": "隐藏%@",
  308. "Quit %@": "退出%@",
  309. "Preferences…": "偏好设置…",
  310. "Assistant is searching": "助手正在搜索",
  311. "Indeed": "英迪",
  312. "Google": "谷歌",
  313. "e.g., Google": "例如:谷歌",
  314. "There was nothing to restore for this Apple ID.": "此 Apple 账户没有可恢复的内容。",
  315. "Check out %@ on the Mac App Store.": "在 Mac App Store 中查看%@。",
  316. "Check out %@ on the Mac App Store:\n%@": "在 Mac App Store 中查看%@:\n%@",
  317. },
  318. "zh-Hant": {
  319. "App for Indeed": "Indeed 應用程式",
  320. "About %@": "關於%@",
  321. "Hide %@": "隱藏%@",
  322. "Quit %@": "結束%@",
  323. "Preferences…": "偏好設定…",
  324. "Assistant is searching": "助理正在搜尋",
  325. "Indeed": "英迪",
  326. "Google": "谷歌",
  327. "e.g., Google": "例如:谷歌",
  328. "There was nothing to restore for this Apple ID.": "此 Apple 帳號沒有可回復的內容。",
  329. "Website": "網站",
  330. "Modern": "現代",
  331. "match": "相符",
  332. "matches": "相符",
  333. "/ week": "/ 週",
  334. },
  335. }
  336. def main():
  337. for loc, patches in LOCALE_PATCHES.items():
  338. name = patches["App for Indeed"]
  339. info_path = os.path.join(base, f"{loc}.lproj", "InfoPlist.strings")
  340. with open(info_path, "w", encoding="utf-8") as f:
  341. f.write(f"/* Localized bundle display name ({loc}) */\n")
  342. f.write(f'"CFBundleDisplayName" = "{name}";\n')
  343. f.write(f'"CFBundleName" = "{name}";\n')
  344. path = os.path.join(base, f"{loc}.lproj", "Localizable.strings")
  345. with open(path, encoding="utf-8") as f:
  346. content = f.read()
  347. for key, val in patches.items():
  348. content = set_key(content, key, val)
  349. with open(path, "w", encoding="utf-8") as f:
  350. f.write(content)
  351. print(f"Patched {loc}: {len(patches)} keys")
  352. en_info = os.path.join(base, "en.lproj", "InfoPlist.strings")
  353. with open(en_info, "w", encoding="utf-8") as f:
  354. f.write("/* Localized bundle display name (English) */\n")
  355. f.write('"CFBundleDisplayName" = "App for Indeed";\n')
  356. f.write('"CFBundleName" = "App for Indeed";\n')
  357. if __name__ == "__main__":
  358. main()