1. 程式人生 > >安卓分包優化版本Python27(純Python+mysql)

安卓分包優化版本Python27(純Python+mysql)

#!/usr/bin/python #coding:utf-8 import threading,time import requests import MySQLdb as db import os import shutil import zipfile import commands from oss2 import SizedFileAdapter,determine_part_size from oss2.models import PartInfo import oss2

class appsubpack():     #定義渠道數量     Channel = []     #定義遊戲詳情資訊     gameinfo = {}     #定義渠道詳情     ch_info ={}     #定義目錄     path=""

    def __init__(self):         #連結資料庫         conn=db.connect(host="127.0.0.1",user="root",passwd="xxx",db="xxx",charset="utf8")         cursor=conn.cursor()

        #查詢資料庫是否連線成功         try:             conn.ping(True)         except Exception,e:             conn=db.connect(host="127.0.0.1",user="root",passwd="xxx",db="xxx",charset="utf8")             cursor=conn.cursor()

        #查詢需要分包的資料         try:             cursor.execute("select gid,chid from app_dsrw limit 100")             #獲取返回資料             lists=cursor.fetchall()             #lists=(("GID1534313785917","CH1153827307025"),("GID1528770399326","CH1153827307025"),("GID1528343925362","CH1153827307025"))             #print lists                         for i in lists:                self.Channel.append(list(i))

        except Exception,e:             print e     #定義mysql資料庫連結     def _mysql_connect(self,dbname):         if dbname == None:             dbname="AYbase_db"         conn=db.connect(host="127.0.0.1",user="root",passwd="xxx",db=dbname,charset="utf8",cursorclass=db.cursors.DictCursor)         cursor=conn.cursor()         try:             conn.ping(True)         except Exception,e:            conn=db.connect(host="127.0.0.1",user="root",passwd="xxx",db=dbname,charset="utf8",cursorclass=db.cursors.DictCursor)            cursor=conn.cursor()

        return cursor     #定義資料庫連結沒有游標的     def _mysql_connect_db(self,dbname):         if dbname == None:             dbname="AYbase_db"         conn=db.connect(host="127.0.0.1",user="root",passwd="xxx",db=dbname,charset="utf8",cursorclass=db.cursors.DictCursor)         return conn

    def _apks(self,gid,chid):         #根據gid查詢app_aprvider資料表         mydb=self._mysql_connect("AYkcp_db")         mydb.execute("select * from app_provider where gid='%s' limit 1" % gid)         #查詢遊戲資訊         gameinfo=mydb.fetchone()

        if gameinfo is None:             return         #遞迴建立目錄         #定義要建立的目錄         #/home/apps/ljzz/         path="/home/apps/%s" % gameinfo['app_name'];         self._mkdir_apk(path)

        #判斷是一級渠道還是二級渠道         is_ch=chid[0:3]         if is_ch == "CH1":             ch_db=self._mysql_connect("AYqudao_db")             ch_db.execute("select * from core_channel_one_info where ch_id='%s' limit 1" % chid)             ch_info=ch_db.fetchone()         if is_ch == "CH2":             ch_db=self._mysql_connect("AYqudao_db")             ch_db.execute("select * from core_channel_two_info where ch_id='%s' limit 1" % chid)             ch_info=ch_db.fetchone()         if is_ch == None:             return

        #根據渠道ID和遊戲ID查詢生成包資訊         appSubpack_db=self._mysql_connect("AYqudao_db")         appSubpack_db.execute("select * from app_subpackage  where gid='%s' AND chid='%s' limit 1" % (gid,chid))         appSubpack_data=appSubpack_db.fetchone()         self._createSubpackage(chid,path,gameinfo,ch_info,appSubpack_data)

    def _createSubpackage(self,chid,path,gameinfo,ch_info,appSubpack_data):

        #新包存放的路徑         newFile = path+"/"+chid+"_"+gameinfo['app_name']+".apk"

        #阿里雲存放路徑         newFile2 = path+"/"+chid+"_"+gameinfo['app_name']+"_"+gameinfo['mark_banben']+".apk"

        #查詢是否正在簽名         sign_apks=newFile+".sig"         if os.path.exists(sign_apks) ==True:                 return         #查詢是否已經分完包         if os.path.exists(newFile2) ==True:                 return         #定義母包路徑         main_apk=gameinfo['main_package']         main_apks="/ayplatform/website/symi_cn/"+main_apk[2:]

        #複製包         shutil.copy(main_apks,newFile)         if os.path.exists(newFile)==False:                 return         #定義安卓渠道標識         ChannelName="META-INF/AY_"+chid         #建立空白檔案            #channel_path=path+ChannelName         #print channel_path

        #加入渠道標識         filesa=path+"/"+chid+".txt"         f=open(filesa,"w")         f.close()         zips=zipfile.ZipFile(newFile,"a")         zips.write(filesa,ChannelName)         zips.close()         os.remove(filesa)

        #對打好的安裝包進行簽名         shellbat="/usr/java/jdk1.8.0_65/bin/signapk.sh %s %s" % (newFile,newFile2);         #獲取返回值         (status,output) = commands.getstatusoutput(shellbat)

        if output  == "ok":                 os.remove(newFile)                 oss_result=self._aliuploadoss(newFile2,chid,gameinfo,appSubpack_data)

                if oss_result != False:                     ay_db=self._mysql_connect_db("AYqudao_db")                     ay_db_cursor = ay_db.cursor()                     sql="UPDATE app_subpackage set cos_url='%s',up_flag=%d,cos_flag='%s' WHERE gid='%s' AND chid='%s'" % (oss_result,3,"no",gameinfo['gid'],chid)                     apps_result=ay_db_cursor.execute(sql)                     #print apps_result                     #ay_db.close()                     if apps_result>0:                         dsrw_db = self._mysql_connect_db("AYbase_db")                         dsrw_db_cursor = dsrw_db.cursor()                         sql_dsrw = "DELETE FROM app_dsrw where gid='%s' AND chid='%s'" % (gameinfo['gid'],chid)                         dsrw_db_cursor.execute(sql_dsrw)                         ay_db.commit()                         dsrw_db.commit()                         os.remove(newFile2)                         if os.path.exists(sign_apks):                             os.remove(sign_apks)                         #os.remove(sign_apks)                         dsrw_db.close()                         return True                     else:                         ay_db.rollback()                     ay_db.close()         else:                 return False

    def _aliuploadoss(self,newfile,chid,gameinfo,appSubpack_data):         #上傳之前,檢查下是否有已經上傳過的

        #阿里雲主賬號AccessKey         auth = oss2.Auth("xxx","xxx")

        #Endpoint         bucket = oss2.Bucket(auth,"xxx","xxx",enable_crc=False)

        #oss上傳存放的地址         ossFile="Public/subpackage/"+gameinfo['app_name']+"/"+chid+"_"+gameinfo['app_name']+"_"+gameinfo['mark_banben']+".apk"

        #print ossFile  

        #本地存放的檔案地址         pathfile=newfile

        #檢視分片大小         total_size = os.path.getsize(pathfile)         part_size = determine_part_size(total_size,preferred_size=5 * 1024 * 1024)

        #初始化分片         upload_id = bucket.init_multipart_upload(ossFile).upload_id         parts = []

        #print bucket.request_id         #上傳分片         with open(pathfile,"rb") as fileobj:                 part_number = 1                 offset = 0                 while offset < total_size:                         num_to_upload = min(part_size,total_size - offset)                         result = bucket.upload_part(ossFile,upload_id,part_number,SizedFileAdapter(fileobj,num_to_upload))                         parts.append(PartInfo(part_number,result.etag))                         offset+=num_to_upload                         part_number+=1         #完成分片上傳         bucket.complete_multipart_upload(ossFile,upload_id,parts)

        #檢測檔案是否存在         exist = bucket.object_exists(ossFile)         if exist:

            #print appSubpack_data['cos_url'],appSubpack_data['up_flag']             #刪除掉OSS的檔案             #print appSubpack_data['up_flag'],appSubpack_data['cos_url']             #print appSubpack_data              #if appSubpack_data.has_key("cos_url"):             #    print "11111111"                     #刪除之前更新過的檔案             #   bucket.delete_object(appSubpack_data['cos_url'])             return ossFile         else:             return False

    #建立目錄         def _mkdir_apk(self,path):         #檢測目錄是否存在         if not  os.path.exists(path):             #如果不存在就建立目錄             os.makedirs(path)             return True         else:             return False

    def _subs(self):         #判斷是否有要生成的包的標識         if len(self.Channel)<=0:             return

        if len(self.Channel)>4:             nums=4         else:             nums=len(self.Channel)

        #開啟執行緒

        for i in range(nums):

            thre = threading.Thread(target=self._apks,args=(self.Channel[i][0],self.Channel[i][1]),name='xc%d' % i)             thre.start()

if __name__=="__main__":          app = ""     app = appsubpack()     app._subs()