美文网首页
python一键实现apk编译打包、上传蒲公英、企业微信机器人提

python一键实现apk编译打包、上传蒲公英、企业微信机器人提

作者: 激扬飞雪 | 来源:发表于2023-04-12 10:22 被阅读0次

    编译脚本组成

    1681351227078.png

    1、buildApk.py:位于根目录,调用不同平台shell的gradlew clean 和 根据用户选择gradlew assembleRelease或者 gradlew assembleDebug ,调用UploadUtil.uploadPuGongYing(vSysInfo=vSysInfo)上传到蒲公英平台
    2、upload_pgyer.py:蒲公英官方api 2.0上传apk,获取上传后的apk信息
    3、upload.py: 调用蒲公英官方上传api, 将获取到apk信息发送到企业微信群机器人提醒
    4、buildUpdateMsg.txt:更新日志,此内容会更新到蒲公英更新描述和企业微信群内

    编译环境

    1、安装python 3版本
    2、使用pip install requests库
    3、执行python buildApk.py

    buildApk.py

    # -*- coding: utf-8 -*-
    # -*- author: zhoulikai-*-
    import subprocess
    import os
    import time
    import platform
    from buildScript import upload as UploadUtil
    
    
    import sys
    import shutil
    from pathlib import Path
    
    
    def main():
        tip = """
        请输入编译0:debug 1:release
        0、debug
        1、release
        """
        print(tip)
        vSys = input("")
        vSysInfo = "Debug"
        if vSys == "1":
            vSysInfo = "Release"
        else:
            vSysInfo = "Debug"
        print("编译版本:" + vSysInfo)
        print("*********************************编译开始**********************************")
        #删除以前的编译文件
        # apkFiles = os.path.join(os.getcwd(), "releaseApks")
        # if (os.path.exists(apkFiles)):
        #     print("缓存目录存在")
        #     for root, dirs, files in os.walk(apkFiles, topdown=False):
        #         for name in files:
        #             print(name)
        #             os.remove(os.path.join(root, name))
        #         for name in dirs:
        #             print(name)
        #             os.rmdir(os.path.join(root, name))
        #     time.sleep(3)
        #     os.rmdir(apkFiles)
    
        print("开始执行 gradlew clean")
        systemInfo = platform.system().lower()
        print("编译系统:%s" % systemInfo)
        commond = os.path.join(os.getcwd(), "gradlew.bat" if systemInfo == "windows" else "gradlew")
        # cleanResult = os.system(commond)
        # print(cleanResult)
        # cleanResult = subprocess.call([commond, "clean"],shell=True)
        cleanResult = os.system(commond + " clean")
        # cleanResult = 0
        if (cleanResult == 0):
            print("执行 gradlew clean结束")
            print("开始执行 gradlew assemble")
            # assembleResult = subprocess.call([commond, "assemble" + vSysInfo],shell=True)
            assembleResult = os.system(commond + " assemble" + vSysInfo)
            # assembleResult = 0
            if (assembleResult == 0):
                print("执行gradlew assemble成功")
                print("*********************************编译结束**********************************")
                UploadUtil.uploadPuGongYing(vSysInfo=vSysInfo)
            else:
                print("执行gradlew assemble失败")
        else:
            print("执行gradlew clean 失败")
    
    if __name__ == "__main__":
        main()
    
    

    upload_pgyer.py

    # -*- coding: utf-8 -*-
    # -*- author: LinXunFeng -*-
    
    import time
    import requests
    
    # 官方文档
    # https://www.pgyer.com/doc/view/api#fastUploadApp
    
    def _getCOSToken(
        api_key, 
        install_type, 
        password='', 
        update_description='', 
        callback=None
    ):
      """
      获取上传的 token
      """
      headers = {'enctype': 'multipart/form-data'}
      payload = {
        '_api_key': api_key, # API Key
        'buildType': 'android', # 需要上传的应用类型,ios 或 android
        'buildInstallType': install_type, # (选填)应用安装方式,值为(1,2,3,默认为1 公开安装)。1:公开安装,2:密码安装,3:邀请安装
        'buildPassword': password, # (选填) 设置App安装密码,密码为空时默认公开安装
        'buildUpdateDescription': update_description, # (选填) 版本更新描述,请传空字符串,或不传。
      }
      try:
        r = requests.post('https://www.pgyer.com/apiv2/app/getCOSToken', data=payload, headers=headers)
        if r.status_code == requests.codes.ok:
          result = r.json()
          # print(result)
          if callback is not None:
            callback(True, result)
        else:
          if callback is not None:
              callback(False, None)
      except Exception as e:
        print('服务器暂时无法为您服务', e)
    
    
    def upload_to_pgyer(path, api_key, install_type=2, password='', update_description='', callback=None):
        """
        上传到蒲公英
        :param path: 文件路径
        :param api_key: API Key
        :param install_type: 应用安装方式,值为(1,2,3)。1:公开,2:密码安装,3:邀请安装。默认为1公开
        :param password: App安装密码
        :param update_description:
        :return: 版本更新描述
        """
    
        def getCOSToken_callback(isSuccess, json):
          if isSuccess:
            _upload_url = json['data']['endpoint']
            
            files = {'file': open(path, 'rb')}
            headers = {'enctype': 'multipart/form-data'}
            payload = json['data']['params']
            print("上传中...")
            
            try:
              r = requests.post(_upload_url, data=payload, files=files, headers=headers)
              if r.status_code == 204:
                # result = r.json()
                # print(result)
                print("上传成功,正在获取包处理信息,请稍等...")
                _getBuildInfo(api_key=api_key, json=json, callback=callback)
              else:
                print('HTTPError,Code:'+ str(r.status_code))
                if callback is not None:
                  callback(False, None)
            except Exception as e:
              print('服务器暂时无法为您服务', e)
          else:
              pass
    
        _getCOSToken(
          api_key=api_key, 
          install_type=install_type, 
          password=password, 
          update_description=update_description, 
          callback=getCOSToken_callback,
        )
    
    def _getBuildInfo(api_key, json, callback=None):
        """
        检测应用是否发布完成,并获取发布应用的信息
        """
        time.sleep(3) # 先等个几秒,上传完直接获取肯定app是还在处理中~
        response = requests.get('https://www.pgyer.com/apiv2/app/buildInfo', params={
          '_api_key': api_key,
          'buildKey': json['data']['params']['key'],
        })
        if response.status_code == requests.codes.ok:
          result = response.json()
          code = result['code']
          if code == 1247 or code == 1246: # 1246   应用正在解析、1247 应用正在发布中
            print("------_getBuildInfo-------")
            _getBuildInfo(api_key=api_key, json=json, callback=callback)
          else:
            if callback is not None:
              callback(True, result)
        else:
          if callback is not None:
            callback(False, None)
    
    
    

    upload.py

    # -*- coding: utf-8 -*-
    # -*- author: zhoulikai -*-
    
    from buildScript import upload_pgyer as PgyerUtil
    import os
    import requests
    import json
    import platform
    
    #配置信息
    os.environ['NO_PROXY']="www.pgyer.com,qyapi.weixin.qq.com"
    pgyer_api_key = 'API KEY' # API KEY
    pgyer_password = '1234' # 安装密码
    update_description = ""
    webhook_url="企业微信机器人webhook地址"
    buildTime = ""
    userBuild = ""
    #读取更新内容
    def readUpdateMsg():
      f = open('buildUpdateMsg.txt', 'r', encoding='utf-8')
      try:
        lines = f.readlines()
        # print(lines)
        return lines
      finally:
        f.close()
      pass
    
    #发送企业微信机器人消息
    def send_wechat_msg(content, webhook_url= "你的机器人webhook地址"):
      headers = {"content-type": "application/json"}
      data = {"msgtype": "markdown", "markdown": {"content": content, "mentioned_list":["@all"]} }
      r = requests.post(headers=headers, url=webhook_url, data=json.dumps(data, ensure_ascii=False).encode('utf-8'), verify=False)
      return r.status_code, r.text
    
    #上传蒲公英平台
    def uploadPuGongYing(vSysInfo="Release"):
      def upload_complete_callback(isSuccess, result):
        if isSuccess:
          print('上传完成')
          print(result)
          _data = result['data']
          _url = _data['buildShortcutUrl'].strip() # 去除首尾空格
          _appVer = _data['buildVersion']
          _buildVer = _data['buildBuildVersion']
          # print('链接: https://www.pgyer.com/%s'%_url)
          # print('版本: %s (build %s)'%(_appVer, _buildVer))
          print("*********************************上传apk结束**********************************")
          _buildName = _data['buildName']
          _buildVersion = _data['buildVersion']
          _buildVersionNo = _data['buildVersionNo']
          _buildFileSize = _data['buildFileSize']
          _buildUpdated = _data['buildUpdated']
          _buildKey=_data['buildKey'].strip()
          _buildUrl = 'https://www.pgyer.com/{buildKey}'.format(buildKey=_buildKey)
          _updateDess = update_description.replace('\n', ";")
          _buildQRCodeURL = _data['buildQRCodeURL']
          _buildSystem = platform.system().lower()
          content = """
          应用更新提醒
          您的应用上传了新版本
          应用名称:{buildName}
          应用类型:{buildPlatform}
          版本信息:{buildVersion}(Build {buildVersionNo})
          应用大小:{buildFileSize}M
          安装密码:{pgyerPassword}
          编译系统:{buildSystem}
          编译用户: {userBuild}
          编译类型:{vSysInfo}
          编译时间: {buildTime}
          更新时间:{buildUpdated}
          更新内容:{update_description}
          点击查看应用:[{buildUrl}]({buildUrl})
          下载二维码:![下载二维码]({buildQRCodeURL})
          """.format(buildName=_buildName,
                     buildPlatform="Android",
                     buildVersion=_buildVersion,
                     buildVersionNo=_buildVer,
                     buildTime=buildTime,
                     buildSystem=_buildSystem,
                     buildFileSize=round(int(_buildFileSize) / 1024 / 1024, 2),
                     pgyerPassword=pgyer_password,
                     buildUpdated=_buildUpdated,
                     update_description=_updateDess,
                     buildUrl=_buildUrl,
                     userBuild=userBuild,
                     vSysInfo=vSysInfo,
                     buildQRCodeURL=_buildQRCodeURL)
          print(content)
          print("*********************************企业微信提醒开始**********************************")
          status_code, text = send_wechat_msg(content=content, webhook_url=webhook_url)
          print("微信提醒", status_code, text)
          print("*********************************企业微信提醒结束**********************************")
        else:
          print('上传失败')
    
    
      rootDir = os.path.abspath(".")
      print("编译的根目录:%s" %rootDir)
      #buildApkPath = "releaseApks/" + vSysInfo.lower()
      buildApkPath = "app/build/outputs/apk/" + vSysInfo.lower()
      apkDir = os.path.join(rootDir, buildApkPath)
      print("编译的apk路径:%s" % apkDir)
      fileList = os.listdir(apkDir)
      fileList = [os.path.join(apkDir, f) for f in fileList if f.endswith(".apk")]
      print(fileList)
      size = len(fileList)
      if size != 1:
        print("编译文件错误")
      else:
        f = fileList[0]
        print("要上传的文件 %s" %f)
        app_path = f
        fileName = os.path.basename(app_path)
        print("要上传的文件路径:%s" %fileName)
        files = fileName.replace(".apk", "").split('_')
        buildTime = files[3][0:4] + "-" + files[3][4:6] + "-" + files[3][6:] + " " + files[4][0:2] + ":" + files[4][2:4] + ":" + files[4][4:]
        print("编译时间:%s" %buildTime)
        userBuild = os.getlogin()
        print("编译用户名:%s" %userBuild)
        updateMsgs = readUpdateMsg()
        update_description = ""
        print("*********************************更新内容开始**********************************")
        for msg in updateMsgs:
          update_description += msg
          print(msg)
        print("*********************************更新内容结束**********************************")
        print("*********************************上传apk开始**********************************")
        PgyerUtil.upload_to_pgyer(
          path = app_path,
          api_key = pgyer_api_key,
          password=pgyer_password,
          update_description=update_description,
          callback=upload_complete_callback
        )
    
    #编译脚本执行入口
    def main():
      uploadPuGongYing()
    if __name__ == "__main__":
      main()
    
    

    注意 apk文件名称定义,目的脚本获取到编译时间及编译类型

    android.applicationVariants.all { variant ->
                variant.outputs.all {output->
    //                output.getPackageApplication().outputDirectory = new File(project.rootDir.absolutePath + "/releaseApks/${buildType.name}")
                    def buildTime = new Date().format("YYYYMMdd_HHmmss", TimeZone.getTimeZone("GMT+08:00"))
                    outputFileName = "App_${defaultConfig.versionName}_${buildType.name}_${buildTime}.apk"
                }
            }
    

    相关文章

      网友评论

          本文标题:python一键实现apk编译打包、上传蒲公英、企业微信机器人提

          本文链接:https://www.haomeiwen.com/subject/cjnnddtx.html