diff --git a/fir_admin/src/views/appinfos/AppReleaseDetail.vue b/fir_admin/src/views/appinfos/AppReleaseDetail.vue index e829c2d..b947079 100644 --- a/fir_admin/src/views/appinfos/AppReleaseDetail.vue +++ b/fir_admin/src/views/appinfos/AppReleaseDetail.vue @@ -102,7 +102,7 @@ - + diff --git a/fir_ser/cli.py b/fir_ser/cli.py index 3c1102d..d99e734 100644 --- a/fir_ser/cli.py +++ b/fir_ser/cli.py @@ -3,6 +3,7 @@ # project: 1月 # author: NinEveN # date: 2021/1/9 +import argparse import os import sys import plistlib @@ -10,13 +11,7 @@ import random import re import json import zipfile - -from oss2 import determine_part_size, SizedFileAdapter -from oss2.models import PartInfo -from requests_toolbelt.multipart.encoder import MultipartEncoderMonitor -import oss2 import requests -from androguard.core.bytecodes import apk ''' pip install --upgrade pip @@ -24,6 +19,7 @@ pip install setuptools-rust pip install oss2 pip install requests-toolbelt pip install androguard +pip install qiniu ''' @@ -52,6 +48,9 @@ def alioss_progress_callback_fun(offset, total_size): def upload_aliyunoss(access_key_id, access_key_secret, security_token, endpoint, bucket, local_file_full_path, filename, headers=None): + from oss2 import determine_part_size, SizedFileAdapter + from oss2.models import PartInfo + import oss2 stsauth = oss2.StsAuth(access_key_id, access_key_secret, security_token) bucket = oss2.Bucket(stsauth, endpoint, bucket) total_size = os.path.getsize(local_file_full_path) @@ -73,14 +72,16 @@ def upload_aliyunoss(access_key_id, access_key_secret, security_token, endpoint, offset += num_to_upload part_number += 1 bucket.complete_multipart_upload(filename, upload_id, parts) - print("数据上传存储成功.") + if not filename.endswith('.png.tmp'): + print("\n数据上传存储成功.", end='') def upload_qiniuyunoss(key, token, file_path): from qiniu import put_file ret, info = put_file(token, key, file_path, progress_handler=qiniu_progress_callback) if info.status_code == 200: - print("数据上传存储成功.") + if not token.endswith('.png.tmp'): + print("\n数据上传存储成功.", end='') else: raise AssertionError(info.text) @@ -110,12 +111,13 @@ class FLYCliSer(object): req = requests.put(url, json=data, headers=self._header) if req.status_code == 200: if req.json()['code'] == 1000: - print("APP信息更新成功" + req.text) + print("应用 %s %s 上传更新成功" % (data.get('appname'), data.get('bundleid'))) return raise AssertionError(req.text) def upload_local_storage(self, upload_key, upload_token, app_id, file_path): url = '%s/api/v2/fir/server/upload' % self.fly_cli_domain + from requests_toolbelt.multipart.encoder import MultipartEncoderMonitor m = MultipartEncoderMonitor.from_fields(fields={ 'file': (os.path.basename(file_path), open(file_path, 'rb'), 'application/octet-stream'), 'certinfo': json.dumps( @@ -133,16 +135,24 @@ class FLYCliSer(object): req = requests.post(url, data=m, headers={**self._header, **header}) if req.status_code == 200: if req.json()['code'] == 1000: - print("数据上传存储成功." + req.text) + if not upload_key.endswith('.png.tmp'): + print("\n数据上传存储成功.", end='') return raise AssertionError(req.text) - def upload_app(self, app_path): + def upload_app(self, app_path, r_short, r_name, r_change_log): appobj = AppInfo(app_path) appinfo = appobj.get_app_data() icon_path = appobj.make_app_png(icon_path=appinfo.get("icon_path", None)) bundle_id = appinfo.get("bundle_id") upcretsdata = self.get_upload_token(bundle_id, appinfo.get("type")) + if r_short: + upcretsdata['short'] = r_short + if r_name: + appinfo['labelname'] = r_name + if r_change_log: + upcretsdata['changelog'] = r_change_log + if appinfo.get('iOS', '') == 'iOS': f_type = '.ipa' else: @@ -254,6 +264,7 @@ class AppInfo(object): def __get_android_data(self): try: + from androguard.core.bytecodes import apk apkobj = apk.APK(self.app_path) except Exception as err: raise err @@ -320,14 +331,71 @@ class AppInfo(object): return m.group() +def check_depends(): + cmd_list = ['--upgrade pip', 'setuptools-rust', 'oss2', 'requests-toolbelt', 'androguard', 'qiniu'] + for cmd in cmd_list: + os.system('pip install %s' % cmd) + + +def read_token(token_file='.fly_cli_token'): + if os.path.isfile(token_file): + with open(token_file, 'r') as f: + return f.readline() + + +def write_token(token, token_file='.fly_cli_token'): + with open(token_file, 'w') as f: + f.write(token) + + if __name__ == '__main__': - fly_cli_domain = 'https://app.hehelucky.cn' - fly_cli_token = 'f63d05d2bb0511eb9fa400163e069e27oTa51Q3N6rJT5yjddCrkmgiFeKRQNa0L3TctPLTYd0CrdIqgO3wfYCKsFnJysQXJ' - fly_obj = FLYCliSer(fly_cli_domain, fly_cli_token) - if len(sys.argv) != 2: - raise ValueError('参数有误') - app_path = sys.argv[1] - if os.path.isfile(app_path): - fly_obj.upload_app(app_path) + domain = 'https://app.hehelucky.cn' + base_dir = os.path.dirname(os.path.abspath(__file__)) + parser = argparse.ArgumentParser( + description=""" + flyapps service cli tools; + Example: \r\n + """ + ) + parser.add_argument('-s', '--short', nargs="?", const=True, type=str, help="短连接") + parser.add_argument('-cl', '--change_log', nargs="?", const=True, type=str, help="更新日志") + parser.add_argument('-n', '--name', nargs="?", const=True, type=str, help="名称") + parser.add_argument('-i', '--install_depends', nargs="?", const=True, help="安装依赖") + parser.add_argument('-w', '--write_token_info', nargs="?", const=True) + parser.add_argument('-t', '--token', nargs="?", type=str, help="token") + parser.add_argument('-f', '--filepath', nargs="+", type=str, help="filepath") + parser.add_argument('-d', '--dir_path', nargs="+", type=str, help="dir_path") + args = parser.parse_args() + if args.token and args.write_token_info: + write_token(args.token) + if args.install_depends: + check_depends() + elif args.filepath or args.dir_path: + token = args.token + if not token: + token = read_token() + if token: token = token.replace('\r', '').replace('\n', '') + if not token: + raise Exception('token not exist') + fly_obj = FLYCliSer(domain, token) + file_path_list = [] + if args.filepath is not None and len(args.filepath) > 0: + for args_filepath in args.filepath: + file_path_list.extend(os.path.join(base_dir, args_filepath)) + if args.dir_path is not None and len(args.dir_path) > 0: + for args_dir_path in args.dir_path: + dir_path = os.path.join(base_dir, args_dir_path) + if os.path.isdir(dir_path): + for fil in os.listdir(dir_path): + if os.path.isfile(fil) and fil.split('.')[-1].lower() in ['ipa', 'apk']: + file_path_list.append(fil) + err_file = [] + for filepath in file_path_list: + if os.path.isfile(filepath) and filepath.split('.')[-1].lower() in ['ipa', 'apk']: + fly_obj.upload_app(filepath, args.short, args.name, args.change_log) + else: + err_file.append(filepath) + if err_file: + print("error file", err_file) else: - raise FileNotFoundError(app_path) + parser.print_help()