def process_exception(self, request: HttpRequest, e: Exception): Trace("执行[%s][%s]出错" % (request.path, json_str(getattr(request, "_orig_params", {}))[:1000]), e) msg = str(e) if isinstance(e, AssertionError) else "服务器出错" if len(msg) > 1000: msg = msg[:996] + " ..." return HttpResponse(json_str({ "ret": -1, "error": msg, }), content_type="application/json", status=500)
def wrapper(self, req: HttpRequest, *args, **kwargs): is_req = isinstance(req, HttpRequest) if is_req: orig_params = {} orig_params.update(self.default_params) if len(req.POST): orig_params.update(to_simple_str_dict(req.POST)) if len(req.GET): orig_params.update(to_simple_str_dict(req.GET)) if len(req.FILES): for f, c in req.FILES.items(): orig_params[f] = c.read() if len(req.COOKIES): for k, v in req.COOKIES.items(): orig_params["$c_%s" % k] = v _path = req.path.split("/") if len(_path) > 3: # 基于路径的参数 for i in range(4, len(_path), 2): orig_params[_path[i - 1]] = _path[i] content_type = req.META.get("CONTENT_TYPE", "") if content_type.startswith('multipart'): pass elif len(req.body): if "json" in content_type: orig_params.update(json.loads(req.body.decode('utf8'))) elif "text" in content_type: orig_params.update(json.loads(req.body.decode('utf8'))) req._orig_params = orig_params else: orig_params = dict(self.default_params) orig_params.update(req) # noinspection PyNoneFunctionAssignment pre_ret = self.pre_wrapper(req, orig_params, *args, **kwargs) if pre_ret is not None: if pre_ret is True: pass else: return pre_ret params = {} if len(self.params_hints): if is_req: for each in self.req_inject_func: each(req, params) for each in self.inject_func: each(orig_params, params) for k, hint in self.params_hints: # type:Tuple[str,any] if k.startswith("_"): continue if k not in orig_params: raise Fail("缺少参数[%s]" % k) params[k] = get_data(orig_params[k], hint) for each in self.last_inject_func: each(orig_params, params) try: ret = self.func(**params) if ret is None: ret = { "succ": True, } except Exception as e: # _be_log = req._log if is_req else req.get("_log") # type:BeLog # if _be_log: # _be_log.ret = str(e) Trace("出现异常", e) raise e finally: # with Block("处理log部分", fail=False): # _be_log = req._log if is_req else req.get("_log") # type:BeLog # if _be_log: # _be_log.save() pass return ret
def __add_device(account: IosAccountInfo, udid: str, project: str) -> bool: title = "设备%s" % udid _config = IosAccountHelper(account) try: _device = IosDeviceInfo.objects.filter( udid=udid).first() # type:Optional[IosDeviceInfo] if not _device: # 先注册设备 ret = _config.post( "验证设备udid", "https://developer.apple.com/services-account/QH65B2/account/ios/device/validateDevices.action?teamId=", { "deviceNames": title, "deviceNumbers": udid, "register": "single", "teamId": _config.team_id, }, cache=True) Assert( len(ret["failedDevices"]) == 0, "验证udid请求失败[%s][%s]" % (udid, ret["validationMessages"])) __list_all_devices(_config) ret = _config.post( "添加设备", "https://developer.apple.com/services-account/QH65B2/account/ios/device/addDevices.action?teamId=%s" % _config.team_id, { "deviceClasses": "iphone", "deviceNames": title, "deviceNumbers": udid, "register": "single", "teamId": _config.team_id, }, csrf=True) Assert(ret["resultCode"] == 0, "添加udid请求失败[%s]" % udid) Assert(not ret["validationMessages"], "添加udid请求失败[%s]" % udid) Assert(ret["devices"], "添加udid请求失败[%s]" % udid) device = ret["devices"][0] # type: Dict _reg_device(device["deviceId"], device["deviceNumber"], device["model"], device["serialNumber"]) with Block("更新"): ret, _info = __list_all_profile(_config, project) if not _info: _info = IosProfileInfo() _info.sid = "%s:%s" % (_config.account, project) _info.app = _config.account _info.devices = "[]" _info.devices_num = 0 _info.project = project devices = str_json(_info.devices) # type: List[str] if udid in devices: pass else: devices.append(udid) with Block("默认全开当期的设备"): # noinspection PyTypeChecker devices = list( set(devices + str_json(_config.info.devices))) _cert = _get_cert(_config.info) _app = _get_app(_config, project) found = False for each in ret["provisioningProfiles"]: # type: Dict if each["name"] != "专用 %s" % project: continue # todo: 过期更新 ret = _config.post( "更新ProvisioningProfile", "https://developer.apple.com/services-account/QH65B2/account/ios/profile/regenProvisioningProfile.action?teamId=", data={ "provisioningProfileId": each["provisioningProfileId"], "distributionType": "limited", "subPlatform": "", "returnFullObjects": False, "provisioningProfileName": each["name"], "appIdId": _app.app_id_id, "certificateIds": _cert.cert_req_id, "deviceIds": ",".join(_get_device_id(devices).values()), }, csrf=True) Assert(ret["resultCode"] == 0) _info.devices = json_str(devices) _info.profile_id = each["provisioningProfileId"] # noinspection PyTypeChecker _info.profile = ret["provisioningProfile"][ "encodedProfile"] _info.expire = _to_dt( ret["provisioningProfile"]["dateExpire"]) _info.save() found = True Log("更新证书[%s]添加设备[%s][%s]成功" % (project, udid, len(devices))) break if not found: ret = _config.post( "创建ProvisioningProfile", "https://developer.apple.com/services-account/QH65B2/account/ios/profile/createProvisioningProfile.action?teamId=", data={ "subPlatform": "", "certificateIds": _cert.cert_req_id, "deviceIds": ",".join(_get_device_id(devices).values()), "template": "", "returnFullObjects": False, "distributionTypeLabel": "distributionTypeLabel", "distributionType": "limited", "appIdId": _app.app_id_id, "appIdName": _app.name, "appIdPrefix": _app.prefix, "appIdIdentifier": _app.identifier, "provisioningProfileName": "专用 %s" % project, }, csrf=True) Assert(ret["resultCode"] == 0) # noinspection PyTypeChecker _info.profile_id = ret["provisioningProfile"][ "provisioningProfileId"] # noinspection PyTypeChecker _info.profile = ret["provisioningProfile"][ "encodedProfile"] _info.expire = _to_dt( ret["provisioningProfile"]["dateExpire"]) _info.save() Log("添加证书[%s]添加设备[%s][%s]成功" % (project, udid, len(devices))) except Exception as e: Trace("添加设备出错了[%s]" % e, e) return False return True
def resign_ipa(self: Task, uuid: str, cert: str, cert_url: str, cert_md5: str, mp_url, mp_md5, project, ipa_url, ipa_md5, ipa_new, upload_url, process_url: str): worker = self.request.hostname Log("[%s]启动Celery任务[%s][%s][%s]" % (worker, uuid, self.request.retries, json_str(self.request.kwargs))) base = tempfile.gettempdir() _update_state(process_url, worker, "ready") try: # 确认ipa with Block("cert部分"): if cert in _certs: Log("钥匙串中已经拥有证书[%s]" % cert) else: _refresh_certs() if cert in _certs: Log("钥匙串中已经拥有证书[%s]" % cert) else: _update_state(process_url, worker, "prepare_cert") Log("下载证书p12[%s]" % cert) file_cert = os.path.join(base, "cert.p12") _download(cert_url, file_cert, md5=cert_md5) Log("导入证书p12[%s]" % cert) assert call( [SECURITY_BIN, "import", file_cert, "-P", "q1w2e3r4"]) == 0, "导入证书[%s]失败" % cert if not _check_cert(cert): _update_state(process_url, worker, "exception", fail=True) with Block("mobileprovision部分"): file_mp = os.path.join(base, "package.mobileprovision") if os.path.isfile(file_mp) and md5bytes( read_binary_file(file_mp)) == mp_md5: Log("采用本地的mobileprovision文件") else: _update_state(process_url, worker, "prepare_mp") Log("下载mobileprovision文件") os.makedirs(os.path.join("package", project), exist_ok=True) _download(mp_url, file_mp, md5=mp_md5) with Block("ipa部分"): file_ipa = os.path.join("package", project, "orig.ipa") if os.path.isfile(file_ipa) and md5bytes( read_binary_file(file_ipa)) == ipa_md5: Log("采用本地的ipa文件") else: _update_state(process_url, worker, "prepare_ipa") Log("下载ipa文件[%s]" % ipa_url) os.makedirs(os.path.join("package", project), exist_ok=True) _download(ipa_url, file_ipa, md5=ipa_md5) with Block("打包"): Log("开始打包[%s]" % project) file_new = os.path.join("package", project, ipa_new) _update_state(process_url, worker, "resign") # noinspection PyBroadException _package(file_ipa, file_mp, cert, file_new) with Block("上传"): _update_state(process_url, worker, "upload_ipa") Log("上传ipa[%s][%s]" % (project, upload_url)) # todo: 断点续传 rsp = requests.post(upload_url, files={ "worker": worker, "file": read_binary_file(file_new), }) assert rsp.status_code == 200 assert rsp.json()["ret"] == 0 Log("任务完成") _update_state(process_url, worker, "succ", fail=True) return { "succ": True, "uuid": uuid, } except Exception as e: Trace("打包任务失败了", e) _update_state(process_url, worker, "fail")