EquipmentOTA.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. import os
  2. import simplejson as json
  3. import time
  4. from django.utils import timezone
  5. from django.utils.decorators import method_decorator
  6. from django.views.decorators.csrf import csrf_exempt
  7. from django.views.generic.base import View
  8. from AdminController.VersionManagementController import VersionManagement
  9. from Ansjer.config import BASE_DIR, SERVER_DOMAIN, SERVER_DOMAIN_OTA
  10. from Model.models import Equipment_Version, EquipmentVersionLimitModel
  11. from Object.RedisObject import RedisObject
  12. from Object.ResponseObject import ResponseObject
  13. from Object.TokenObject import TokenObject
  14. from Object.UrlTokenObject import UrlTokenObject
  15. from Service.CommonService import CommonService
  16. from Service.ModelService import ModelService
  17. from django.db.models import Q
  18. from Ansjer.config import LOGGER
  19. class EquipmentOTA(View):
  20. @method_decorator(csrf_exempt)
  21. def dispatch(self, *args, **kwargs):
  22. return super(EquipmentOTA, self).dispatch(*args, **kwargs)
  23. def get(self, request, *args, **kwargs):
  24. request.encoding = 'utf-8'
  25. return self.validation(request_dict=request.GET)
  26. def post(self, request, *args, **kwargs):
  27. request.encoding = 'utf-8'
  28. return self.validation(request_dict=request.POST)
  29. def validation(self, request_dict, *args, **kwargs):
  30. token = request_dict.get('token', None)
  31. response = ResponseObject()
  32. if token is None:
  33. return response.json(309)
  34. tko = TokenObject(token)
  35. response.lang = tko.lang
  36. if tko.code != 0:
  37. return response.json(tko.code)
  38. userID = tko.userID
  39. if userID is None:
  40. return response.json(309)
  41. operation = request_dict.get('operation', None)
  42. if operation == 'delete':
  43. return self.delete(request_dict, userID, response)
  44. elif operation == 'query':
  45. return self.query(request_dict, userID, response)
  46. elif operation == 'find':
  47. return self.find(request_dict, userID, response)
  48. elif operation == 'update':
  49. return self.update(request_dict, userID, response)
  50. else:
  51. return response.json(444, 'operation')
  52. def delete(self, request_dict, userID, response):
  53. eid = request_dict.get('eid', None)
  54. version = request_dict.get('version', None)
  55. if not eid or not version:
  56. return response.json(444, 'eid or version')
  57. own_perm = ModelService.check_perm(userID=userID, permID=230)
  58. if not own_perm:
  59. return response.json(404)
  60. equipment_version = Equipment_Version.objects.filter(eid=eid, version=version)
  61. if not equipment_version.exists():
  62. return response.json(173)
  63. try:
  64. # 删除文件和相应数据
  65. file_path = equipment_version[0].filePath
  66. file_path = os.path.join(BASE_DIR, file_path).replace('\\', '/')
  67. os.remove(file_path)
  68. equipment_version.delete()
  69. except Exception as e:
  70. return response.json(176, repr(e))
  71. else:
  72. return response.json(0)
  73. def query(self, request_dict, userID, response):
  74. page = int(request_dict.get('page', None))
  75. line = int(request_dict.get('line', None))
  76. lang = request_dict.get('lang', None)
  77. if page is None or line is None:
  78. return response.json(444, 'page,line')
  79. own_permission = ModelService.check_perm(userID=userID, permID=240)
  80. if own_permission is not True:
  81. return response.json(404)
  82. if lang is None:
  83. qs = Equipment_Version.objects.all().order_by('-data_joined')
  84. else:
  85. qs = Equipment_Version.objects.filter(lang=lang).order_by('-data_joined')
  86. if qs.exists():
  87. count = qs.count()
  88. res = qs[(page - 1) * line:page * line]
  89. send_json = CommonService.qs_to_dict(res)
  90. send_json['count'] = count
  91. return response.json(0, send_json)
  92. return response.json(0)
  93. def find(self, request_dict, userID, response):
  94. page = int(request_dict.get('page', None))
  95. line = int(request_dict.get('line', None))
  96. content = request_dict.get('content', None)
  97. if page is None or line is None or content is None:
  98. return response.json(444)
  99. own_permission = ModelService.check_perm(userID=userID, permID=250)
  100. if own_permission is not True:
  101. return response.json(404)
  102. content = json.loads(content)
  103. search_kwargs = CommonService.get_kwargs(data=content)
  104. qs = Equipment_Version.objects.filter(**search_kwargs)
  105. if not qs.exists():
  106. return response.json(0, [])
  107. count = qs.count()
  108. res = qs[(page - 1) * line:page * line]
  109. send_json = CommonService.qs_to_dict(res)
  110. send_json['count'] = count
  111. return response.json(0, send_json)
  112. def update(self, request_dict, userID, response):
  113. eid = request_dict.get('eid', None)
  114. if eid is None:
  115. return response.json(444, 'eid')
  116. own_permission = ModelService.check_perm(userID=userID, permID=230)
  117. if own_permission is not True:
  118. return response.json(404)
  119. ev = Equipment_Version.objects.filter(eid=eid)
  120. if not ev.exists():
  121. return response.json(10, 'ev none')
  122. status = request_dict.get('status', None)
  123. try:
  124. update_time = timezone.localtime(timezone.now())
  125. ev.update(status=status, update_time=update_time)
  126. except Exception as e:
  127. print(repr(e))
  128. else:
  129. return response.json(0, {'update_time': str(update_time)})
  130. class EquipmentVersionView(View):
  131. def get(self, request, *args, **kwargs):
  132. request.encoding = 'utf-8'
  133. operation = kwargs.get('operation')
  134. return self.validation(request.GET, operation, request)
  135. def post(self, request, *args, **kwargs):
  136. request.encoding = 'utf-8'
  137. operation = kwargs.get('operation')
  138. return self.validation(request.POST, operation, request)
  139. def validation(self, request_dict, operation, request):
  140. response = ResponseObject()
  141. if operation is None:
  142. return response.json(444, 'error path')
  143. elif operation == 'checkVer':
  144. return self.do_check_value(request_dict, response, request)
  145. elif operation == 'checkIpcVer':
  146. return self.check_ipc_ver(request_dict, response)
  147. token = request_dict.get('token', None)
  148. # 设备主键uid
  149. tko = TokenObject(token)
  150. response.lang = tko.lang
  151. if tko.code != 0:
  152. return response.json(tko.code)
  153. userID = tko.userID
  154. own_perm = ModelService.check_perm(userID, 240)
  155. if own_perm is False:
  156. return response.json(404)
  157. if operation == 'query':
  158. return self.do_query(request_dict, response)
  159. if operation == 'update':
  160. return self.do_update(request_dict, response, request)
  161. if operation == 'filter':
  162. return self.do_filter(request_dict, response)
  163. else:
  164. return response.json(444, 'error path')
  165. def do_update(self, request_dict, response, request):
  166. code = request_dict.get('code', None)
  167. status = request_dict.get('status', None)
  168. lang = request_dict.get('lang', None)
  169. max_ver = request_dict.get('max_ver', None)
  170. file_s = request.FILES.get('file', None)
  171. paths = 'static/versions/image'
  172. if not os.path.exists(paths):
  173. os.makedirs(paths) # makedirs 创建文件时如果路径不存在会创建这个路径
  174. # print ('该文件不存在')
  175. else:
  176. print('该文件存在')
  177. ev = Equipment_Version.objects.filter(code=code, lang=lang)
  178. if file_s is None:
  179. rv_path = 'static/versions/image/' + code + '.png'
  180. img = SERVER_DOMAIN + 'sysfile/' + rv_path
  181. else:
  182. rv_path = 'static/versions/image/' + code + '.png'
  183. try:
  184. as_path = os.path.join(BASE_DIR, rv_path)
  185. if os.path.exists(as_path):
  186. os.remove(as_path)
  187. with open(as_path, 'wb+') as destination:
  188. for chunk in file_s.chunks():
  189. destination.write(chunk)
  190. except Exception as e:
  191. print(repr(e))
  192. else:
  193. img = SERVER_DOMAIN + 'sysfile/' + rv_path
  194. if code is not None:
  195. if ev.exists():
  196. try:
  197. update_time = timezone.localtime(timezone.now())
  198. update_dict = {
  199. 'status': status,
  200. 'img': img,
  201. 'update_time': update_time
  202. }
  203. if max_ver:
  204. update_dict['max_ver'] = max_ver
  205. ev.update(**update_dict)
  206. except Exception as e:
  207. return response.json(404, repr(e))
  208. else:
  209. return response.json(0, {'update_time': str(update_time), 'img': img})
  210. else:
  211. return response.json(173)
  212. else:
  213. return response.json(444, 'code')
  214. def do_check_ver(self, request_dict, response):
  215. code = request_dict.get('code', None)
  216. ov = request_dict.get('ov', None)
  217. uid = request_dict.get('uid', '')
  218. if not code:
  219. return response.json(444, 'code')
  220. eqs = Equipment_Version.objects.filter(code=uid, status=1, lang='en').order_by('-data_joined')
  221. if not eqs.exclude():
  222. eqs = Equipment_Version.objects.filter(code=code, status=1, lang='en').order_by('-data_joined')
  223. if not eqs.exists():
  224. return response.json(900)
  225. if ov is not None:
  226. # 判断大小
  227. if ov > eqs[0].softwareVersion:
  228. return response.json(0, {'softwareVersion': ov})
  229. file_path = eqs[0].filePath
  230. if file_path.find('static/Upgrade/') != -1:
  231. path = file_path.replace('static/Upgrade/', '').replace('\\', '/')
  232. url = SERVER_DOMAIN + 'OTA/downloads/' + path + '?time=' + str(time.time())
  233. elif file_path.find('static/otapack') != -1:
  234. url = SERVER_DOMAIN + 'OTA/downloadsPack/' + file_path + '?time=' + str(time.time())
  235. # url = SERVER_DOMAIN + 'dl/otaPack/' + file_path + '?time=' + str(time.time())
  236. else:
  237. return response.json(900, '2')
  238. res = {
  239. "url": url,
  240. "fileSize": eqs[0].fileSize,
  241. "Description": eqs[0].Description,
  242. "softwareVersion": eqs[0].softwareVersion
  243. }
  244. return response.json(0, res)
  245. # 修改加密的路径
  246. def do_check_value(self, request_dict, response, request):
  247. uid = request_dict.get('uid', '')
  248. try:
  249. code = request_dict.get('code', None)
  250. ov = request_dict.get('ov', None)
  251. if not code:
  252. return response.json(444, 'code')
  253. ip = CommonService.get_ip_address(request)
  254. LOGGER.info(f'请求参数:{uid},{code},{ov},{ip}')
  255. eqs = Equipment_Version.objects.filter(code=uid, status=1, lang='en').order_by('-data_joined')
  256. # 限制NVR版本升级
  257. if code == '681008800304A0001100000300001Z' and ov == '1.7.2':
  258. return response.json(900)
  259. if not eqs.exclude():
  260. eqs = Equipment_Version.objects.filter(code=code, status=1, lang='en').order_by('-data_joined')
  261. if not eqs.exists():
  262. return response.json(900)
  263. if ov is not None:
  264. # 判断大小
  265. if ov > eqs[0].softwareVersion:
  266. return response.json(0, {'softwareVersion': ov})
  267. equipment = eqs[0]
  268. # 升级文件指定设备时,判断uid是否在指定设备中
  269. ver_data = equipment.data_json
  270. result = VersionManagement.check_version_auto_update(uid, '', ver_data)
  271. if not result:
  272. return response.json(0, {'uid': uid})
  273. redisObject = RedisObject()
  274. key = 'limit_{eid}'.format(eid=equipment.eid)
  275. evl_qs = redisObject.get_data(key=key)
  276. if evl_qs:
  277. evl_qs = json.loads(evl_qs)
  278. else:
  279. evl_qs = EquipmentVersionLimitModel.objects.filter(equipment_version_id=equipment.eid,
  280. status=1).values()
  281. if evl_qs.exists():
  282. redisObject.set_data(key=key, val=json.dumps(list(evl_qs.values())), expire=600)
  283. if evl_qs and len(evl_qs) > 0:
  284. evl = evl_qs[0]
  285. if evl['type'] == 1: # uid限制
  286. uids = json.loads(evl['content'])
  287. if not uids.__contains__(uid):
  288. return response.json(902)
  289. file_path = eqs[0].filePath
  290. url = SERVER_DOMAIN_OTA
  291. if file_path.find('static/Upgrade/') != -1:
  292. # 创建url的token
  293. tko = UrlTokenObject()
  294. path = tko.generate(data={'Url': "ansjer/" + CommonService.RandomStr(6) + "/" + file_path})
  295. url += 'OTA/downloads/' + path
  296. elif file_path.find('static/otapack') != -1:
  297. file_path = file_path
  298. param_url = "ansjer/" + CommonService.RandomStr(6) + "/" + file_path
  299. data = {'Url': param_url, 'user_id': '', 'uid': uid, 'serial_number': '', 'old_version': ov,
  300. 'new_version': eqs[0].softwareVersion, 'mci': 'NVR'}
  301. dvr_ota_key = 'ASJ:SERVER:VERSION:{}'.format(uid)
  302. dvr_ota_value = json.dumps(data)
  303. expire = 129600
  304. redisObject.set_data(dvr_ota_key, dvr_ota_value, expire)
  305. # 创建url的token
  306. tko = UrlTokenObject()
  307. file_path = tko.generate(data={'uid': uid})
  308. url += 'dlotapack/' + file_path
  309. res = {
  310. "url": url,
  311. "fileSize": eqs[0].fileSize,
  312. "Description": eqs[0].Description,
  313. "softwareVersion": eqs[0].softwareVersion
  314. }
  315. return response.json(0, res)
  316. except Exception as e:
  317. error_line = e.__traceback__.tb_lineno
  318. LOGGER.error(f'检查OTA异常:{uid}, error_line:{error_line}, error_msg:{repr(e)}')
  319. return response.json(500)
  320. @staticmethod
  321. def check_ipc_ver(request_dict, response):
  322. """
  323. NVR获取IPC升级链接
  324. @param request_dict: 请求参数
  325. @request_dict lang: 语言
  326. @request_dict code: 网关设备id
  327. @request_dict now_ver: 设备当前版本
  328. @param response: 响应对象
  329. @return: response
  330. """
  331. lang = request_dict.get('lang', None)
  332. code = request_dict.get('code', None)
  333. now_ver = request_dict.get('now_ver', None)
  334. if not all([code, lang, now_ver]):
  335. return response.json(902, {'param': 'code, lang, ver'})
  336. equipment_version_qs = Equipment_Version.objects.filter(code=code, status=1, lang=lang).order_by('-data_joined')
  337. if not equipment_version_qs.exists():
  338. return response.json(902)
  339. equipment = equipment_version_qs[0]
  340. file_path = equipment.filePath
  341. max_ver = equipment.max_ver
  342. if now_ver > max_ver:
  343. return response.json(902)
  344. url = SERVER_DOMAIN_OTA + 'OTA/downloadsPack/' + file_path
  345. file_name = file_path[file_path.rindex('/')+1:]
  346. res = {
  347. "url": url,
  348. "fileName": file_name,
  349. "fileSize": equipment.fileSize,
  350. "Description": equipment.Description,
  351. "softwareVersion": equipment.softwareVersion
  352. }
  353. return response.json(0, res)
  354. def do_query(self, request_dict, response):
  355. mci = request_dict.get('mci', None)
  356. page = request_dict.get('page', None)
  357. line = request_dict.get('line', None)
  358. code = request_dict.get('code', None)
  359. if not page or not line:
  360. return response.json(444, 'page,line')
  361. else:
  362. page = int(page)
  363. line = int(line)
  364. cv_qs = Equipment_Version.objects
  365. if mci is not None:
  366. cv_qs = cv_qs.filter(mci=mci)
  367. if code is not None:
  368. cv_qs = cv_qs.filter(code__contains=code)
  369. cv_qs = cv_qs.order_by('code').values_list('code', flat=True).distinct()
  370. print(cv_qs)
  371. count = cv_qs.count()
  372. cv_qs = list(cv_qs[(page - 1) * line:page * line])
  373. # return response.json(0, cv_qs)
  374. ev_qs = Equipment_Version.objects.filter(code__in=list(cv_qs)).values()
  375. ev_list = CommonService.qs_to_list(ev_qs)
  376. datas = {}
  377. # 组装数据
  378. for ev in ev_list:
  379. for code in cv_qs:
  380. if code not in datas.keys():
  381. datas[code] = []
  382. if code == ev['code']:
  383. datas[code].append(ev)
  384. res = {
  385. 'datas': datas,
  386. 'count': count
  387. }
  388. return response.json(0, res)
  389. def do_filter(self, request_dict, response):
  390. mci = request_dict.get('mci', None)
  391. page = request_dict.get('page', None)
  392. line = request_dict.get('line', None)
  393. code = request_dict.get('code', None)
  394. lang = request_dict.get('lang', None)
  395. if not page or not line:
  396. return response.json(444, 'page,line')
  397. else:
  398. page = int(page)
  399. line = int(line)
  400. ev_qs = Equipment_Version.objects
  401. if mci:
  402. ev_qs = ev_qs.filter(mci=mci)
  403. if code:
  404. ev_qs = ev_qs.filter(code__contains=code)
  405. if lang:
  406. if lang == 'cn' or lang == 'zh-Hans':
  407. ev_qs = ev_qs.filter(Q(lang='cn') | Q(lang='zh-Hans'))
  408. else:
  409. ev_qs = ev_qs.filter(lang=lang)
  410. count = ev_qs.count()
  411. ev_qs = ev_qs[(page - 1) * line:page * line].values()
  412. ev_ls = CommonService.qs_to_list(ev_qs)
  413. res = {
  414. 'datas': ev_ls,
  415. 'count': count
  416. }
  417. return response.json(0, res)