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