/* Ċ * ĠĠ ĠCopyright Ġ 2 0 1 9 ĠMar co ĠG omi ero Ċ * Ċ * ĠĠ ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ * ĠĠ Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ * ĠĠ ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ * Ċ * ĠĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ * Ċ * ĠĠ ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ * ĠĠ Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ * ĠĠ ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ * ĠĠ ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ * ĠĠ Ġlimitations Ġunder Ġthe ĠLicense . Ċ * Ċ */ Ċ Ċ package Ġcom . prof . youtube parser Ċ Ċ import Ġcom . prof . youtube parser . engine . Json Fetcher Ċ import Ġcom . prof . youtube parser . engine . Json Video Parser Ċ import Ġcom . prof . youtube parser . engine coroutines . Coroutine Engine Ċ import Ġcom . prof . youtube parser . models . videos . Video Ċ import Ġkotlinx . coroutines .* Ċ import Ġjava . util . concurrent . ExecutorService Ċ import Ġjava . util . concurrent . Executors Ċ import Ġkotlin . coroutines . Coroutine Context Ċ Ċ class ĠParser Ġ{ ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar ĠonComplete : ĠOn Task Completed ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġservice : ĠExecutor Service ĊĊĠĠĠ Ġprivate Ġval Ġparser Job Ġ= ĠJob () ĊĠĠĠ Ġprivate Ġval Ġcoroutine Context : ĠCor outine Context ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġparser Job Ġ+ ĠDispatch ers . Default ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġmethod Ġgenerates Ġthe Ġurl Ġthat Ġretrieves ĠY outube Ġvideo Ġdata ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġchannel ID ĠThe ĠID Ġof Ġthe Ġdesired Ġchannel . ĠEx : Ġhttps :// www . youtube . com / channel / U CV HF bq X qo Y v E WM 1 D dx l 0 Q Dg ĊĠĠĠĠ Ġ* Ġchannel Ġid Ġ= ĠU CV HF bq X qo Y v E WM 1 D dx l 0 Q Dg ĊĠĠĠĠ Ġ* Ġ@ param Ġmax Result ĠThe Ġnumber Ġof Ġvideo Ġto Ġget ĊĠĠĠĠ Ġ* Ġ@ param Ġkey ĠĠĠĠĠĠ ĠYour ĠBrowser ĠAPI Ġkey . ĠObtain Ġone Ġby Ġvisit ing Ġhttps :// console . developers . google . com ĊĠĠĠĠ Ġ* Ġ@ return ĠThe Ġurl Ġrequired Ġto Ġget Ġdata ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Deprecated ( ĊĠĠĠĠĠĠĠ Ġmessage Ġ= Ġ" This Ġmethod Ġis Ġdeprecated . ĠPlease Ġuse Ġthe Ġnew Ġversion Ġthat Ġallows Ġto Ġchoose Ġthe Ġtype Ġof Ġorder Ġof Ġthe Ġvideos : Ġ{@ link Ġ# generate Request ( String , Ġint , Ġint , ĠString )} ", ĊĠĠĠĠĠĠĠ Ġreplace With Ġ= ĠReplace With ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" generate Request ( channel ID , Ġmax Result , ĠORDER _ DATE Ġ, key )", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" com . prof . youtube parser . Parser . Companion . ORDER _ DATE " ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ) ĊĠĠĠ Ġfun Ġgenerate Request ( channel ID : ĠString , Ġmax Result : ĠInt , Ġkey : ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ"$ BASE _ ADDRESS $ channel ID & max Results =$ max Result & order = date & key =$ key " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġmethod Ġgenerates Ġthe Ġurl Ġto Ġretrieve ĠY outube ĠVideo Ġdata ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġchannel ID ĠThe ĠID Ġof Ġthe Ġdesired Ġchannel . ĠEx : Ġhttps :// www . youtube . com / channel / U CV HF bq X qo Y v E WM 1 D dx l 0 Q Dg ĊĠĠĠĠ Ġ* Ġchannel Ġid Ġ= ĠU CV HF bq X qo Y v E WM 1 D dx l 0 Q Dg ĊĠĠĠĠ Ġ* Ġ@ param Ġmax Result ĠThe Ġnumber Ġof Ġvideo Ġto Ġget . ĠThe Ġmaximum Ġvalue Ġis Ġ 5 0 ĊĠĠĠĠ Ġ* Ġ@ param Ġorder Type ĠThe Ġtype Ġof Ġordering . ĠYou Ġcan Ġchoose Ġan Ġorder Ġby Ġdate : Ġ[. ORDER _ DATE ] Ġand Ġby Ġview Ġcount Ġ[. ORDER _ VIEW _ COUNT ]. ĊĠĠĠĠ Ġ* Ġ@ param Ġkey ĠĠĠĠĠĠ ĠYour ĠBrowser ĠAPI Ġkey . ĠObtain Ġone Ġby Ġvisit ing Ġhttps :// console . developers . google . com ĊĠĠĠĠ Ġ* Ġ@ return ĠThe Ġurl Ġrequired Ġto Ġget Ġdata ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġgenerate Request ( channel ID : ĠString , Ġmax Result : ĠInt , Ġorder Type : ĠInt , Ġkey : ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġorder Ġ= Ġwhen Ġ( order Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠORDER _ DATE Ġ-> Ġ" date " ĊĠĠĠĠĠĠĠĠĠĠĠ ĠORDER _ VIEW _ COUNT Ġ-> Ġ" view count " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ"" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġ"$ BASE _ ADDRESS $ channel ID & max Results =$ max Result & order =$ order & key =$ key " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThis Ġmethod Ġgenerates Ġthe Ġurl Ġto Ġretrieve Ġmore Ġvideo Ġdata . ĠRemember Ġthat Ġfirst Ġyou Ġhave Ġto Ġcall ĊĠĠĠĠ Ġ* Ġ[. generate Request ] Ġto Ġget Ġthe Ġnext Ġpage Ġtoken ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġchannel ID ĠThe ĠID Ġof Ġthe Ġdesired Ġchannel . ĠEx : Ġhttps :// www . youtube . com / channel / U CV HF bq X qo Y v E WM 1 D dx l 0 Q Dg ĊĠĠĠĠ Ġ* Ġchannel Ġid Ġ= ĠU CV HF bq X qo Y v E WM 1 D dx l 0 Q Dg ĊĠĠĠĠ Ġ* Ġ@ param Ġmax Result ĠThe Ġnumber Ġof Ġvideo Ġto Ġget . ĠThe Ġmaximum Ġvalue Ġis Ġ 5 0 ĊĠĠĠĠ Ġ* Ġ@ param Ġorder Type ĠThe Ġtype Ġof Ġordering . ĠYou Ġcan Ġchoose Ġan Ġorder Ġby Ġdate : Ġ[. ORDER _ DATE ] Ġand Ġby Ġview Ġcount Ġ[. ORDER _ VIEW _ COUNT ]. ĊĠĠĠĠ Ġ* Ġ@ param Ġkey ĠĠĠĠĠĠ ĠYour ĠBrowser ĠAPI Ġkey . ĠObtain Ġone Ġby Ġvisit ing Ġhttps :// console . developers . google . com ĊĠĠĠĠ Ġ* Ġ@ param Ġnext Token ĠThe Ġtoken Ġnecessary Ġto Ġload Ġmore Ġdata ĊĠĠĠĠ Ġ* Ġ@ return ĠThe Ġurl Ġrequired Ġto Ġget Ġmore Ġdata ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġgenerate More Data Request ( ĊĠĠĠĠĠĠĠ Ġchannel ID : ĠString , ĊĠĠĠĠĠĠĠ Ġmax Result : ĠInt , ĊĠĠĠĠĠĠĠ Ġorder Type : ĠInt , ĊĠĠĠĠĠĠĠ Ġkey : ĠString , ĊĠĠĠĠĠĠĠ Ġnext Token : ĠString ĊĠĠĠ Ġ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġurl String Ġ= Ġ" https :// www . googleapis . com / youtube / v 3 / search ? page Token =" ĊĠĠĠĠĠĠĠ Ġval Ġorder Ġ= Ġwhen Ġ( order Type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠORDER _ DATE Ġ-> Ġ" date " ĊĠĠĠĠĠĠĠĠĠĠĠ ĠORDER _ VIEW _ COUNT Ġ-> Ġ" view count " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ"" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġ"$ url String $ nextToken & part = snippet & channelId =$ channel ID & max Results =$ max Result & order =$ order & key =$ key " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Finish ( onComplete : ĠOn Task Completed ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . onComplete Ġ= ĠonComplete ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġexecute ( url : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ ĠExec utors . new Single Thread Executor (). submit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġservice Ġ= ĠExec utors . new Fixed ThreadPool ( 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġf 1 Ġ= Ġservice . submit ( Json Fetcher ( url )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvideo Json Ġ= Ġf 1 . get () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġf 2 Ġ= Ġservice . submit ( Json Video Parser ( video Json )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠonComplete . on Task Completed ( f 2 . get (). videos , Ġf 2 . get (). nextToken ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠonComplete . onError ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġservice . shutdown () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsuspend Ġfun Ġget Videos ( url : ĠString ) Ġ= Ġwith Context ( coroutine Context ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġjson Ġ= ĠCor outine Engine . fetch Json ( url ) ĊĠĠĠĠĠĠĠ Ġreturn @ with Context ĠCor outine Engine . parse Video ( json ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ ĠCancel Ġthe Ġexecution Ġof Ġthe Ġfetching Ġand Ġthe Ġparsing . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġcancel () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(:: service . isInitialized ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġclient Ġis Ġusing ĠJava ! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! service . is Shutdown ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġservice . shutdown Now () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠonComplete . onError ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġclient Ġis Ġusing ĠKotlin Ġand Ġcor outines ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( coroutine Context . isActive ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcoroutine Context . cancel () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠBASE _ ADDRESS Ġ= Ġ" https :// www . googleapis . com / youtube / v 3 / search ? part = snippet & channelId =" ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠORDER _ DATE Ġ= Ġ 1 ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠORDER _ VIEW _ COUNT Ġ= Ġ 2 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinterface ĠOn Task Completed Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġon Task Completed ( list : ĠList < Video >, Ġnext PageToken : ĠString ?) ĊĠĠĠĠĠĠĠ Ġfun ĠonError ( e : ĠException ) ĊĠĠĠ Ġ} Ċ }