# -*- encoding: utf-8 -*- """ @File : UserDeviceShareController.py @Time : 2023/1/7 15:05 @Author : stephen @Email : zhangdongming@asj6.wecom.work @Software: PyCharm """ import json import logging import threading import time import boto3 import botocore from botocore import client from django.db import transaction from django.db.models import Q from django.views import View from Model.models import DeviceSharePermission, DeviceChannelUserSet, DeviceChannelUserPermission, UidChannelSetModel, \ Device_Info from Object.ContentSecurityObject import ContentSecurity from Object.ResponseObject import ResponseObject from Object.TokenObject import TokenObject from Service.UserDeviceService import UserDeviceService from Ansjer.config import CONFIG_CN, CONFIG_INFO, CONFIG_TEST, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, \ AWS_SES_ACCESS_REGION, AWS_IOT_SES_ACCESS_CHINA_REGION from Model.models import DeviceWallpaper from Object.AWS.AmazonS3Util import AmazonS3Util LOGGER = logging.getLogger('info') class UserDeviceShareView(View): def get(self, request, *args, **kwargs): request.encoding = 'utf-8' operation = kwargs.get('operation') return self.validation(request.GET, request, operation) def post(self, request, *args, **kwargs): request.encoding = 'utf-8' operation = kwargs.get('operation') return self.validation(request.POST, request, operation) def validation(self, request_dict, request, operation): token = TokenObject(request.META.get('HTTP_AUTHORIZATION')) lang = request_dict.get('lang', token.lang) response = ResponseObject(lang) if token.code != 0: return response.json(token.code) if operation == 'user-permissions': return self.get_user_share_permission(request_dict, response) elif operation == 'permissions-save': return self.user_channel_permission_save(request_dict, response) elif operation == 'permissions-test': return self.synch_share_device_permission(response) elif operation == 'getWallpaperList': return self.get_wallpaper_list(request_dict, response) elif operation == 'getUploadWallpaper': return self.get_upload_wallpaper(request_dict, response) elif operation == 'notifyUploadWallpaper': return self.notify_upload_wallpaper(request_dict, response) elif operation == 'delWallpaper': return self.del_wallpaper(request_dict, response) elif operation == 'selectWallpaper': return self.select_wallpaper(request_dict, response) else: return response.json(404) @classmethod def get_user_share_permission(cls, request_dict, response): """ 获取用户分享权限 @param request_dict: 设备uid @param response: 响应对象 @return: permission List """ try: uid = request_dict.get('uid', None) user_id = request_dict.get('userId', None) channel_count = request_dict.get('channelCount', None) if not all([user_id, uid, channel_count]): return response(444, 'uid, userId and channelCount is required') user_permission_qs = DeviceChannelUserSet.objects.filter(user_id=user_id, uid=uid) \ .values('id', 'channels') if not user_permission_qs.exists(): return response.json(0, {}) up_id = user_permission_qs[0]['id'] channel_permission_qs = DeviceChannelUserPermission.objects.filter(channel_user_id=up_id) \ .values('permission_id', 'channel_user_id') if not channel_permission_qs.exists(): return response.json(0, {}) channel_list = list(range(1, int(channel_count) + 1)) share_channel_list = user_permission_qs[0]['channels'].split(',') c_list = [] for channel in channel_list: is_select = 1 if str(channel) in share_channel_list else 0 c_list.append({'channelIndex': channel, 'isSelect': is_select}) p_list = [] permission_qs = DeviceSharePermission.objects.all() share_permission_list = [item['permission_id'] for item in channel_permission_qs] for item in permission_qs: is_select = 1 if item.id in share_permission_list else 0 p_list.append({'permissionId': item.id, 'code': item.code, 'isSelect': is_select}) data = {'channels': c_list, 'permissions': p_list} return response.json(0, data) except Exception as e: LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e))) return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) @classmethod def user_channel_permission_save(cls, request_dict, response): """ 主用户分享设备时设置通道权限保存 """ try: uid = request_dict.get('uid', None) channels = request_dict.get('channels', None) # 通道集合,多个','隔开 user_id = request_dict.get('userId', None) permission_ids = request_dict.get('permissionIds', None) # 权限集合,多个','隔开 if not all([user_id, uid, channels, permission_ids]): return response.json(444) p_ids = [] device_user_set = DeviceChannelUserSet.objects.filter(user_id=user_id, uid=uid) now_time = int(time.time()) with transaction.atomic(): is_delete = False if not device_user_set.exists(): device_set = {'uid': uid, 'user_id': user_id, 'channels': channels, 'created_time': now_time, 'updated_time': now_time} device_user_set = DeviceChannelUserSet.objects.create(**device_set) channel_user_id = device_user_set.id else: DeviceChannelUserSet.objects.update(channels=channels, updated_time=now_time) channel_user_id = device_user_set.first().id is_delete = True if ',' in permission_ids: p_ids = [int(val) for val in permission_ids.split(',')] if is_delete: DeviceChannelUserPermission.objects.filter( channel_user_id=channel_user_id).delete() if not p_ids: channel_permission = {'permission_id': int(permission_ids), 'channel_user_id': channel_user_id, 'created_time': now_time} DeviceChannelUserPermission.objects.create(**channel_permission) else: channel_permission_list = [] for item in p_ids: channel_permission_list.append(DeviceChannelUserPermission( permission_id=int(item), channel_user_id=channel_user_id, created_time=now_time)) DeviceChannelUserPermission.objects.bulk_create(channel_permission_list) return response.json(0) except Exception as e: LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e))) return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) @staticmethod def qrcode_share_channel_permission_save(user_id, uid): """ 二维码分享保存通道权限 @param user_id: 用户id @param uid: 用户设备ID @return: True | False """ try: if not all([user_id, uid]): return False with transaction.atomic(): ds_qs = DeviceChannelUserSet.objects.filter(user_id=user_id, uid=uid) if ds_qs.exists(): return True UserDeviceService.update_device_channel(uid) channel_qs = UidChannelSetModel.objects.filter(uid__uid=uid).values('channel') if not channel_qs.exists(): return False channel_list = [str(val['channel']) for val in channel_qs] channel_str = ','.join(channel_list) now_time = int(time.time()) device_set = {'uid': uid, 'user_id': user_id, 'channels': channel_str, 'created_time': now_time, 'updated_time': now_time} device_user_set = DeviceChannelUserSet.objects.create(**device_set) channel_permission_qs = DeviceSharePermission.objects \ .all().values('id', 'code').order_by('sort') user_set_id = device_user_set.id channel_permission_list = [] for item in channel_permission_qs: channel_permission_list.append(DeviceChannelUserPermission( permission_id=item['id'], channel_user_id=user_set_id, created_time=now_time)) DeviceChannelUserPermission.objects.bulk_create(channel_permission_list) return True except Exception as e: LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e))) return False @staticmethod def synch_share_device_permission(response): """ 同步分析设备权限 @param response: 响应结果 """ device_info_qs = Device_Info.objects \ .filter(~Q(Type__in=[1, 2, 3, 4, 10001]), ~Q(primaryUserID=''), isShare=1) \ .values('userID_id', 'UID').order_by('-data_joined') if not device_info_qs.exists(): return response.json(0) for item in device_info_qs: UserDeviceShareView.qrcode_share_channel_permission_save(item['userID_id'], item['UID']) return response.json(0) @classmethod def get_wallpaper_list(cls, request_dict, response): """ 获取设备壁纸列表 @param request_dict: @param response: @return: """ try: device_type = int(request_dict.get('deviceType', None)) uid = request_dict.get('uid', None) channel = int(request_dict.get('channel', 1)) LOGGER.info('获取设备壁纸列表参数:{}'.format(request_dict)) if not all([device_type, uid]): return response.json(444) # 查询用户自定义壁纸 user_wallpaper_qs = DeviceWallpaper.objects.filter(channel=channel, uid=uid, device_type=device_type, parent_id=0, status=1) # 查询系统默认壁纸 def_wallpaper_qs = DeviceWallpaper.objects.filter(classification=1, device_type=device_type, uid='', status=1) # 查询用户选中的壁纸 user_checked_qs = DeviceWallpaper.objects.filter(channel=channel, uid=uid, device_type=device_type, parent_id__gt=0, status=1) checked_id = user_checked_qs[0].parent_id if user_checked_qs.exists() else 0 wallpaper_list = [] if def_wallpaper_qs.exists() or user_wallpaper_qs.exists(): # 初始化存储桶客户端 if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO: s3 = boto3.client( 's3', aws_access_key_id=AWS_ACCESS_KEY_ID[0], aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0], config=botocore.client.Config(signature_version='s3v4'), region_name='cn-northwest-1' ) else: s3 = boto3.client( 's3', aws_access_key_id=AWS_ACCESS_KEY_ID[1], aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1], config=botocore.client.Config(signature_version='s3v4'), region_name='us-east-1' ) # 处理系统默认壁纸和用户自定义壁纸 all_wallpapers_qs = def_wallpaper_qs.union(user_wallpaper_qs) for item in all_wallpapers_qs: obj_key = item.obj_prefix + item.obj_name params = { 'Key': obj_key, 'Bucket': 'ansjerfilemanager', } response_url = s3.generate_presigned_url( 'get_object', Params=params, ExpiresIn=3600) wallpaper = { 'id': item.id, 'url': response_url, 'state': 1 if checked_id == item.id else 0, 'classification': item.classification } wallpaper_list.append(wallpaper) return response.json(0, {'wallpapers': wallpaper_list}) except Exception as e: LOGGER.error('查询设备壁纸异常:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e))) return response.json(5) @classmethod def get_upload_wallpaper(cls, request_dict, response): """ 获取设备壁纸上传链接 @param request_dict: @param response: @return: """ try: uid = request_dict.get('uid', None) channel = int(request_dict.get('channel', 1)) if not uid: return response.json(444) # 初始化存储桶客户端 if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO: s3 = boto3.client( 's3', aws_access_key_id=AWS_ACCESS_KEY_ID[0], aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0], config=botocore.client.Config(signature_version='s3v4'), region_name='cn-northwest-1' ) else: s3 = boto3.client( 's3', aws_access_key_id=AWS_ACCESS_KEY_ID[1], aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1], config=botocore.client.Config(signature_version='s3v4'), region_name='us-east-1' ) # 生成唯一的文件名 file_name = f"{int(time.time())}.png" obj_key = f"app/static/device-wallpaper/{uid}/{file_name}" # 生成预签名的 URL presigned_url = s3.generate_presigned_url( 'put_object', Params={ 'Bucket': 'ansjerfilemanager', 'Key': obj_key, }, ExpiresIn=600 ) # 返回预签名的URL和字段 return response.json(0, { 'uploadUrl': presigned_url, 'fileName': file_name, }) except Exception as e: LOGGER.error('获取上传链接异常:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e))) return response.json(5) @classmethod def notify_upload_wallpaper(cls, request_dict, response): """ 确认壁纸上传成功,创建DeviceWallpaper @param request_dict: @param response: @return: """ try: uid = request_dict.get('uid', None) file_name = request_dict.get('fileName', None) channel = int(request_dict.get('channel', 1)) if not all([uid, file_name]): return response.json(444) device_info_qs = Device_Info.objects.filter(UID=uid).values('id', 'Type') device_type = device_info_qs[0]['Type'] if device_info_qs.exists() else '' # 初始化存储桶客户端 if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO: s3 = boto3.client( 's3', aws_access_key_id=AWS_ACCESS_KEY_ID[0], aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0], config=botocore.client.Config(signature_version='s3v4'), region_name='cn-northwest-1' ) else: s3 = boto3.client( 's3', aws_access_key_id=AWS_ACCESS_KEY_ID[1], aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1], config=botocore.client.Config(signature_version='s3v4'), region_name='us-east-1' ) obj_key = f"app/static/device-wallpaper/{uid}/{file_name}" params = {'Bucket': "ansjerfilemanager", 'Key': obj_key} image_url = s3.generate_presigned_url('get_object', Params=params) service = 'profilePhotoCheck' LOGGER.info('壁纸链接:{}'.format(image_url)) service_dict = {'imageUrl': image_url} service_parameters = json.dumps(service_dict) legal = ContentSecurity().image_review(service, service_parameters) if not legal: # 异步删除 thread = threading.Thread(target=cls.delete_wallpaper, args=(obj_key,)) thread.start() return response.json(184) DeviceWallpaper.objects.create( device_type=device_type, storage_type=1, channel=channel, uid=uid, obj_prefix=f'app/static/device-wallpaper/{uid}/', obj_name=file_name, classification=2, # 自定义壁纸分类 status=1, parent_id=0, created_time=int(time.time()) ) return response.json(0) except Exception as e: LOGGER.error('壁纸创建失败:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e))) return response.json(5) @classmethod def del_wallpaper(cls, request_dict, response): """ 删除设备壁纸 """ wallpaper_id = request_dict.get('wallpaperId', None) if not all([wallpaper_id]): return response.json(444) try: wallpaper_id = int(wallpaper_id) if DeviceWallpaper.objects.filter(id=wallpaper_id, classification=1).exists(): return response.json(176, "系统图片不能删除") device_wallpaper_qs = DeviceWallpaper.objects.filter(id=wallpaper_id) device_wallpaper = device_wallpaper_qs.values("obj_prefix", "obj_name", "uid", "parent_id") uid = device_wallpaper[0]['uid'] obj_name = device_wallpaper[0]['obj_name'] # 使用中壁纸被删除 use_device_wallpaper = DeviceWallpaper.objects.filter(uid=uid, parent_id__gt=0).first() if use_device_wallpaper and use_device_wallpaper.parent_id == wallpaper_id: system_device_wallpaper = DeviceWallpaper.objects.filter(id=1).first() use_device_wallpaper.parent_id = 1 use_device_wallpaper.storage_type = system_device_wallpaper.storage_type use_device_wallpaper.obj_name = system_device_wallpaper.obj_name use_device_wallpaper.obj_prefix = system_device_wallpaper.obj_prefix use_device_wallpaper.classification = system_device_wallpaper.classification use_device_wallpaper.channel = system_device_wallpaper.channel use_device_wallpaper.save() if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO: s3 = AmazonS3Util( AWS_ACCESS_KEY_ID[0], AWS_SECRET_ACCESS_KEY[0], 'cn-northwest-1' ) else: s3 = AmazonS3Util( AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], 'us-east-1' ) s3.delete_obj("ansjerfilemanager", f"app/static/device-wallpaper/{uid}/{obj_name}") device_wallpaper_qs.delete() return response.json(0) except Exception as e: LOGGER.info('删除壁纸异常:{}'.format(e)) return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))) @classmethod def select_wallpaper(cls, request_dict, response): """ 用户选取壁纸 @param request_dict: @param response: @return: """ try: wallpaper_id = request_dict.get('wallpaperId', None) uid = request_dict.get('uid', None) if not all([wallpaper_id, uid]): return response.json(444) device_wallpaper = DeviceWallpaper.objects.filter(id=wallpaper_id).values("device_type", "storage_type", "obj_prefix", "obj_name", "classification", "channel").first() device_wallpaper_qs = DeviceWallpaper.objects.filter(uid=uid, parent_id__gt=0) if device_wallpaper_qs.exists(): device_wallpaper_qs.update( storage_type=device_wallpaper["storage_type"], classification=device_wallpaper["classification"], obj_prefix=device_wallpaper["obj_prefix"], obj_name=device_wallpaper["obj_name"], parent_id=wallpaper_id ) else: DeviceWallpaper.objects.create( device_type=device_wallpaper["device_type"], storage_type=device_wallpaper["storage_type"], obj_name=device_wallpaper["obj_name"], obj_prefix=device_wallpaper["obj_prefix"], classification=device_wallpaper["classification"], uid=uid, channel=device_wallpaper["channel"], status=1, parent_id=wallpaper_id, created_time=int(time.time()) ) return response.json(0) except Exception as e: LOGGER.error('用户选取壁纸异常:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e))) return response.json(5) @staticmethod def delete_wallpaper(file_key): try: if CONFIG_CN == CONFIG_INFO or CONFIG_TEST == CONFIG_INFO: s3 = AmazonS3Util( AWS_ACCESS_KEY_ID[0], AWS_SECRET_ACCESS_KEY[0], 'cn-northwest-1' ) else: s3 = AmazonS3Util( AWS_ACCESS_KEY_ID[1], AWS_SECRET_ACCESS_KEY[1], 'us-east-1' ) s3.delete_obj("ansjerfilemanager", file_key) return True except Exception as e: LOGGER.info('删除违规壁纸异常:errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e))) return False