LangArea.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. @Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
  5. @AUTHOR: ASJRD018
  6. @NAME: langer
  7. @software: PyCharm
  8. @DATE: 2019/6/4 11:44
  9. @Version: python3.6
  10. @MODIFY DECORD:ansjer dev
  11. @file: LangArea.py
  12. @Contact: chanjunkai@163.com
  13. """
  14. import json
  15. import requests
  16. from django.db.models import Min, Q
  17. from django.http import HttpResponse
  18. from django.views.generic import TemplateView
  19. from django.views.decorators.csrf import csrf_exempt
  20. from django.utils.decorators import method_decorator
  21. from object.ResponseObject import ResponseObject
  22. from django.contrib.auth.hashers import make_password, check_password
  23. from model.models import UserModel, LangSetModel, LangAreaModel, LangValModel, LangKeyModel, LangKeyClassModel, \
  24. SearchToolBlock, SearchToolKeyModel, LangLocationModel
  25. import time
  26. from object.TokenObject import TokenObject
  27. from django.http import StreamingHttpResponse
  28. class LangAreaView(TemplateView):
  29. def post(self, request, *args, **kwargs):
  30. request.encoding = 'utf-8'
  31. operation = kwargs.get('operation', None)
  32. request_dict = json.loads(request.body.decode('utf-8'))
  33. return self.validate(request_dict, operation)
  34. def get(self, request, *args, **kwargs):
  35. request.encoding = 'utf-8'
  36. request_dict = request.GET
  37. operation = kwargs.get('operation', None)
  38. return self.validate(request_dict, operation)
  39. def validate(self, request_dict, operation):
  40. response = ResponseObject()
  41. token = request_dict.get('token', None)
  42. tko = TokenObject(token)
  43. if tko.code == 0:
  44. userID = tko.userID
  45. user_qs = UserModel.objects.filter(id=userID, username='admin')
  46. if not user_qs.exists():
  47. return response.json(403)
  48. if operation == 'add':
  49. return self.do_add(request_dict, response)
  50. elif operation == 'update':
  51. return self.do_update(request_dict, response)
  52. elif operation == 'delete':
  53. return self.do_delete(request_dict, response)
  54. elif operation == 'query':
  55. return self.do_query(request_dict, response, userID)
  56. elif operation == 'export':
  57. return self.do_export(request_dict, response, userID)
  58. elif operation == 'AITranslation':
  59. return self.ai_translation(request_dict, response)
  60. elif operation == 'AITranslationTest':
  61. return self.ai_translation_test(request_dict, response)
  62. else:
  63. return response.json(414)
  64. else:
  65. return response.json(tko.code)
  66. def do_add(self, request_dict, response):
  67. lang = request_dict.get('lang', None)
  68. if lang:
  69. nowTime = int(time.time())
  70. create_dict = {
  71. 'lang': lang,
  72. 'addTime': nowTime,
  73. 'updTime': nowTime
  74. }
  75. try:
  76. LangAreaModel.objects.create(**create_dict)
  77. except Exception as e:
  78. return response.json(404, repr(e))
  79. else:
  80. return response.json(0)
  81. else:
  82. return response.json(414)
  83. def do_update(self, request_dict, response):
  84. lang = request_dict.get('lang', None)
  85. id = request_dict.get('id', None)
  86. nowTime = int(time.time())
  87. update_dict = {
  88. 'lang': lang,
  89. 'updTime': nowTime
  90. }
  91. try:
  92. LangAreaModel.objects.filter(id=id).update(**update_dict)
  93. except Exception as e:
  94. return response.json(404, repr(e))
  95. else:
  96. return response.json(0)
  97. def do_delete(self, request_dict, response):
  98. id = request_dict.get('id', None)
  99. try:
  100. LangAreaModel.objects.filter(id=id).delete()
  101. except Exception as e:
  102. return response.json(404, repr(e))
  103. else:
  104. return response.json(0)
  105. def do_query(self, request_dict, response, userID):
  106. user_qs = UserModel.objects.filter(id=userID, username='admin')
  107. if not user_qs.exists():
  108. return response.json(403)
  109. la_qs = LangAreaModel.objects.filter().values('lang', 'id')
  110. return response.json(0, list(la_qs))
  111. def do_export(self, request_dict, response, userID):
  112. print("进来了")
  113. id = request_dict.get('id', None)
  114. type = request_dict.get('type', None)
  115. # key_list = LangKeyModel.objects.filter().values_list('word_key', flat=True)
  116. print('id = ' + id)
  117. langType = (1, 3, 5, 7)
  118. if type == 'avss':
  119. langType = (2, 3, 6, 7)
  120. elif type == 'link_ios' or type == 'link_android':
  121. langType = (4, 5, 6, 7)
  122. en_qs = LangKeyModel.objects.filter(langvalmodel__la__id=20, type__in=langType).values('word_key',
  123. 'langvalmodel__word_val')
  124. en_kv = {}
  125. for e in en_qs:
  126. en_kv[e['word_key']] = e['langvalmodel__word_val']
  127. content = ''
  128. if type == 'ios' or type == 'link_ios' or type == 'flutter':
  129. res_qs = LangKeyModel.objects.filter(langvalmodel__la__id=id, type__in=langType). \
  130. values('word_key', 'langvalmodel__word_val')
  131. res = {}
  132. for r in res_qs:
  133. print(r['langvalmodel__word_val'])
  134. if r['langvalmodel__word_val']:
  135. res[r['word_key']] = r['langvalmodel__word_val']
  136. elif en_kv[r['word_key']]:
  137. res[r['word_key']] = en_kv[r['word_key']]
  138. for l in res:
  139. content_val = res[l].replace('"', '\'')
  140. if type == 'ios' or type == 'link_ios':
  141. content = content + '"' + l + '"="' + content_val + '";\n'
  142. else:
  143. content = content + '"' + l + '":"' + content_val + '",\n'
  144. if type == 'flutter':
  145. content = '{\n' + content + '}'
  146. elif type == 'android' or type == 'link_android':
  147. res_qs = LangKeyModel.objects.filter(langvalmodel__la__id=id, type__in=langType). \
  148. values('word_key', 'langvalmodel__word_val').order_by('addTime')
  149. res = {}
  150. for r in res_qs:
  151. if r['langvalmodel__word_val']:
  152. res[r['word_key']] = r['langvalmodel__word_val']
  153. elif en_kv[r['word_key']]:
  154. res[r['word_key']] = en_kv[r['word_key']]
  155. for l in res:
  156. lk = l
  157. lk = lk.replace('.', '_')
  158. lk = lk.replace('\\n', '_')
  159. lk = lk.replace('“', '_')
  160. lk = lk.replace('”', '_')
  161. lk = lk.replace(' ', '_')
  162. lk = lk.replace('\\\'', '_')
  163. lk = lk.replace('\'', '_')
  164. lk = lk.replace('\\', '_')
  165. lk = lk.replace('!', '_')
  166. lk = lk.replace('’', '_')
  167. lk = lk.replace('...', '_')
  168. lk = lk.replace('…', '_')
  169. lk = lk.replace(':', '_')
  170. lk = lk.replace(':', '_')
  171. lk = lk.replace('(', '_')
  172. lk = lk.replace(')', '_')
  173. lk = lk.replace('?', '_')
  174. lk = lk.replace('?', '_')
  175. lk = lk.replace(',', '_')
  176. lk = lk.replace('-', '_')
  177. lk = lk.replace('%', '_')
  178. lk = lk.replace(';', '_')
  179. lk = lk.replace('‘', '_')
  180. lk = lk.replace('&', '&')
  181. if lk[0].isdigit():
  182. lk = lk.replace(lk[0], '_')
  183. # 正则表达式
  184. # re.sub("[a-z]+", "$", "123abc78ab9cdeg00t8")
  185. content_val = res[l].replace("'", "\\'")
  186. content_val = content_val.replace('"', '\\"')
  187. content_val = content_val.replace('&', '&')
  188. content = content + '<string name="' + lk + '">' + content_val + '</string>\n'
  189. elif type == 'avss':
  190. content = self.do_download_avss(id)
  191. elif type == 'new_searchTool':
  192. content = self.do_download_SearchTool(id, 0)
  193. elif type == 'old_searchTool':
  194. content = self.do_download_SearchTool(id, 1)
  195. response = StreamingHttpResponse(content)
  196. response['Content-Type'] = 'application/octet-stream'
  197. response['Content-Disposition'] = 'attachment;filename="lang.txt"'
  198. return response
  199. @classmethod
  200. def ai_translation(cls, request_dict, response):
  201. lang_id = request_dict.get('lang_id', None)
  202. if not lang_id:
  203. return response.json(444)
  204. lang_id = int(lang_id)
  205. # 英文不翻译
  206. if lang_id == 20:
  207. return response.json(0)
  208. try:
  209. # 查询语种
  210. lang_area_qs = LangAreaModel.objects.filter(id=lang_id).values('lang')
  211. if not lang_area_qs.exists():
  212. return response.json(444)
  213. lang = lang_area_qs[0]['lang']
  214. # 查询英文不为空,并根据lk_id去重
  215. lang_val_qs = LangValModel.objects.filter(~Q(word_val=''), Q(la_id=20)).values('lk_id').\
  216. annotate(word_val=Min('word_val')).order_by('lk_id')
  217. if not lang_val_qs.exists():
  218. return response.json(444)
  219. bulk = []
  220. now_time = int(time.time())
  221. # 根据lk_id查询有无对应语种,没有则调用API翻译并保存数据
  222. for lang_val in lang_val_qs:
  223. lk_id = lang_val['lk_id']
  224. lang_qs = LangValModel.objects.filter(la_id=lang_id, lk_id=lk_id).values('word_val')
  225. if not lang_qs.exists():
  226. # 翻译内容不存在,进行AI翻译
  227. word_val_en = lang_val['word_val']
  228. word_val = cls.deepseek_translation(lang, word_val_en)
  229. lang_val_model = LangValModel(
  230. lk_id=lk_id, la_id=lang_id, word_val=word_val, addTime=now_time, updTime=now_time, status=1
  231. )
  232. bulk.append(lang_val_model)
  233. else:
  234. # 翻译内容为空,进行AI翻译
  235. if lang_qs[0]['word_val'] == '':
  236. word_val_en = lang_val['word_val']
  237. word_val = cls.deepseek_translation(lang, word_val_en)
  238. lang_qs.update(word_val=word_val, addTime=now_time, updTime=now_time, status=1)
  239. LangValModel.objects.bulk_create(bulk)
  240. return response.json(0)
  241. except Exception as e:
  242. return response.json(10, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  243. @classmethod
  244. def ai_translation_test(cls, request_dict, response):
  245. lang = request_dict.get('lang')
  246. word_val_en = request_dict.get('word_val_en')
  247. if not all([lang, word_val_en]):
  248. return response.json(444)
  249. try:
  250. word_val = cls.deepseek_translation(lang, word_val_en)
  251. return response.json(0, word_val)
  252. except Exception as e:
  253. return response.json(10, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  254. @staticmethod
  255. def deepseek_translation(lang, word_val_en):
  256. url = "https://maas-cn-southwest-2.modelarts-maas.com/v1/infers/271c9332-4aa6-4ff5-95b3-0cf8bd94c394/v1/chat/completions" # API地址
  257. api_key = "obPL2x_aJKJpm11JLz1GFKTfXcwF_2ra4bdogC1pbFgV7GobDRW3AD6iHPxCvDZqM87buJ3xyT6-bl1xiDV6aQ" # 把yourApiKey替换成已获取的API Key
  258. # Send request.
  259. headers = {
  260. 'Content-Type': 'application/json',
  261. 'Authorization': f'Bearer {api_key}'
  262. }
  263. content = '请将以下英文内容翻译成{},忽略转义符和占位符,直接返回翻译好的内容即可,无需写上注释:{}'.format(lang, word_val_en)
  264. data = {
  265. "model": "DeepSeek-V3", # 模型名称
  266. "max_tokens": 1024, # 最大输出token数
  267. "messages": [
  268. {"role": "system",
  269. "content": "你是一名翻译家"},
  270. {"role": "user", "content": content}
  271. ],
  272. # 是否开启流式推理, 默认为False, 表示不开启流式推理
  273. "stream": False,
  274. # 在流式输出时是否展示使用的token数目。只有当stream为True时改参数才会生效。
  275. # "stream_options": { "include_usage": True },
  276. # 控制采样随机性的浮点数,值较低时模型更具确定性,值较高时模型更具创造性。"0"表示贪婪取样。默认为0.6。
  277. "temperature": 0.6
  278. }
  279. content = ''
  280. # 延迟请求
  281. time.sleep(1.1)
  282. try:
  283. response = requests.post(url, headers=headers, data=json.dumps(data), verify=False, timeout=60)
  284. text = json.loads(response.text)
  285. choices = text.get('choices')
  286. if choices is not None:
  287. content = choices[0]['message']['content']
  288. return content
  289. except Exception as e:
  290. return content
  291. def do_download_avss(self, id):
  292. content = ''
  293. en_result = self.get_area_language(20)
  294. target_result = self.get_area_language(id)
  295. if target_result:
  296. content += '<TS version=\"2.1\" language=\"' + self.get_avss_language(int(id)) + '\">\n'
  297. # keys = result.keys()
  298. keys = en_result.keys()
  299. for key in keys:
  300. content += '<context>\n<name>'
  301. content += key
  302. content += '</name>\n'
  303. messages = None
  304. if target_result.__contains__(key):
  305. messages = target_result[key]
  306. else:
  307. messages = en_result[key]
  308. messageKeys = en_result[key].keys()
  309. for messageKey in messageKeys:
  310. message = None
  311. if messages.__contains__(messageKey):
  312. message = messages[messageKey]
  313. else:
  314. message = en_result[key][messageKey]
  315. # message = messages[messageKey]
  316. content += '<message>\n'
  317. content += '<source>'
  318. content += message['source']
  319. content += '</source>\n'
  320. content += '<translation>'
  321. translation = message['translation']
  322. # if translation is None or translation == '':
  323. # content += '23333'
  324. # else:
  325. content += translation
  326. content += '</translation>\n'
  327. locations = message['locations']
  328. print(message)
  329. for location in locations:
  330. if location['filename'] != '':
  331. content += '<location filename=\"' + location['filename'] + '\" line=\"' + str(
  332. location['line']) + '\"/>\n'
  333. content += '</message>\n'
  334. content += '</context>\n'
  335. content += '</TS>'
  336. return content
  337. else:
  338. print('none')
  339. return content
  340. def get_area_language(self, id):
  341. result = {}
  342. lkc_qs = LangKeyModel.objects.filter(langvalmodel__la__id=id, type__in=(2, 3, 6, 7)).values('word_key',
  343. 'langkeyclassmodel__clazz__name',
  344. 'langvalmodel__word_val',
  345. 'langlocationmodel__filename',
  346. 'langlocationmodel__line').order_by(
  347. 'langkeyclassmodel__clazz__name', 'word_key')
  348. for lkc in lkc_qs:
  349. # print(lkc)
  350. name = lkc['langkeyclassmodel__clazz__name']
  351. source = lkc['word_key']
  352. localtion = {'filename': lkc['langlocationmodel__filename'], 'line': lkc['langlocationmodel__line']}
  353. hasClass = result.__contains__(name)
  354. if not hasClass:
  355. result[name] = {
  356. source: {'source': source, 'translation': lkc['langvalmodel__word_val'], 'locations': [localtion]}}
  357. else:
  358. hasKey = result[name].__contains__(source)
  359. if not hasKey:
  360. result[name][source] = {'source': source, 'translation': lkc['langvalmodel__word_val'],
  361. 'locations': [localtion]}
  362. else:
  363. if localtion not in result[name][source]['locations']:
  364. result[name][source]['locations'].append(localtion)
  365. print(result)
  366. return result
  367. def get_area_language_search(self, id):
  368. result = {}
  369. lkc_qs = LangKeyModel.objects.filter(langvalmodel__la__id=id, project__id=4).values('word_key',
  370. 'searchtoolkeymodel__bk__name',
  371. 'langvalmodel__word_val',
  372. 'langlocationmodel__filename',
  373. 'langlocationmodel__line')
  374. for lkc in lkc_qs:
  375. # print(lkc)
  376. name = lkc['searchtoolkeymodel__bk__name']
  377. hasClass = result.__contains__(name)
  378. if hasClass is False:
  379. result[name] = {}
  380. source = lkc['word_key']
  381. if not result[name].__contains__(source):
  382. result[name][source] = {}
  383. message = result[name][source]
  384. message['source'] = source[(len(name) + 1):]
  385. message['translation'] = lkc['langvalmodel__word_val']
  386. # location
  387. locations = []
  388. locations.append({'filename': lkc['langlocationmodel__filename'], 'line': lkc['langlocationmodel__line']})
  389. message['locations'] = locations
  390. print(result)
  391. return result
  392. def get_avss_language(self, id):
  393. if id == 18: # 简体中文
  394. return 'zh_CN'
  395. elif id == 19: # 繁体中文
  396. return 'zh_HK'
  397. elif id == 20: # 英文
  398. return 'en_US'
  399. elif id == 21: # 俄语
  400. return 'ru'
  401. elif id == 22: # 德语
  402. return 'de'
  403. elif id == 23: # 波兰语
  404. return 'pl'
  405. elif id == 24: # 法语
  406. return 'fr'
  407. elif id == 25: # 西班牙语
  408. return 'es'
  409. elif id == 26: # 日语
  410. return 'ja'
  411. elif id == 27: # 阿拉伯语
  412. return 'ar'
  413. elif id == 29: # 意大利语
  414. return 'it'
  415. elif id == 30: # 葡萄牙语
  416. return 'pt'
  417. elif id == 31: # 荷兰语
  418. return 'nl'
  419. elif id == 32: # 越南语
  420. return 'vi'
  421. else:
  422. return 'en'
  423. def do_download_SearchTool(self, id, searchtype):
  424. content = ''
  425. en_result = self.get_area_language_search(20)
  426. print(en_result)
  427. target_result = self.get_area_language_search(id)
  428. if target_result:
  429. content += '<TS version=\"2.1\" language=\"' + self.get_avss_language(int(id)) + '\">\n'
  430. # keys = result.keys()
  431. keys = en_result.keys()
  432. for key in keys:
  433. content += '<context>\n<name>'
  434. content += key
  435. content += '</name>\n'
  436. messages = None
  437. if target_result.__contains__(key):
  438. messages = target_result[key]
  439. else:
  440. messages = en_result[key]
  441. messageKeys = en_result[key].keys()
  442. for messageKey in messageKeys:
  443. message = None
  444. if messages.__contains__(messageKey):
  445. message = messages[messageKey]
  446. else:
  447. message = en_result[key][messageKey]
  448. # message = messages[messageKey]
  449. content += '<message>\n'
  450. content += '<source>'
  451. content += message['source']
  452. content += '</source>\n'
  453. content += '<translation>'
  454. translation = message['translation']
  455. # if translation is None or translation == '':
  456. # content += '23333'
  457. # else:
  458. content += translation
  459. content += '</translation>\n'
  460. locations = message['locations']
  461. print(message)
  462. for location in locations:
  463. if location['filename'] != '':
  464. content += '<location filename=\"' + location['filename'] + '\" line=\"' + str(
  465. location['line']) + '\"/>\n'
  466. content += '</message>\n'
  467. content += '</context>\n'
  468. content += '</TS>'
  469. return content
  470. else:
  471. print('none')
  472. return content
  473. class exportLangView(TemplateView):
  474. def post(self, request, *args, **kwargs):
  475. request.encoding = 'utf-8'
  476. request_dict = json.loads(request.body.decode('utf-8'))
  477. return self.validate(request_dict)
  478. def get(self, request, *args, **kwargs):
  479. request.encoding = 'utf-8'
  480. request_dict = request.GET
  481. return self.validate(request_dict)
  482. def validate(self, request_dict):
  483. # 得到即将下载文件的路径和名称
  484. response = StreamingHttpResponse('123l4kjlkfjlksadjlfksdajlf')
  485. response['Content-Type'] = 'application/octet-stream'
  486. response['Content-Disposition'] = 'attachment;filename="lang.txt"'
  487. return response