#!/usr/bin/env python # coding:utf-8 import os import sys import time curr_dir = os.path.split(os.path.abspath(__file__))[0] sys.path.append(os.path.join(curr_dir, '../')) sys.path.append(os.path.join(curr_dir, '../ipm')) level_origin_path = os.path.join(curr_dir, "../../Assets/Bundles/Levels") import json import utils as utils import config as config from firebase.firebase_helper import FirebaseHelper from ipm.clear_cdn import clear_cdn from copy import deepcopy from ipm.wechat_alert import wechat_alert alert = wechat_alert() clear_cdn_tool = clear_cdn(config.app_id, config.domain_list) def upload_single_file(helper, storage_file, local_file, blob_dic, ext_meta={}): try: blob = None if storage_file in blob_dic: blob = blob_dic[storage_file] is_same = False if blob is not None: local_hash = utils.calc_hash(local_file) local_md5 = utils.calc_md5(local_file) storage_hash = "" if blob.metadata is not None and config.meta_hash in blob.metadata: storage_hash = blob.metadata[config.meta_hash] storage_md5 = "" if blob.metadata is not None and config.meta_md5 in blob.metadata: storage_md5 = blob.metadata[config.meta_md5] is_same = storage_hash == local_hash and storage_md5 == local_md5 if not is_same: print(f"{local_file} 上传中..") helper.upload_file(storage_file, local_file, ext_meta) else: pass except Exception as e: print(local_file + " 上传失败,尝试重试,错误信息:" + repr(e)) upload_single_file(helper, storage_file, local_file, blob_dic, ext_meta) def upload_file_with_retry(helper, storage_file, file_path, max_retries=3): """带重试机制的文件上传函数""" for attempt in range(max_retries): try: print(f"{file_path} 上传中..") helper.upload_file_no_metadata(storage_file, file_path) return except Exception as e: if attempt < max_retries - 1: print(f"{file_path} 上传失败,尝试重试 ({attempt + 1}/{max_retries}),错误信息:{repr(e)}") time.sleep(2) # 重试前等待2秒 else: print(f"{file_path} 上传失败,已达到最大重试次数,错误信息:{repr(e)}") raise def get_psd_id(ab_name): arr = ab_name.split("_") return int(arr[len(arr) - 1].split(".")[0]) def upload_directory(helper, storage_path, local_path, filter, ext_meta={}): hasSameFile = False for root, dirs, files in os.walk(local_path): for name in files: if name.endswith(".bundle"): storage_file = f"{storage_path}/{name}" blob = helper.get_file(storage_file) if blob is not None: hasSameFile = True break if hasSameFile: print(f"{storage_path} 相同md5 bundle文件已存在,不重复上传") return print("开始上传Package资源 Local: {} Storage: {}".format(local_path, storage_path)) for root, dirs, files in os.walk(local_path): for name in files: file_path = os.path.join(root, name) storage_file = f"{storage_path}/{name}" if filter in name: upload_single_file(helper, storage_file, file_path, {}, ext_meta) clear_cdn_tool.appendClearFile(storage_file) else: upload_file_with_retry(helper, storage_file, file_path) # 每个文件上传后间隔1秒 time.sleep(1) print("上传完成Package资源 Local: {} Storage: {}".format(local_path, storage_path)) def upload_package_assets(ab_path, modify_files, storage_path, asset_find_num_dict, ext_meta={}): helper = FirebaseHelper() for asset_id in modify_files: if asset_id in asset_find_num_dict: find_num = asset_find_num_dict[asset_id] ext_meta[config.meta_find_num] = find_num asset_gameplay = asset_id.split("_")[0] level_asset_package_dir_path = ab_path.format(asset_id) storage_dir_path = f"{storage_path}/Level/{asset_gameplay}/{asset_id}" if not os.path.exists(level_asset_package_dir_path): print(f"{asset_id}关卡资源目录不存在,{level_asset_package_dir_path}") else: print(f"开始上传{asset_id}关卡资源") upload_directory(helper, storage_dir_path, level_asset_package_dir_path, ".version", ext_meta) level_asset_thum_package_dir_path = ab_path.format(f"{asset_id}_thum") thum_storage_dir_path = f"{storage_path}/Thum/{asset_gameplay}/{asset_id}_thum" if not os.path.exists(level_asset_thum_package_dir_path): print(f"{asset_id}缩略图资源目录不存在,{level_asset_thum_package_dir_path}") else: print(f"开始上传{asset_id}缩略图资源") upload_directory(helper, thum_storage_dir_path, level_asset_thum_package_dir_path, ".version", ext_meta) print(str(modify_files) + "上传成功") clear_cdn_tool.clearCDN() def upload_content_ab(local_path, storage_path, asset_find_num_dict, endswith=[".bundle"], ext_meta={}): origin_ext_meta = deepcopy(ext_meta) """上传ab包及缩略图""" # wx_message.wx_message("开始上传 Local: {} Storage: {}".format(local_path, storage_path)) helper = FirebaseHelper() print(storage_path) blobs = helper.get_files_all_versions(storage_path) blob_dic = {} for a_blob in blobs: if a_blob.metadata is not None and config.meta_encryption in a_blob.metadata and config.meta_encryption in ext_meta and \ a_blob.metadata[config.meta_encryption] == ext_meta[config.meta_encryption]: blob_dic[a_blob.name] = a_blob for root, dirs, files in os.walk(local_path): for name in files: for a_ends in endswith: tmp_ext_meta = origin_ext_meta if name.endswith(a_ends) is False: continue # 上传ab包 is_success, is_thum, gameplay, asset_name = utils.parse_bundle_name(name) fileonlyname = asset_name.replace(".bundle", "") if fileonlyname in asset_find_num_dict: tmp_ext_meta[config.meta_find_num] = asset_find_num_dict[fileonlyname] if is_success: ab_storage_file = f"{storage_path}/Thum/{gameplay}/{asset_name}" if is_thum else f"{storage_path}/Level/{gameplay}/{asset_name}" ab_local_file = os.path.join(root, name) upload_single_file(helper, ab_storage_file, ab_local_file, blob_dic, tmp_ext_meta) # wx_message.wx_message("上传完成 Local: {} Storage: {}".format(local_path, storage_path)) if __name__ == "__main__": pass # upload_content_ab("/Users/castbox/.jenkins/workspace2/AP_unity_bundle/unity_ap_bundle/ArtPuzzleBundle/Tools/BuildPackage/../../Build/Debug/Hotupdate/Bundles/Android/v1.0.0.1", "Android/Bundles/Content", [".ab"], {})