You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 11 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 11 години
преди 11 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 12 години
преди 11 години
преди 12 години
преди 12 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
  2. # MIT License. See license.txt
  3. from __future__ import unicode_literals
  4. """
  5. Contributing:
  6. 1. Add the .csv file
  7. 2. Run import
  8. 3. Then run translate
  9. """
  10. # loading
  11. # doctype, page, report
  12. # boot(startup)
  13. # wn.require
  14. # webnotes._
  15. import webnotes, os, re, codecs, json
  16. def get_user_lang(user=None):
  17. if not user:
  18. user = webnotes.session.user
  19. return get_lang_dict().get(webnotes.conn.get_value("Profile", user, "language") or "english")
  20. def get_all_languages():
  21. return [a.split()[0] for a in get_lang_info()]
  22. def get_lang_dict():
  23. return dict([[a[1], a[0]] for a in [a.split() for a in get_lang_info()]])
  24. def get_lang_info():
  25. return webnotes.cache().get_value("langinfo",
  26. lambda:webnotes.get_file_items(os.path.join(webnotes.local.sites_path, "languages.txt")))
  27. def rebuild_all_translation_files():
  28. for lang in get_all_languages():
  29. for app in get_all_apps():
  30. write_translations_file(app, lang)
  31. def write_translations_file(app, lang, full_dict=None):
  32. tpath = webnotes.get_pymodule_path(app, "translations")
  33. webnotes.create_folder(tpath)
  34. write_csv_file(os.path.join(tpath, lang + ".csv"),
  35. get_messages_for_app(app), full_dict or get_full_dict(lang))
  36. def get_dict(fortype, name=None):
  37. fortype = fortype.lower()
  38. cache = webnotes.cache()
  39. cache_key = "translation_assets:" + webnotes.local.lang
  40. asset_key = fortype + ":" + (name or "-")
  41. translation_assets = cache.get_value(cache_key) or {}
  42. if not asset_key in translation_assets:
  43. if fortype=="doctype":
  44. messages = get_messages_from_doctype(name)
  45. elif fortype=="page":
  46. messages = get_messages_from_page(name)
  47. elif fortype=="report":
  48. messages = get_messages_from_report(name)
  49. elif fortype=="include":
  50. messages = get_messages_from_include_files()
  51. elif fortype=="jsfile":
  52. messages = get_messages_from_file(name)
  53. translation_assets[asset_key] = make_dict_from_messages(messages)
  54. cache.set_value(cache_key, translation_assets)
  55. return translation_assets[asset_key]
  56. def add_lang_dict(code):
  57. messages = extract_messages_from_code(code)
  58. code += "\n\n$.extend(wn._messages, %s)" % json.dumps(make_dict_from_messages(messages))
  59. return code
  60. def make_dict_from_messages(messages, full_dict=None):
  61. out = {}
  62. if full_dict==None:
  63. full_dict = get_full_dict(webnotes.local.lang)
  64. for m in messages:
  65. if m in full_dict:
  66. out[m] = full_dict[m]
  67. return out
  68. def get_lang_js(fortype, name):
  69. return "\n\n$.extend(wn._messages, %s)" % json.dumps(get_dict(fortype, name))
  70. def get_full_dict(lang):
  71. if lang == "en": return {}
  72. return webnotes.cache().get_value("lang:" + lang, lambda:load_lang(lang))
  73. def load_lang(lang, apps=None):
  74. out = {}
  75. for app in (apps or webnotes.get_all_apps(True)):
  76. path = os.path.join(webnotes.get_pymodule_path(app), "translations", lang + ".csv")
  77. if os.path.exists(path):
  78. cleaned = dict([item for item in dict(read_csv_file(path)).iteritems() if item[1]])
  79. out.update(cleaned)
  80. return out
  81. def clear_cache():
  82. cache = webnotes.cache()
  83. cache.delete_value("langinfo")
  84. for lang in get_all_languages():
  85. cache.delete_value("lang:" + lang)
  86. cache.delete_value("translation_assets:" + lang)
  87. def get_messages_for_app(app):
  88. messages = []
  89. modules = ", ".join(['"{}"'.format(m.title().replace("_", " ")) \
  90. for m in webnotes.local.app_modules[app]])
  91. # doctypes
  92. for name in webnotes.conn.sql_list("""select name from tabDocType
  93. where module in ({})""".format(modules)):
  94. messages.extend(get_messages_from_doctype(name))
  95. # pages
  96. for name in webnotes.conn.sql_list("""select name from tabPage
  97. where module in ({})""".format(modules)):
  98. messages.extend(get_messages_from_page(name))
  99. # reports
  100. for name in webnotes.conn.sql_list("""select tabReport.name from tabDocType, tabReport
  101. where tabReport.ref_doctype = tabDocType.name
  102. and tabDocType.module in ({})""".format(modules)):
  103. messages.extend(get_messages_from_report(name))
  104. # app_include_files
  105. messages.extend(get_messages_from_include_files(app))
  106. # server_messages
  107. messages.extend(get_server_messages(app))
  108. return list(set(messages))
  109. def get_messages_from_doctype(name):
  110. messages = []
  111. meta = webnotes.get_doctype(name)
  112. messages = [meta[0].name, meta[0].description, meta[0].module]
  113. for d in meta.get({"doctype":"DocField"}):
  114. messages.extend([d.label, d.description])
  115. if d.fieldtype=='Select' and d.options \
  116. and not d.options.startswith("link:") \
  117. and not d.options.startswith("attach_files:"):
  118. options = d.options.split('\n')
  119. if not "icon" in options[0]:
  120. messages.extend(options)
  121. # extract from js, py files
  122. doctype_file_path = webnotes.get_module_path(meta[0].module, "doctype", meta[0].name, meta[0].name)
  123. messages.extend(get_messages_from_file(doctype_file_path + ".js"))
  124. return clean(messages)
  125. def get_messages_from_page(name):
  126. return get_messages_from_page_or_report("Page", name)
  127. def get_messages_from_report(name):
  128. report = webnotes.doc("Report", name)
  129. messages = get_messages_from_page_or_report("Report", name,
  130. webnotes.conn.get_value("DocType", report.ref_doctype, "module"))
  131. if report.query:
  132. messages.extend(re.findall('"([^:,^"]*):', report.query))
  133. messages.append(report.report_name)
  134. return clean(messages)
  135. def get_messages_from_page_or_report(doctype, name, module=None):
  136. if not module:
  137. module = webnotes.conn.get_value(doctype, name, "module")
  138. file_path = webnotes.get_module_path(module, doctype, name, name)
  139. messages = get_messages_from_file(file_path + ".js")
  140. return clean(messages)
  141. def get_server_messages(app):
  142. messages = []
  143. for basepath, folders, files in os.walk(webnotes.get_pymodule_path(app)):
  144. for dontwalk in (".git", "public", "locale"):
  145. if dontwalk in folders: folders.remove(dontwalk)
  146. for f in files:
  147. if f.endswith(".py") or f.endswith(".html"):
  148. messages.extend(get_messages_from_file(os.path.join(basepath, f)))
  149. return clean(messages)
  150. def get_messages_from_include_files(app_name=None):
  151. messages = []
  152. hooks = webnotes.get_hooks(app_name)
  153. for file in (hooks.app_include_js or []) + (hooks.web_include_js or []):
  154. messages.extend(get_messages_from_file(os.path.join(webnotes.local.sites_path, file)))
  155. return messages
  156. def get_messages_from_file(path):
  157. """get list of messages from a code file"""
  158. if os.path.exists(path):
  159. with open(path, 'r') as sourcefile:
  160. return extract_messages_from_code(sourcefile.read(), path.endswith(".py"))
  161. else:
  162. return []
  163. def extract_messages_from_code(code, is_py=False):
  164. messages = []
  165. messages += re.findall('_\("([^"]*)"\)', code)
  166. messages += re.findall("_\('([^']*)'\)", code)
  167. if is_py:
  168. messages += re.findall('_\("{3}([^"]*)"{3}.*\)', code, re.S)
  169. return messages
  170. def clean(messages):
  171. return filter(lambda t: t if t else None, list(set(messages)))
  172. def read_csv_file(path):
  173. from csv import reader
  174. with codecs.open(path, 'r', 'utf-8') as msgfile:
  175. data = msgfile.read()
  176. data = reader([r.encode('utf-8') for r in data.splitlines()])
  177. newdata = [[unicode(val, 'utf-8') for val in row] for row in data]
  178. return newdata
  179. def write_csv_file(path, app_messages, lang_dict):
  180. app_messages.sort()
  181. from csv import writer
  182. with open(path, 'w') as msgfile:
  183. w = writer(msgfile)
  184. for m in app_messages:
  185. w.writerow([m.encode('utf-8'), lang_dict.get(m, '').encode('utf-8')])
  186. def get_untranslated(lang, untranslated_file):
  187. """translate objects using Google API. Add you own API key for translation"""
  188. clear_cache()
  189. apps = webnotes.get_all_apps(True)
  190. messages = []
  191. untranslated = []
  192. for app in apps:
  193. messages.extend(get_messages_for_app(app))
  194. full_dict = get_full_dict(lang)
  195. for m in messages:
  196. if not full_dict.get(m):
  197. untranslated.append(m)
  198. if untranslated:
  199. print str(len(untranslated)) + " missing translations of " + str(len(messages))
  200. with open(untranslated_file, "w") as f:
  201. f.write("\n".join(untranslated))
  202. else:
  203. print "all translated!"
  204. def update_translations(lang, untranslated_file, translated_file):
  205. clear_cache()
  206. full_dict = get_full_dict(lang)
  207. full_dict.update(dict(zip(webnotes.get_file_items(untranslated_file),
  208. webnotes.get_file_items(translated_file))))
  209. for app in webnotes.get_all_apps(True):
  210. write_translations_file(app, lang, full_dict)
  211. def google_translate(lang, untranslated):
  212. import requests
  213. if untranslated:
  214. response = requests.get("""https://www.googleapis.com/language/translate/v2""",
  215. params = {
  216. "key": webnotes.conf.google_api_key,
  217. "source": "en",
  218. "target": lang,
  219. "q": "\n".join(untranslated)
  220. })
  221. data = response.json()
  222. if "error" in data:
  223. print data
  224. translated = data["data"]["translations"][0]["translatedText"]
  225. if translated:
  226. return dict(zip(untranslated, translated))
  227. else:
  228. print "unable to translate"
  229. return {}