import hashlib import time from django.conf import settings from gm_types.ascle import ERROR from helios.rpc.exceptions import RPCFaultException from utils.base import APIView from utils.channel_package_tools import ChannelPackage from utils.logger import error_logger from .tasks import version_release_task, channel_build, channel_build_one def get_md5_value(src): md5 = hashlib.md5() md5.update(src) md5_digest = md5.hexdigest() return md5_digest class Vendor(APIView): def get(self, request): """ 获取渠道商列表 :param request: :return: """ query = request.GET.get('q', '') page = int(request.GET.get('page', 1)) offset = int(request.GET.get('offset', 30)) data = request.rpc.origin['endpoint']( query=query, start=(page - 1) * offset, offset=offset ).unwrap() return data class ChannelList(APIView): def get(self, request): """ 渠道列表 :param request: :return: """ page = int(request.GET.get('page', 1)) limit = int(request.GET.get('limit', 10)) filters = self.handle_filter(request.GET.get('filter', "")) try: channel_list = self.rpc['venus/sun/channel_build/channel/list']( offset=(page-1)*limit, limit=limit, filters=filters ).unwrap() except Exception as e: error_logger.error(u'获取渠道列表失败:%s', e) raise e data = {'total': channel_list.get('total', 0)} url = settings.APK_DOMAIN + settings.APK_BUILD_DIR + '/' + settings.APK_RELEASE_DIR + \ "/{name}/gm_alpha_{name}.apk?t={timestamp}" channels = [ { 'id': data.get('id'), 'name': data.get('name'), 'url_name': data.get('url_name'), 'pack': data.get('pack'), 'released_version': data.get('released_version'), 'download_url': url.format(name=data.get('url_name'), timestamp=time.time()), } for data in channel_list.get('data', [])] data.update({'channel': channels}) return self.write_success(message='获取渠道列表成功', data=data) class ChannelVersionList(APIView): def get(self, request): """ :param request: :return: """ channel_id = request.GET.get('channel_id') page = int(request.GET.get('page', 1)) limit = int(request.GET.get('limit', 10)) try: channel_list = self.rpc['venus/sun/channel_build/channel_version/list']( offset=(page-1)*limit, limit=limit, channel_id=channel_id ).unwrap() except Exception as e: error_logger.error(u'获取渠道列表失败:%s', e) raise e data = {'total': channel_list.get('total', 0)} url = settings.APK_DOMAIN + settings.APK_BUILD_DIR + "/{version}/{name}/gm_alpha_{name}.apk?t={timestamp}" channels = [ { 'version_id': data.get('version_id'), 'channel_id': data.get('channel_id'), 'version': data.get('version'), 'name': data.get('name'), 'url_name': data.get('url_name'), 'packed_time': data.get('packed_time'), 'packed': data.get('packed'), 'release_time': data.get('release_time'), 'is_released': data.get('is_released'), 'download_url': url.format( version=data.get('version'), name=data.get('url_name'), timestamp=time.time()), } for data in channel_list.get('data', [])] data.update({'channel': channels}) return self.write_success(message='获取渠道列表成功', data=data) class Channel(APIView): def get(self, request): """ 渠道详情 :param request: :return: """ channel_id = request.GET.get('channel_id') if not channel_id: error_logger.error(u'参数不完整') return self.write_fail(code=ERROR.ARG_MISS, message='参数不完整') try: channel_data = self.rpc['venus/sun/channel_build/channel/get']( id=channel_id ).unwrap() except Exception as e: error_logger.error(u'获取渠道详情失败:%s', e) raise e channel = { 'id': channel_data.get('id'), 'name': channel_data.get('name'), 'url_name': channel_data.get('url_name'), 'pack': channel_data.get('pack'), 'type': channel_data.get('type'), 'released_version': channel_data.get('released_version'), } return self.write_success(message='获取渠道详情成功', data=channel) def post(self, request): """ 渠道创建 / 编辑 :param request: :return: """ channel_id = request.POST.get('id', None) channel_name = request.POST.get('name', '') url_name = request.POST.get('url_name', '') auto_pack = request.POST.get('pack', True) channel_type = request.POST.get('type', 2) if not all([channel_name, url_name, auto_pack, channel_type]): error_logger.error(u'参数不完整') return self.write_fail(code=ERROR.ARG_MISS, message='参数不完整') if channel_id: channel = self.rpc['venus/sun/channel_build/channel/get']( id=channel_id ).unwrap() else: channel = {} data = dict() if channel_name: data.update({'name': channel_name}) if url_name: data.update({'url_name': url_name}) if auto_pack: data.update({'pack': auto_pack}) if channel_type: data.update({'type': channel_type}) try: resp = self.rpc['venus/sun/channel_build/channel/edit']( id=channel_id, data=data ).unwrap() except Exception as e: error_logger.error('操作失败%s', e) return self.write_fail(message='路径名不能重复', code=-1) version = resp.get('version', '') if version and channel.get('url_name') != url_name: channel_build_one.delay(version, url_name) return self.write_success(message='操作成功', data={}) class ChannelPacked(APIView): def post(self, request): """ 当前版本的渠道包发布 :param request: :return: """ version_id = request.POST.get('version_id') channel_id = request.POST.get('channel_id') if not all([channel_id, version_id]): error_logger.error(u'参数不完整') return self.write_fail(code=ERROR.ARG_MISS, message='参数不完整') channel = self.rpc['venus/sun/channel_build/channel/get']( id=channel_id ).unwrap() version = self.rpc['venus/sun/channel_build/version/get']( id=version_id ).unwrap() ChannelPackage.publish_apk(channel.get('url_name'), version.get('version')) try: self.rpc['venus/sun/channel_build/version/release']( version_id=version_id, channel_ids=[channel_id] ).unwrap() #发布 except RPCFaultException as e: error_logger.error(u'发布失败:%s', e) return self.write_fail(code=-1, message='发布失败!') return self.write_success(data={}, message='发布成功!') class VersionList(APIView): def get(self, request): """ 所有版本列表 :param request: :return: """ page = int(request.GET.get('page', 1)) offset = int(request.GET.get('limit', 10)) try: version_list = self.rpc['venus/sun/channel_build/version/list']( offset=(page-1)*offset, limit=offset ).unwrap() except Exception as e: error_logger.error(u'获取版本列表失败:%s', e) raise e data = {'total': version_list.get('total', 0)} versions = [ { 'version_id': item.get('id'), 'version': item.get('version'), 'md5': item.get('md5'), 'release_time': item.get('release_time'), } for item in version_list.get('data', []) ] data.update({'data': versions}) return self.write_success(data=data) class VersionChannelList(APIView): def get(self, request): page = int(request.GET.get('page', 1)) offset = int(request.GET.get('limit', 10)) version_id = request.GET.get('version_id', 10) try: version_list = self.rpc['venus/sun/channel_build/version_channel/list']( offset=(page-1)*offset, limit=offset, version_id=version_id ).unwrap() except Exception as e: error_logger.error(u'获取版本列表失败:%s', e) raise e data = {'total': version_list.get('total', 0)} url = settings.APK_DOMAIN + settings.APK_BUILD_DIR + "/{version}/{name}/gm_alpha_{name}.apk?t={timestamp}" sup_url = ChannelPackage.apk_url(channel='', version=version_list.get('version')) + '?t={timestamp}' versions = { 'version': [{ 'channel_id': item.get('channel_id'), 'version_id': item.get('version_id'), 'version': item.get('version'), 'name': item.get('name'), 'packed_time': item.get('packed_time'), 'packed': item.get('packed'), 'download_url': url.format( version=item.get('version'), name=item.get('url_name'), timestamp=time.time()), 'release_time': item.get('release_time'), 'is_released': item.get('is_released'), } for item in version_list.get('data', [])], 'base_apk_url': sup_url.format(timestamp=time.time()), } data.update({'data': versions}) return self.write_success(data=data) class VersionDetailUpdate(APIView): def get(self, request): """ 版本详情 :param request: :return: """ version_id = request.GET.get('version_id') if not version_id: error_logger.error(u'参数不完整') return self.write_fail(code=ERROR.ARG_MISS, message='参数不完整') version_info = self.rpc['venus/sun/channel_build/version/get']( id=version_id ).unwrap() data = { 'id': version_info.get('id'), 'version': version_info.get('version'), 'release_time': version_info.get('release_time'), 'md5': version_info.get('md5'), 'description': version_info.get('description'), } return self.write_success(data=data, message='操作成功') def post(self, request): """ 版本信息编辑 只允许修改描述 :param request: :return: """ version_id = request.POST.get('id') version = request.POST.get('version') md5 = request.POST.get('md5') release_time = request.POST.get('release_time') desc = request.POST.get('description') if not version_id: error_logger.error(u'参数不完整') return self.write_fail(code=ERROR.ARG_MISS, message='参数不完整') data = dict() if version: data.update({'version': version}) if release_time: data.update({'release_time': release_time}) if desc: data.update({'description': desc}) if md5: data.update({'md5': md5}) try: self.rpc['venus/sun/channel_build/version/edit']( id=version_id, data=data ).unwrap() except Exception as e: error_logger.error(e) return self.write_fail(code=-1, message='操作失败') return self.write_success(data={}, message='操作成功') class BatchPublishVersion(APIView): def post(self, request): """ 批量发布 并邮件通知 :param request: :return: """ version_id = request.POST.get('version_id') if not version_id: error_logger.error(u'参数不完整') return self.write_fail(code=ERROR.ARG_MISS, message='参数不完整') try: # 获取当前版本所有已打包渠道 channel_info = self.rpc['venus/sun/channel_build/version/get_channel_info']( version_id=version_id ).unwrap() except RPCFaultException as e: error_logger.error(u'获取渠道失败%s', e) return self.write_fail(code=-1, message='获取渠道失败!') packed_channels = list() for item in channel_info.get('data', []): if item.get('pack', False): packed_channels.append(item) version_release_task.delay( packed_channels, version_id=version_id, version=channel_info.get('version') ) return self.write_success(data={}, message='操作成功') class VersionCreate(APIView): def post(self, request): """ 版本创建 供脚本使用 :param request: :return: """ apk = request.FILES.get('file').read() file_md5 = get_md5_value(apk) version = request.POST.get('version') md5 = request.POST.get('md5') if md5 != file_md5: raise Exception('md5校验失败, 文件md5{}'.format(file_md5)) data = dict() if version: data.update({'version': version}) if md5: data.update({'md5': md5}) try: version_id = self.rpc['venus/sun/channel_build/version/edit']( data=data ).unwrap() except RPCFaultException as e: error_logger.error('创建版本失败:%s', e) raise Exception('创建版本失败!') channel_info = self.rpc['venus/sun/channel_build/version/get_channel_info']( version_id=version_id ).unwrap() # 所有渠道的url_name: list() url_names = [] for item in channel_info.get('data', []): if item.get('pack', False): url_names.append(item.get('url_name')) channel_build.delay(version, url_names, apk) return {'success': True}