UserDeviceShareController.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. # -*- encoding: utf-8 -*-
  2. """
  3. @File : UserDeviceShareController.py
  4. @Time : 2023/1/7 15:05
  5. @Author : stephen
  6. @Email : zhangdongming@asj6.wecom.work
  7. @Software: PyCharm
  8. """
  9. import json
  10. import logging
  11. import threading
  12. import time
  13. import boto3
  14. import botocore
  15. from botocore import client
  16. from django.db import transaction
  17. from django.db.models import Q
  18. from django.views import View
  19. from Model.models import DeviceSharePermission, DeviceChannelUserSet, DeviceChannelUserPermission, UidChannelSetModel, \
  20. Device_Info
  21. from Object.ContentSecurityObject import ContentSecurity
  22. from Object.ResponseObject import ResponseObject
  23. from Object.TokenObject import TokenObject
  24. from Service.UserDeviceService import UserDeviceService
  25. from Ansjer.config import CONFIG_CN, CONFIG_INFO, CONFIG_TEST, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, \
  26. AWS_SES_ACCESS_REGION, AWS_IOT_SES_ACCESS_CHINA_REGION
  27. from Model.models import DeviceWallpaper
  28. from Object.AWS.AmazonS3Util import AmazonS3Util
  29. LOGGER = logging.getLogger('info')
  30. class UserDeviceShareView(View):
  31. def get(self, request, *args, **kwargs):
  32. request.encoding = 'utf-8'
  33. operation = kwargs.get('operation')
  34. return self.validation(request.GET, request, operation)
  35. def post(self, request, *args, **kwargs):
  36. request.encoding = 'utf-8'
  37. operation = kwargs.get('operation')
  38. return self.validation(request.POST, request, operation)
  39. def validation(self, request_dict, request, operation):
  40. token = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
  41. lang = request_dict.get('lang', token.lang)
  42. response = ResponseObject(lang)
  43. if token.code != 0:
  44. return response.json(token.code)
  45. if operation == 'user-permissions':
  46. return self.get_user_share_permission(request_dict, response)
  47. elif operation == 'permissions-save':
  48. return self.user_channel_permission_save(request_dict, response)
  49. elif operation == 'permissions-test':
  50. return self.synch_share_device_permission(response)
  51. elif operation == 'getWallpaperList':
  52. return self.get_wallpaper_list(request_dict, response)
  53. elif operation == 'getUploadWallpaper':
  54. return self.get_upload_wallpaper(request_dict, response)
  55. elif operation == 'notifyUploadWallpaper':
  56. return self.notify_upload_wallpaper(request_dict, response)
  57. elif operation == 'delWallpaper':
  58. return self.del_wallpaper(request_dict, response)
  59. elif operation == 'selectWallpaper':
  60. return self.select_wallpaper(request_dict, response)
  61. else:
  62. return response.json(404)
  63. @classmethod
  64. def get_user_share_permission(cls, request_dict, response):
  65. """
  66. 获取用户分享权限
  67. @param request_dict: 设备uid
  68. @param response: 响应对象
  69. @return: permission List
  70. """
  71. try:
  72. uid = request_dict.get('uid', None)
  73. user_id = request_dict.get('userId', None)
  74. channel_count = request_dict.get('channelCount', None)
  75. if not all([user_id, uid, channel_count]):
  76. return response(444, 'uid, userId and channelCount is required')
  77. user_permission_qs = DeviceChannelUserSet.objects.filter(user_id=user_id, uid=uid) \
  78. .values('id', 'channels')
  79. if not user_permission_qs.exists():
  80. return response.json(0, {})
  81. up_id = user_permission_qs[0]['id']
  82. channel_permission_qs = DeviceChannelUserPermission.objects.filter(channel_user_id=up_id) \
  83. .values('permission_id', 'channel_user_id')
  84. if not channel_permission_qs.exists():
  85. return response.json(0, {})
  86. channel_list = list(range(1, int(channel_count) + 1))
  87. share_channel_list = user_permission_qs[0]['channels'].split(',')
  88. c_list = []
  89. for channel in channel_list:
  90. is_select = 1 if str(channel) in share_channel_list else 0
  91. c_list.append({'channelIndex': channel, 'isSelect': is_select})
  92. p_list = []
  93. permission_qs = DeviceSharePermission.objects.all()
  94. share_permission_list = [item['permission_id'] for item in channel_permission_qs]
  95. for item in permission_qs:
  96. is_select = 1 if item.id in share_permission_list else 0
  97. p_list.append({'permissionId': item.id, 'code': item.code, 'isSelect': is_select})
  98. data = {'channels': c_list, 'permissions': p_list}
  99. return response.json(0, data)
  100. except Exception as e:
  101. LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  102. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  103. @classmethod
  104. def user_channel_permission_save(cls, request_dict, response):
  105. """
  106. 主用户分享设备时设置通道权限保存
  107. """
  108. try:
  109. uid = request_dict.get('uid', None)
  110. channels = request_dict.get('channels', None) # 通道集合,多个','隔开
  111. user_id = request_dict.get('userId', None)
  112. permission_ids = request_dict.get('permissionIds', None) # 权限集合,多个','隔开
  113. if not all([user_id, uid, channels, permission_ids]):
  114. return response.json(444)
  115. p_ids = []
  116. device_user_set = DeviceChannelUserSet.objects.filter(user_id=user_id, uid=uid)
  117. now_time = int(time.time())
  118. with transaction.atomic():
  119. is_delete = False
  120. if not device_user_set.exists():
  121. device_set = {'uid': uid, 'user_id': user_id, 'channels': channels,
  122. 'created_time': now_time, 'updated_time': now_time}
  123. device_user_set = DeviceChannelUserSet.objects.create(**device_set)
  124. channel_user_id = device_user_set.id
  125. else:
  126. DeviceChannelUserSet.objects.update(channels=channels, updated_time=now_time)
  127. channel_user_id = device_user_set.first().id
  128. is_delete = True
  129. if ',' in permission_ids:
  130. p_ids = [int(val) for val in permission_ids.split(',')]
  131. if is_delete:
  132. DeviceChannelUserPermission.objects.filter(
  133. channel_user_id=channel_user_id).delete()
  134. if not p_ids:
  135. channel_permission = {'permission_id': int(permission_ids),
  136. 'channel_user_id': channel_user_id,
  137. 'created_time': now_time}
  138. DeviceChannelUserPermission.objects.create(**channel_permission)
  139. else:
  140. channel_permission_list = []
  141. for item in p_ids:
  142. channel_permission_list.append(DeviceChannelUserPermission(
  143. permission_id=int(item),
  144. channel_user_id=channel_user_id,
  145. created_time=now_time))
  146. DeviceChannelUserPermission.objects.bulk_create(channel_permission_list)
  147. return response.json(0)
  148. except Exception as e:
  149. LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  150. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  151. @staticmethod
  152. def qrcode_share_channel_permission_save(user_id, uid):
  153. """
  154. 二维码分享保存通道权限
  155. @param user_id: 用户id
  156. @param uid: 用户设备ID
  157. @return: True | False
  158. """
  159. try:
  160. if not all([user_id, uid]):
  161. return False
  162. with transaction.atomic():
  163. ds_qs = DeviceChannelUserSet.objects.filter(user_id=user_id, uid=uid)
  164. if ds_qs.exists():
  165. return True
  166. UserDeviceService.update_device_channel(uid)
  167. channel_qs = UidChannelSetModel.objects.filter(uid__uid=uid).values('channel')
  168. if not channel_qs.exists():
  169. return False
  170. channel_list = [str(val['channel']) for val in channel_qs]
  171. channel_str = ','.join(channel_list)
  172. now_time = int(time.time())
  173. device_set = {'uid': uid, 'user_id': user_id, 'channels': channel_str,
  174. 'created_time': now_time, 'updated_time': now_time}
  175. device_user_set = DeviceChannelUserSet.objects.create(**device_set)
  176. channel_permission_qs = DeviceSharePermission.objects \
  177. .all().values('id', 'code').order_by('sort')
  178. user_set_id = device_user_set.id
  179. channel_permission_list = []
  180. for item in channel_permission_qs:
  181. channel_permission_list.append(DeviceChannelUserPermission(
  182. permission_id=item['id'],
  183. channel_user_id=user_set_id,
  184. created_time=now_time))
  185. DeviceChannelUserPermission.objects.bulk_create(channel_permission_list)
  186. return True
  187. except Exception as e:
  188. LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  189. return False
  190. @staticmethod
  191. def synch_share_device_permission(response):
  192. """
  193. 同步分析设备权限
  194. @param response: 响应结果
  195. """
  196. device_info_qs = Device_Info.objects \
  197. .filter(~Q(Type__in=[1, 2, 3, 4, 10001]), ~Q(primaryUserID=''), isShare=1) \
  198. .values('userID_id', 'UID').order_by('-data_joined')
  199. if not device_info_qs.exists():
  200. return response.json(0)
  201. for item in device_info_qs:
  202. UserDeviceShareView.qrcode_share_channel_permission_save(item['userID_id'], item['UID'])
  203. return response.json(0)
  204. @classmethod
  205. def get_wallpaper_list(cls, request_dict, response):
  206. """
  207. 获取设备壁纸列表
  208. @param request_dict:
  209. @param response:
  210. @return:
  211. """
  212. try:
  213. device_type = int(request_dict.get('deviceType', None))
  214. uid = request_dict.get('uid', None)
  215. channel = int(request_dict.get('channel', 1))
  216. LOGGER.info('获取设备壁纸列表参数:{}'.format(request_dict))
  217. if not all([device_type, uid]):
  218. return response.json(444)
  219. # 查询用户自定义壁纸
  220. user_wallpaper_qs = DeviceWallpaper.objects.filter(channel=channel, uid=uid,
  221. device_type=device_type, parent_id=0, status=1)
  222. # 查询系统默认壁纸
  223. def_wallpaper_qs = DeviceWallpaper.objects.filter(classification=1, device_type=device_type, uid='',
  224. status=1)
  225. # 查询用户选中的壁纸
  226. user_checked_qs = DeviceWallpaper.objects.filter(channel=channel, uid=uid,
  227. device_type=device_type, parent_id__gt=0, status=1)
  228. checked_id = user_checked_qs[0].parent_id if user_checked_qs.exists() else 0
  229. wallpaper_list = []
  230. if def_wallpaper_qs.exists() or user_wallpaper_qs.exists():
  231. # 初始化存储桶客户端
  232. if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO:
  233. s3 = boto3.client(
  234. 's3',
  235. aws_access_key_id=AWS_ACCESS_KEY_ID[0],
  236. aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
  237. config=botocore.client.Config(signature_version='s3v4'),
  238. region_name='cn-northwest-1'
  239. )
  240. else:
  241. s3 = boto3.client(
  242. 's3',
  243. aws_access_key_id=AWS_ACCESS_KEY_ID[1],
  244. aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1],
  245. config=botocore.client.Config(signature_version='s3v4'),
  246. region_name='us-east-1'
  247. )
  248. # 处理系统默认壁纸和用户自定义壁纸
  249. all_wallpapers_qs = def_wallpaper_qs.union(user_wallpaper_qs)
  250. for item in all_wallpapers_qs:
  251. obj_key = item.obj_prefix + item.obj_name
  252. params = {
  253. 'Key': obj_key,
  254. 'Bucket': 'ansjerfilemanager',
  255. }
  256. response_url = s3.generate_presigned_url(
  257. 'get_object', Params=params, ExpiresIn=3600)
  258. wallpaper = {
  259. 'id': item.id,
  260. 'url': response_url,
  261. 'state': 1 if checked_id == item.id else 0,
  262. 'classification': item.classification
  263. }
  264. wallpaper_list.append(wallpaper)
  265. return response.json(0, {'wallpapers': wallpaper_list})
  266. except Exception as e:
  267. LOGGER.error('查询设备壁纸异常:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  268. return response.json(5)
  269. @classmethod
  270. def get_upload_wallpaper(cls, request_dict, response):
  271. """
  272. 获取设备壁纸上传链接
  273. @param request_dict:
  274. @param response:
  275. @return:
  276. """
  277. try:
  278. uid = request_dict.get('uid', None)
  279. channel = int(request_dict.get('channel', 1))
  280. if not uid:
  281. return response.json(444)
  282. # 初始化存储桶客户端
  283. if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO:
  284. s3 = boto3.client(
  285. 's3',
  286. aws_access_key_id=AWS_ACCESS_KEY_ID[0],
  287. aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
  288. config=botocore.client.Config(signature_version='s3v4'),
  289. region_name='cn-northwest-1'
  290. )
  291. else:
  292. s3 = boto3.client(
  293. 's3',
  294. aws_access_key_id=AWS_ACCESS_KEY_ID[1],
  295. aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1],
  296. config=botocore.client.Config(signature_version='s3v4'),
  297. region_name='us-east-1'
  298. )
  299. # 生成唯一的文件名
  300. file_name = f"{int(time.time())}.png"
  301. obj_key = f"app/static/device-wallpaper/{uid}/{file_name}"
  302. # 生成预签名的 URL
  303. presigned_url = s3.generate_presigned_url(
  304. 'put_object',
  305. Params={
  306. 'Bucket': 'ansjerfilemanager',
  307. 'Key': obj_key,
  308. },
  309. ExpiresIn=600
  310. )
  311. # 返回预签名的URL和字段
  312. return response.json(0, {
  313. 'uploadUrl': presigned_url,
  314. 'fileName': file_name,
  315. })
  316. except Exception as e:
  317. LOGGER.error('获取上传链接异常:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  318. return response.json(5)
  319. @classmethod
  320. def notify_upload_wallpaper(cls, request_dict, response):
  321. """
  322. 确认壁纸上传成功,创建DeviceWallpaper
  323. @param request_dict:
  324. @param response:
  325. @return:
  326. """
  327. try:
  328. uid = request_dict.get('uid', None)
  329. file_name = request_dict.get('fileName', None)
  330. channel = int(request_dict.get('channel', 1))
  331. if not all([uid, file_name]):
  332. return response.json(444)
  333. device_info_qs = Device_Info.objects.filter(UID=uid).values('id', 'Type')
  334. device_type = device_info_qs[0]['Type'] if device_info_qs.exists() else ''
  335. # 初始化存储桶客户端
  336. if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO:
  337. s3 = boto3.client(
  338. 's3',
  339. aws_access_key_id=AWS_ACCESS_KEY_ID[0],
  340. aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
  341. config=botocore.client.Config(signature_version='s3v4'),
  342. region_name='cn-northwest-1'
  343. )
  344. else:
  345. s3 = boto3.client(
  346. 's3',
  347. aws_access_key_id=AWS_ACCESS_KEY_ID[1],
  348. aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1],
  349. config=botocore.client.Config(signature_version='s3v4'),
  350. region_name='us-east-1'
  351. )
  352. obj_key = f"app/static/device-wallpaper/{uid}/{file_name}"
  353. params = {'Bucket': "ansjerfilemanager", 'Key': obj_key}
  354. image_url = s3.generate_presigned_url('get_object', Params=params)
  355. service = 'profilePhotoCheck'
  356. LOGGER.info('壁纸链接:{}'.format(image_url))
  357. service_dict = {'imageUrl': image_url}
  358. service_parameters = json.dumps(service_dict)
  359. legal = ContentSecurity().image_review(service, service_parameters)
  360. if not legal:
  361. # 异步删除
  362. thread = threading.Thread(target=cls.delete_wallpaper, args=(obj_key,))
  363. thread.start()
  364. return response.json(184)
  365. DeviceWallpaper.objects.create(
  366. device_type=device_type,
  367. storage_type=1,
  368. channel=channel,
  369. uid=uid,
  370. obj_prefix=f'app/static/device-wallpaper/{uid}/',
  371. obj_name=file_name,
  372. classification=2, # 自定义壁纸分类
  373. status=1,
  374. parent_id=0,
  375. created_time=int(time.time())
  376. )
  377. return response.json(0)
  378. except Exception as e:
  379. LOGGER.error('壁纸创建失败:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  380. return response.json(5)
  381. @classmethod
  382. def del_wallpaper(cls, request_dict, response):
  383. """
  384. 删除设备壁纸
  385. """
  386. wallpaper_id = request_dict.get('wallpaperId', None)
  387. if not all([wallpaper_id]):
  388. return response.json(444)
  389. try:
  390. wallpaper_id = int(wallpaper_id)
  391. if DeviceWallpaper.objects.filter(id=wallpaper_id, classification=1).exists():
  392. return response.json(176, "系统图片不能删除")
  393. device_wallpaper_qs = DeviceWallpaper.objects.filter(id=wallpaper_id)
  394. device_wallpaper = device_wallpaper_qs.values("obj_prefix", "obj_name", "uid", "parent_id")
  395. uid = device_wallpaper[0]['uid']
  396. obj_name = device_wallpaper[0]['obj_name']
  397. # 使用中壁纸被删除
  398. use_device_wallpaper = DeviceWallpaper.objects.filter(uid=uid, parent_id__gt=0).first()
  399. if use_device_wallpaper and use_device_wallpaper.parent_id == wallpaper_id:
  400. system_device_wallpaper = DeviceWallpaper.objects.filter(id=1).first()
  401. use_device_wallpaper.parent_id = 1
  402. use_device_wallpaper.storage_type = system_device_wallpaper.storage_type
  403. use_device_wallpaper.obj_name = system_device_wallpaper.obj_name
  404. use_device_wallpaper.obj_prefix = system_device_wallpaper.obj_prefix
  405. use_device_wallpaper.classification = system_device_wallpaper.classification
  406. use_device_wallpaper.channel = system_device_wallpaper.channel
  407. use_device_wallpaper.save()
  408. if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO:
  409. s3 = AmazonS3Util(
  410. AWS_ACCESS_KEY_ID[0], AWS_SECRET_ACCESS_KEY[0], 'cn-northwest-1'
  411. )
  412. else:
  413. s3 = AmazonS3Util(
  414. AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], 'us-east-1'
  415. )
  416. s3.delete_obj("ansjerfilemanager", f"app/static/device-wallpaper/{uid}/{obj_name}")
  417. device_wallpaper_qs.delete()
  418. return response.json(0)
  419. except Exception as e:
  420. LOGGER.info('删除壁纸异常:{}'.format(e))
  421. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  422. @classmethod
  423. def select_wallpaper(cls, request_dict, response):
  424. """
  425. 用户选取壁纸
  426. @param request_dict:
  427. @param response:
  428. @return:
  429. """
  430. try:
  431. wallpaper_id = request_dict.get('wallpaperId', None)
  432. uid = request_dict.get('uid', None)
  433. if not all([wallpaper_id, uid]):
  434. return response.json(444)
  435. device_wallpaper = DeviceWallpaper.objects.filter(id=wallpaper_id).values("device_type", "storage_type",
  436. "obj_prefix",
  437. "obj_name",
  438. "classification",
  439. "channel").first()
  440. device_wallpaper_qs = DeviceWallpaper.objects.filter(uid=uid, parent_id__gt=0)
  441. if device_wallpaper_qs.exists():
  442. device_wallpaper_qs.update(
  443. storage_type=device_wallpaper["storage_type"],
  444. classification=device_wallpaper["classification"],
  445. obj_prefix=device_wallpaper["obj_prefix"],
  446. obj_name=device_wallpaper["obj_name"],
  447. parent_id=wallpaper_id
  448. )
  449. else:
  450. DeviceWallpaper.objects.create(
  451. device_type=device_wallpaper["device_type"],
  452. storage_type=device_wallpaper["storage_type"],
  453. obj_name=device_wallpaper["obj_name"],
  454. obj_prefix=device_wallpaper["obj_prefix"],
  455. classification=device_wallpaper["classification"],
  456. uid=uid,
  457. channel=device_wallpaper["channel"],
  458. status=1,
  459. parent_id=wallpaper_id,
  460. created_time=int(time.time())
  461. )
  462. return response.json(0)
  463. except Exception as e:
  464. LOGGER.error('用户选取壁纸异常:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  465. return response.json(5)
  466. @staticmethod
  467. def delete_wallpaper(file_key):
  468. try:
  469. if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO:
  470. s3 = AmazonS3Util(
  471. AWS_ACCESS_KEY_ID[0], AWS_SECRET_ACCESS_KEY[0], 'cn-northwest-1'
  472. )
  473. else:
  474. s3 = AmazonS3Util(
  475. AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], 'us-east-1'
  476. )
  477. s3.delete_obj("ansjerfilemanager", file_key)
  478. return True
  479. except Exception as e:
  480. LOGGER.info('删除违规壁纸异常:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  481. return False