package Ġcom . bet om orrow . gradle . app center . infra Ċ Ċ import Ġokhttp 3 . MediaType . Companion . to MediaType OrNull Ċ import Ġokhttp 3 . RequestBody . Companion . as RequestBody Ċ import Ġretrofit 2 . Call Ċ import Ġretrofit 2 . Response Ċ import Ġjava . io . File Ċ Ċ private Ġconst Ġval ĠRELEASE _ URL _ TEMPLATE Ġ= ĊĠĠĠ Ġ" https :// app center . ms / orgs /% s / apps /% s / distribute / releases /% s " Ċ private Ġconst Ġval ĠCONTENT _ TYPE _ AP K Ġ= Ġ" application / vnd . android . package - archive " Ċ Ċ private Ġconst Ġval ĠRET RY _ DELAY Ġ= Ġ 1 _ 0 0 0 L Ċ private Ġconst Ġval ĠMAX _ RE TR IES Ġ= Ġ 6 0 Ċ Ċ class ĠApp Center Uploader ( ĊĠĠĠ Ġprivate Ġval Ġapi Factory : ĠApp Center API Factory , ĊĠĠĠ Ġprivate Ġval Ġowner Name : ĠString , ĊĠĠĠ Ġprivate Ġval ĠappName : ĠString Ċ ) Ġ{ ĊĊĠĠĠ Ġfun Ġupload A pk ( ĊĠĠĠĠĠĠĠ Ġfile : ĠFile , ĊĠĠĠĠĠĠĠ Ġchange Log : ĠString , ĊĠĠĠĠĠĠĠ Ġdestination Names : ĠList < String >, ĊĠĠĠĠĠĠĠ Ġnotify Test ers : ĠBoolean , ĊĠĠĠĠĠĠĠ Ġlogger : Ġ( String ) Ġ-> ĠUnit ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger (" Step Ġ 1 / 7 Ġ: ĠPrepare Ġrelease Ġupload ") ĊĠĠĠĠĠĠĠ Ġval ĠapiClient Ġ= Ġapi Factory . create Api () ĊĠĠĠĠĠĠĠ Ġval Ġprepared Upload Ġ= ĠapiClient . prepare Release Upload ( owner Name , ĠappName ). execute OrThrow () ĊĊĠĠĠĠĠĠĠ Ġlogger (" Step Ġ 2 / 7 Ġ: ĠSet Ġmetadata ") ĊĠĠĠĠĠĠĠ Ġval Ġupload Api Ġ= Ġapi Factory . create Upload Api ( prepared Upload . upload Domain ) ĊĠĠĠĠĠĠĠ Ġval Ġmetadata Ġ= Ġupload Api . set Metadata ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprepared Upload . package Asset Id , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfile . name , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfile . length (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprepared Upload . token , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCONTENT _ TYPE _ AP K ĊĠĠĠĠĠĠĠ Ġ). execute OrThrow () ĊĊĠĠĠĠĠĠĠ Ġlogger (" Step Ġ 3 / 7 Ġ: ĠUpload Ġrelease Ġchunks ") ĊĠĠĠĠĠĠĠ Ġmetadata . chunk List . forEach Indexed Ġ{ Ġi , Ġchunk Id Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrange Ġ= Ġ( i Ġ* Ġmetadata . chunk Size ) .. (( i Ġ+ Ġ 1 ) Ġ* Ġmetadata . chunk Size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchunk Ġ= ĠChunk ed RequestBody ( file , Ġrange , Ġ" application / octet - stream ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger (" Step Ġ 3 / 7 Ġ: ĠUpload Ġrelease Ġchunk Ġ${ i Ġ+ Ġ 1 } Ġof Ġ${ metadata . chunk List . size }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupload Api . upload Chunk ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprepared Upload . package Asset Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchunk Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprepared Upload . token , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchunk ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ). execute OrThrow () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġlogger (" Step Ġ 4 / 7 Ġ: ĠFinish Ġupload ") ĊĠĠĠĠĠĠĠ Ġupload Api . finish Upload ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmetadata . id , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprepared Upload . token ĊĠĠĠĠĠĠĠ Ġ). execute OrThrow () ĊĊĠĠĠĠĠĠĠ Ġlogger (" Step Ġ 5 / 7 Ġ: ĠCommit Ġrelease ") ĊĠĠĠĠĠĠĠ Ġval Ġcommit Request Ġ= ĠCommit Release Upload Request (" upload Finished ") ĊĠĠĠĠĠĠĠ ĠapiClient . commit Release Upload ( owner Name , ĠappName , Ġprepared Upload . id , Ġcommit Request ). execute OrThrow () ĊĊĠĠĠĠĠĠĠ Ġvar Ġrequest Count Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġupload Result : ĠGet Upload Response ? ĊĠĠĠĠĠĠĠ Ġdo Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger (" Step Ġ 6 / 7 Ġ: ĠWaiting Ġfor Ġrelease Ġto Ġbe Ġready Ġto Ġpublish Ġ(${ request Count } s )") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupload Result Ġ= ĠapiClient . get Upload ( owner Name , ĠappName , Ġprepared Upload . id ). execute OrThrow () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠThread . sleep ( RETRY _ DELAY ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(++ request Count Ġ>= ĠMAX _ RE TR IES ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠApp Center Uploader Exception (" Fetching Ġrelease Ġid Ġfailed : ĠT ried Ġ$ request Count Ġtimes .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġwhile Ġ( upload Result ?. upload Status Ġ!= Ġ" ready ToBe Published ") ĊĊĠĠĠĠĠĠĠ Ġlogger (" Step Ġ 7 / 7 Ġ: ĠDist ribut e Ġrelease ") ĊĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠDist ribut e Request ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdest inations Ġ= Ġdestination Names . map Ġ{ ĠDist ribut e Request . Destination ( it ) Ġ}. toList (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrelease Notes Ġ= Ġchange Log , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnotify Test ers Ġ= Ġnotify Test ers ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġval Ġuploaded Release Id Ġ= Ġupload Result . release Id ĊĠĠĠĠĠĠĠ ĠapiClient . distribute ( owner Name , ĠappName , Ġuploaded Release Id !! , Ġrequest ). execute OrThrow () ĊĠĠĠĠĠĠĠ Ġprintln (" App Center Ġrelease Ġurl Ġis Ġ${ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRELEASE _ URL _ TEMPLATE . format ( owner Name , ĠappName , Ġuploaded Release Id ) ĊĠĠĠĠĠĠĠ Ġ} ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġupload Mapping ( mapping File : ĠFile , Ġversion Name : ĠString , Ġversion Code : ĠInt , Ġlogger : Ġ( String ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġupload Symbols ( mapping File , Ġ" Android Pro guard ", Ġversion Name , Ġversion Code . toString (), Ġlogger ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġupload Symbols ( symbols File : ĠFile , Ġversion Name : ĠString , Ġversion Code : ĠInt , Ġlogger : Ġ( String ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġupload Symbols ( symbols File , Ġ" Break pad ", Ġversion Name , Ġversion Code . toString (), Ġlogger ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġupload Symbols ( ĊĠĠĠĠĠĠĠ Ġmapping File : ĠFile , ĊĠĠĠĠĠĠĠ Ġsymbol Type : ĠString , ĊĠĠĠĠĠĠĠ Ġversion Name : ĠString , ĊĠĠĠĠĠĠĠ Ġversion Code : ĠString , ĊĠĠĠĠĠĠĠ Ġlogger : Ġ( String ) Ġ-> ĠUnit ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger (" Step Ġ 1 / 3 Ġ: ĠPrepare Ġsymbol Ġupload ") ĊĠĠĠĠĠĠĠ Ġval ĠapiClient Ġ= Ġapi Factory . create Api () ĊĠĠĠĠĠĠĠ Ġval Ġprepare Request Ġ= ĠPrepare Symbol Upload Request ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsymbol Type Ġ= Ġsymbol Type , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠfileName Ġ= Ġmapping File . name , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġversion Ġ= Ġversion Name , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuild Ġ= Ġversion Code ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġprepared Upload Ġ= ĠapiClient . prepare Symbol Upload ( owner Name , ĠappName , Ġprepare Request ). execute OrThrow () ĊĊĠĠĠĠĠĠĠ Ġlogger (" Step Ġ 2 / 3 Ġ: ĠUpload Ġsymbol ") ĊĠĠĠĠĠĠĠ Ġval Ġapi Ġ= Ġapi Factory . create Symbols Api () ĊĠĠĠĠĠĠĠ Ġapi . upload Symbols ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprepared Upload . upload Url , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmapping File . as RequestBody (" text / plain ; Ġcharset = UTF - 8 ". to MediaType OrNull ()) ĊĠĠĠĠĠĠĠ Ġ). execute OrThrow () ĊĊĠĠĠĠĠĠĠ Ġlogger (" Step Ġ 3 / 3 Ġ: ĠCommit Ġsymbol ") ĊĠĠĠĠĠĠĠ Ġval Ġcommit Request Ġ= ĠCommit Symbol Upload Request (" committed ") ĊĠĠĠĠĠĠĠ ĠapiClient . commit Symbol Upload ( owner Name , ĠappName , Ġprepared Upload . symbol Upload Id , Ġcommit Request ). execute OrThrow () ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġ< T > ĠCall < T >. execute OrThrow () Ġ= Ġexecute (). body OrThrow () Ċ Ċ private Ġfun ĠCall < Void >. execute OrThrow () Ġ= Ġexecute (). success OrThrow () Ċ Ċ private Ġfun Ġ< T > ĠResponse < T >. body OrThrow () Ġ= Ġsuccess OrThrow () !! Ċ Ċ private Ġfun Ġ< T > ĠResponse < T >. success OrThrow () Ġ= ĊĠĠĠ Ġif Ġ( is Successful ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbody () ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠApp Center Uploader Exception (" Can 't Ġprepare Ġrelease Ġupload , Ġcode =${ code ()}, Ġreason =${ error Body ()?. string () }") ĊĠĠĠ Ġ} Ċ Ċ class ĠApp Center Uploader Exception ( message : ĠString ) Ġ: ĠException ( message ) Ċ