|
@@ -1,21 +1,26 @@
|
|
|
#!/usr/bin/env python3
|
|
|
# -*- coding: utf-8 -*-
|
|
|
-import os
|
|
|
import hashlib
|
|
|
+import json
|
|
|
+import os
|
|
|
+import threading
|
|
|
import time
|
|
|
-import math
|
|
|
|
|
|
import boto3
|
|
|
import botocore
|
|
|
+from django.core.paginator import Paginator
|
|
|
from django.db import transaction
|
|
|
from django.views.generic.base import View
|
|
|
-from Ansjer.config import LOGGER
|
|
|
|
|
|
from Ansjer.config import BASE_DIR, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
|
|
|
-from Object.TokenObject import TokenObject
|
|
|
+from Ansjer.config import LOGGER, CONFIG_TEST, SERVER_DOMAIN, CONFIG_CN, CONFIG_INFO
|
|
|
+from Model.models import Equipment_Version, App_Info, AppSetModel, App_Colophon, Pc_Info, CountryModel, CNRegion, \
|
|
|
+ Device_Info, UidSetModel, Device_User, IPAddr
|
|
|
+from Object.RedisObject import RedisObject
|
|
|
from Object.ResponseObject import ResponseObject
|
|
|
+from Object.TokenObject import TokenObject
|
|
|
+from Object.UrlTokenObject import UrlTokenObject
|
|
|
from Service.CommonService import CommonService
|
|
|
-from Model.models import Equipment_Version, App_Info, AppSetModel, App_Colophon, Pc_Info, CountryModel, CNRegion
|
|
|
|
|
|
|
|
|
class VersionManagement(View):
|
|
@@ -34,6 +39,8 @@ class VersionManagement(View):
|
|
|
response = ResponseObject(language, 'pc')
|
|
|
if operation == 'upLoadFile':
|
|
|
return self.upLoadFile(request, request_dict, response)
|
|
|
+ elif operation == 'deviceAutoUpdate':
|
|
|
+ return self.device_auto_update('124', request_dict, response)
|
|
|
else:
|
|
|
tko = TokenObject(
|
|
|
request.META.get('HTTP_AUTHORIZATION'),
|
|
@@ -76,6 +83,8 @@ class VersionManagement(View):
|
|
|
return self.getCountryList(request_dict, response)
|
|
|
elif operation == 'getCityList':
|
|
|
return self.getCityList(request_dict, response)
|
|
|
+ elif operation == 'deviceAutoUpdate':
|
|
|
+ return self.device_auto_update(userID, request_dict, response)
|
|
|
else:
|
|
|
return response.json(404)
|
|
|
|
|
@@ -670,3 +679,143 @@ class VersionManagement(View):
|
|
|
except Exception as e:
|
|
|
print(e)
|
|
|
return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
|
|
|
+
|
|
|
+ @classmethod
|
|
|
+ def device_auto_update(cls, user_id, request_dict, response):
|
|
|
+ verId = request_dict.get('verId', None)
|
|
|
+ if not verId:
|
|
|
+ return response.json(444)
|
|
|
+ LOGGER.info(f'版本ID:{verId},操作用户{user_id}')
|
|
|
+ version_qs = Equipment_Version.objects.filter(eid=verId, auto_update=True, status=1)
|
|
|
+ if not version_qs.exists():
|
|
|
+ return response.json(173)
|
|
|
+
|
|
|
+ agent_thread = threading.Thread(target=VersionManagement().device_async_update,
|
|
|
+ args=version_qs)
|
|
|
+ agent_thread.start()
|
|
|
+ return response.json(0)
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def device_async_update(version_qs):
|
|
|
+ code = version_qs.code
|
|
|
+ version = version_qs.softwareVersion
|
|
|
+ ver_data = version_qs.data_json
|
|
|
+ uid_set_qs = UidSetModel.objects.filter(ucode=code).exclude(version=version) \
|
|
|
+ .values('uid', 'ip', 'version')
|
|
|
+ LOGGER.info(f'通知设备自动升级查询符合数量{uid_set_qs.count()}')
|
|
|
+ if not uid_set_qs.exists():
|
|
|
+ return
|
|
|
+
|
|
|
+ # 创建分页器,每页100条数据
|
|
|
+ paginator = Paginator(uid_set_qs, 100)
|
|
|
+
|
|
|
+ # 遍历每一页数据
|
|
|
+ for page_num in range(1, paginator.num_pages + 1):
|
|
|
+ # 获取当前页的数据
|
|
|
+ page_data = paginator.page(page_num)
|
|
|
+
|
|
|
+ # 遍历当前页的每一条数据
|
|
|
+ for data in page_data:
|
|
|
+ uid = data['uid']
|
|
|
+
|
|
|
+ result = VersionManagement.check_version_auto_update(uid, '', ver_data)
|
|
|
+ if not result:
|
|
|
+ continue
|
|
|
+ serial_number = CommonService.get_serial_number_by_uid(uid)
|
|
|
+ now_ver = data['version']
|
|
|
+ LOGGER.info(f'uid={uid},ucode={code},当前版本{now_ver},最新版本{version}')
|
|
|
+ VersionManagement.send_auto_update_url(version_qs, uid, serial_number, code, now_ver)
|
|
|
+
|
|
|
+ @classmethod
|
|
|
+ def check_version_auto_update(cls, uid, user_id, ver_data):
|
|
|
+ """
|
|
|
+
|
|
|
+ :param uid: 设备UID
|
|
|
+ :param user_id: 用户id
|
|
|
+ :param ver_data: 版本指定升级数据
|
|
|
+ :return: True | False
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ if not ver_data: # 过滤值默认当前版本所有设备自动升级
|
|
|
+ return True
|
|
|
+
|
|
|
+ if uid and ver_data['uid_list']: # 当前版本指定UID
|
|
|
+ return uid in ver_data['uid_list']
|
|
|
+ if user_id and ver_data['country_list'] and CONFIG_INFO not in [CONFIG_CN, CONFIG_TEST]: # 当前版本指定用户国家
|
|
|
+ user_qs = Device_User.objects.filter(userID=user_id).values('region_country')
|
|
|
+ if not user_qs.exists(): # 用户不存在不升级
|
|
|
+ return False
|
|
|
+ if user_qs[0]['region_country'] == 0: # 用户未选择国家 不进行升级提示
|
|
|
+ return False
|
|
|
+ return user_qs[0]['region_country'] in ver_data['country_list']
|
|
|
+ if CONFIG_INFO in [CONFIG_CN, CONFIG_TEST] and ver_data['addr']: # 中国区可指定城市
|
|
|
+ city_list = ver_data['addr']['city_list']
|
|
|
+ if not city_list:
|
|
|
+ return True
|
|
|
+ uid_set_qs = UidSetModel.objects.filter(uid=uid).values('ip')
|
|
|
+ if not uid_set_qs:
|
|
|
+ return False
|
|
|
+ ip_qs = IPAddr.objects.filter(ip=uid_set_qs[0]['ip']).values('city').order_by('-id')
|
|
|
+ if not ip_qs:
|
|
|
+ return False
|
|
|
+ return ip_qs[0]['city'] in city_list
|
|
|
+ return False
|
|
|
+ except Exception as e:
|
|
|
+ LOGGER.error(f'检测是否符合自动升级{repr(e)}')
|
|
|
+ return False
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def send_auto_update_url(version_qs, uid, serial_number, code, now_ver):
|
|
|
+ """
|
|
|
+ 发送自动升级URL
|
|
|
+ @param version_qs: 最新版本querySet
|
|
|
+ @param uid: 设备UID
|
|
|
+ @param serial_number: 设备序列号
|
|
|
+ @param code: 设备规格码
|
|
|
+ @param now_ver: 设备当前版本好
|
|
|
+ @return:
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ file_path = version_qs.filePath
|
|
|
+ version = version_qs.version
|
|
|
+ mci = version_qs.mci
|
|
|
+ ver = version_qs.softwareVersion
|
|
|
+ max_ver = version_qs.max_ver
|
|
|
+
|
|
|
+ if ver <= max_ver:
|
|
|
+ user_qs = Device_Info.objects.filter(UID=uid, isShare=False).values('userID_id')
|
|
|
+ if not user_qs.exists():
|
|
|
+ return False
|
|
|
+ user_id = user_qs[0]['userID_id']
|
|
|
+ # 创建url的token
|
|
|
+ param_url = "ansjer/" + CommonService.RandomStr(6) + "/" + file_path
|
|
|
+ data = {'Url': param_url, 'user_id': user_id,
|
|
|
+ 'uid': uid, 'serial_number': serial_number, 'old_version': "V" + now_ver + "." + code,
|
|
|
+ 'new_version': version, 'mci': mci}
|
|
|
+ device_info_value = json.dumps(data)
|
|
|
+ expire = 600
|
|
|
+
|
|
|
+ str_uuid = str(user_id)
|
|
|
+ if serial_number and serial_number != 'null':
|
|
|
+ str_uuid += serial_number
|
|
|
+ elif uid and uid != 'null':
|
|
|
+ str_uuid += uid
|
|
|
+ str_uuid += now_ver
|
|
|
+ device_info_key = 'ASJ:SERVER:VERSION:{}'.format(str_uuid)
|
|
|
+ LOGGER.info('缓存key={}'.format(device_info_key))
|
|
|
+ redisObject = RedisObject()
|
|
|
+ redisObject.set_data(device_info_key, device_info_value, expire)
|
|
|
+
|
|
|
+ url_tko = UrlTokenObject()
|
|
|
+ file_path = url_tko.generate(data={'uid': str_uuid})
|
|
|
+
|
|
|
+ url = SERVER_DOMAIN + 'dlotapack/' + file_path
|
|
|
+ # 主题名称
|
|
|
+ topic_name = f'ansjer/generic/{serial_number}'
|
|
|
+ # 发布消息内容
|
|
|
+ msg = {"commandCode": 1, "data": {"url": url}}
|
|
|
+
|
|
|
+ result = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
|
|
|
+ LOGGER.info(f'uid={uid}发送数据msg={msg},发送MQTT结果={result}')
|
|
|
+ except Exception as e:
|
|
|
+ LOGGER.error(f'自动升级异常{repr(e)}')
|