/* Ċ Ġ* ĠCopyright Ġ 2 0 2 1 ĠAle ks and r ĠK amy sh nik ov Ċ Ġ* Ċ Ġ* Ġ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 Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttps :// 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 Ġname . er ax ill an . an il ist app . api Ċ Ċ import Ġandroid . os . Looper Ċ import Ġandroidx . core . text . is Digits Only Ċ import Ġcom . ap ol log raph ql . apollo . A pol lo Client Ċ import Ġcom . ap ol log raph ql . apollo . api .* Ċ import Ġcom . ap ol log raph ql . apollo . coroutines . await Ċ import Ġcom . ap ol log raph ql . apollo . exception . A pol lo Exception Ċ import Ġcom . ap ol log raph ql . apollo . http . Ok Http ExecutionContext Ċ import Ġkotlinx . coroutines . delay Ċ import Ġname . er ax ill an . an il ist app .* Ċ import Ġname . er ax ill an . an il ist app . model . Remote Media Ċ import Ġname . er ax ill an . an il ist app . model . Media Filter Ċ import Ġname . er ax ill an . an il ist app . utilities . NETWORK _ REQUEST _ RETRY _ COUNT Ċ import Ġname . er ax ill an . an il ist app . utilities . NETWORK _ REQUEST _ RETRY _ INTERVAL _ MS Ċ import Ġname . er ax ill an . an il ist app . model . Media Sort Ġas ĠMedia Sort Ċ import Ġname . er ax ill an . an il ist app . type . Media Relation Ġas ĠAn il ist Media Relation Ċ import Ġname . er ax ill an . an il ist app . type . Media Sort Ġas ĠAn il ist Media Sort Ċ import Ġname . er ax ill an . an il ist app . type . Media Status Ġas ĠAn il ist Media Status Ċ import Ġname . er ax ill an . an il ist app . type . MediaType Ġas ĠAn il ist MediaType Ċ import Ġokhttp 3 . Ok HttpClient Ċ import Ġokhttp 3 . logging . Http Logging Interceptor Ċ import Ġtim ber . log . Tim ber Ċ import Ġjava . lang . Number FormatException ĊĊ Ċ /** Ċ Ġ* ĠUsed Ġto Ġconnect Ġto Ġthe ĠAn il ist ĠAPI Ġto Ġfetch Ġmedia Ġschedule Ġand Ġdetails Ċ Ġ*/ Ċ class ĠAn il ist Api ( private Ġval Ġclient : ĠApollo Client ) Ġ{ ĊĊĠĠĠ Ġ/* suspend Ġfun Ġget Genre List (): ĠResponse < Media Gen res Query . Data > Ġ= Ġpost Request Internal ( Media Gen res Query (), Ġ 0 ) */ ĊĊĠĠĠ Ġ/* suspend Ġfun Ġget Tag List (): ĠResponse < Media Tags Query . Data > Ġ= Ġpost Request Internal ( Media Tags Query (), Ġ 0 ) */ ĊĊĠĠĠ Ġ// ĠTODO : ĠAn il ist ĠAPI Ġdoes Ġnot Ġhave Ġsuch Ġkind Ġof Ġquery Ġnow , Ġbut Ġit Ġcan Ġbe Ġadded Ġin Ġfuture ĊĠĠĠ Ġ// suspend Ġfun Ġget Studio List (): ĠResponse < Media St ud ios Query . Data >? Ġ= Ġpost Request Internal ( Media St ud ios Query (), Ġ 0 ) ĊĠĠĠ Ġ/* suspend Ġfun Ġfind Studio ( name : ĠString ): ĠResponse < Media Studio Query . Data > Ġ= Ġpost Request Internal ( Media Studio Query ( name ), Ġ 0 ) */ ĊĊĠĠĠ Ġsuspend Ġfun Ġget Media List ( page : ĠInt , Ġper Page : ĠInt , Ġfilter : ĠMedia Filter , Ġsort : ĠMedia Sort ) ĊĠĠĠĠĠĠĠ Ġ: ĠResponse < Media List Query . Data > Ġ{ ĊĊĠĠĠĠĠĠĠ Ġcheck ( page Ġ>= Ġ 1 ) Ġ{ ĠTim ber . e (" page Ġ< Ġ 0 ") Ġ} ĊĠĠĠĠĠĠĠ Ġcheck ( per Page Ġ>= Ġ 1 ) Ġ{ ĠTim ber . e (" per Page Ġ< Ġ 0 ") Ġ} ĊĠĠĠĠĠĠĠ Ġcheck ( sort Ġ!= ĠMedia Sort . UNKNOWN ) Ġ{ ĠTim ber . e (" sortBy Ġ== ĠMedia Sort . UNKNOWN ") Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġformats Ġ= Ġfilter . formats ?. map NotNull Ġ{ Ġmedia Format Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconvert Media Format ( media Format ) ĊĠĠĠĠĠĠĠ Ġ}. to Input () ĊĊĠĠĠĠĠĠĠ Ġval Ġsort An il ist Ġ= Ġconvert Media Sort Type ( sort ) Ġ?: ĠAn il ist Media Sort . POP ULAR ITY _ DESC ĊĠĠĠĠĠĠĠ Ġcheck ( sort An il ist Ġ!= ĠAn il ist Media Sort . UNKNOWN __) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . e (" sortBy An il ist Ġ== ĠAn il ist Media Sort . UNKNOWN __ ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġmedia List Query Ġ= ĠMedia List Query ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpage Ġ= Ġpage , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġper Page Ġ= Ġper Page , ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġgen res Ġ= Ġfilter . genres . to Input (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtags Ġ= Ġfilter . tags . to Input (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġformats Ġ= Ġformats , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġseason Year Ġ= Ġfilter . year . to Input (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlicensed By Ġ= Ġfilter . services . to Input (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsources Ġ= Ġfilter . sources ?. map NotNull Ġ{ Ġsource Ġ-> Ġconvert Media Source ( source ) Ġ}. to Input (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġseason Ġ= Ġconvert Media Season ( filter . season ). to Input (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstatus Ġ= Ġconvert Media Status ( filter . status ). to Input (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcountry Ġ= Ġconvert Media Country ( filter . country ). to Input (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Licensed Ġ= Ġfilter . is Licensed . to Input (), ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġsort Ġ= ĠlistOf ( sort An il ist ). to Input () ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġpost Request Internal ( media List Query , Ġ 0 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġ< Q Ġ: ĠQuery < R , ĠR , ĠOperation . Variables >, ĠR Ġ: ĠOperation . Data > ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpost Request Internal ( query : ĠQ , Ġretry Number : ĠInt ): ĠResponse < R > Ġ{ ĊĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġclient . query ( query ). await () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( response . has Errors ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmessages Ġ= Ġresponse . errors ?. join ToString (", Ġ") Ġ{ Ġerror Ġ-> Ġerror . message Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠApollo Exception (" GraphQL Ġerror : Ġ$ messages ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrate Limit Ġ= Ġget Response RateLimit ( response ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Network Ġquery Ġrate Ġlimit Ġstatus : Ġ${ rate Limit . remaining } Ġfrom Ġ${ rate Limit . total }" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġresponse ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠApollo Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠHandle Ġprotocol Ġerrors ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . e (" A pol lo Ġexception : Ġ% s ", Ġe . message ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRetry Ġon Ġrate Ġlimit Ġexceed Ġerror Ġ( HTTP Ġcode Ġ 4 2 9 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġan Ġun reli able Ġway Ġto Ġget ĠHTTP Ġresult Ġcode , Ġfind Ġanother Ġone ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( e . message ?. trim () Ġ== Ġ" HTTP Ġ 4 2 9 ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . e (" Rate Ġlimit Ġexceeded !") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( retry Number Ġ> ĠNET WORK _ REQUEST _ RETRY _ COUNT ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . e ("$ NETWORK _ REQUEST _ RETRY _ COUNT Ġattempts Ġto Ġreset Ġrate Ġlimit Ġfailed ! ĠAbort ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġe ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" Sleep Ġ${ NETWORK _ REQUEST _ RETRY _ INTERVAL _ MS Ġ/ Ġ 1 _ 0 0 0 } Ġseconds Ġand Ġtry Ġagain ...") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( NETWORK _ REQUEST _ RETRY _ INTERVAL _ MS ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġpost Request Internal ( query , Ġretry Number Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġe ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/* suspend Ġfun Ġget Media Detail ( id : ĠInt , Ġpage : ĠInt , Ġper Page : ĠInt ): ĠResponse < Media Detail Query . Data > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmedia Detail Query Ġ= ĠMedia Detail Query ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpage Ġ= Ġpage , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġper Page Ġ= Ġper Page , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġid Ġ= ĠInput . from Nullable ( id ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// search Ġ= ĠInput . from Nullable (" media _ name ") ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġpost Request Internal ( media Detail Query , Ġ 0 ) ĊĠĠĠ Ġ}*/ ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġget Media Relations ( ids : ĠList < Long >, Ġpage : ĠInt , Ġper Page : ĠInt ) ĊĠĠĠĠĠĠĠ Ġ: ĠResponse < Media Relations Query . Data > Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġmedia Relations Query Ġ= ĠMedia Relations Query ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpage Ġ= Ġpage , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġper Page Ġ= Ġper Page , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġid _ in Ġ= Ġids . map Ġ{ Ġit . toInt () Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġpost Request Internal ( media Relations Query , Ġ 0 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ////////////////////////////////////////////////////////////////// //////////////////////// /////// ĊĊĠĠĠ Ġprivate Ġfun Ġget Pre quel ( medium : ĠMedia Relations Query . Medium ): ĠPair < Boolean , ĠInt > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpre quel Edge Ġ= Ġmedium . relations ?. edges ?. filter NotNull ()?. find Ġ{ Ġedge Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMedia Ġcan Ġhave Ġonly Ġone Ġpre quel Ġand Ġhave Ġnot Ġat Ġall ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( edge . relation Type Ġ== ĠAn il ist Media Relation . PRE QUE L Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġedge . node ?. type Ġ== ĠAn il ist MediaType . AN IME Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġedge . node . status Ġ== ĠAn il ist Media Status . FINISHED ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtitle Ġ= Ġedge . node . title ?. rom aji ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" Pre quel Ġmedia Ġfound : Ġ$ title ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġpre quel Id Ġ= Ġpre quel Edge ?. node ?. id Ġ?: Ġ- 1 ĊĠĠĠĠĠĠĠ Ġreturn ĠPair ( pre quel Edge Ġ!= Ġnull , Ġpre quel Id ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġtail rec Ġsuspend Ġfun Ġsearch Pre que ls ( relations : ĠMap < Long , ĠMutable List < Long >> ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠFree ĠAn i List ĠAPI Ġrate Ġlimit Ġrestricted Ġwith Ġjust Ġ 9 0 Ġreq / sec ! ĊĠĠĠĠĠĠĠ Ġ// ĠSo Ġwe Ġneed Ġto Ġmake Ġas Ġfew Ġrequests Ġas Ġpossible . ĊĠĠĠĠĠĠĠ Ġ// ĠTo Ġachieve Ġthis , Ġquery Ġall Ġmedia Ġrelations Ġin Ġone Ġrequest Ġusing Ġ` id _ in ` Ġargument ĊĊĠĠĠĠĠĠĠ Ġif Ġ( relations . isEmpty ()) Ġreturn Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġ// ĠRe cur sion Ġstop Ġcondition : Ġall Ġmedia Ġin Ġlist Ġmarked Ġwith Ġspecial Ġstop - value Ġ(- 1 ) ĊĠĠĠĠĠĠĠ Ġval Ġfinished Count Ġ= Ġrelations . count Ġ{ Ġentry Ġ-> Ġentry . value . last () Ġ== Ġ- 1 L Ġ} ĊĠĠĠĠĠĠĠ ĠTim ber . d (" Relations Ġsearch Ġprogress : Ġ$ finished Count Ġfrom Ġ${ relations . size }") ĊĠĠĠĠĠĠĠ Ġif Ġ( finished Count Ġ== Ġrelations . size ) Ġreturn Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġval Ġids Ġ= Ġrelations . map Ġ{ Ġentry Ġ-> Ġentry . value . last () Ġ}. filter Ġ{ Ġentry Ġ-> Ġentry Ġ!= Ġ- 1 L Ġ} ĊĠĠĠĠĠĠĠ ĠTim ber . d (" Remaining Ġmedia Ġids : Ġ$ ids ") ĊĊĠĠĠĠĠĠĠ Ġval Ġresponse Inner Ġ= Ġget Media Relations ( ids Ġ= Ġids , Ġpage Ġ= Ġ 1 , Ġper Page Ġ= Ġ 3 0 ) ĊĊĠĠĠĠĠĠĠ Ġval Ġrate Limit Ġ= Ġget Response RateLimit ( response Inner ) ĊĠĠĠĠĠĠĠ ĠTim ber . d ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Network Ġquery Ġrate Ġlimit Ġstatus : Ġ${ rate Limit . remaining } Ġfrom Ġ${ rate Limit . total }" ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġdelay ( 1 0 0 ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( response Inner . has Errors ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . e (" Relations Ġrequest Ġfailed : Ġ`${ response Inner . errors . toString () }` !") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ- 1 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠTim ber . d (" Relations Ġresponse Ġsucceed : Ġ${ response Inner . data ?. page ?. media ?. size } Ġmedia Ġfound ") ĊĠĠĠĠĠĠĠ Ġif Ġ( response Inner . data ?. page ?. media ?. isEmpty () Ġ== Ġtrue ) Ġreturn Ġ- 1 ĊĊĠĠĠĠĠĠĠ Ġval Ġmedia List Ġ= Ġresponse Inner . data ?. page ?. media ?. filter NotNull () Ġ?: Ġempty List () ĊĠĠĠĠĠĠĠ Ġmedia List . forEach Ġ{ Ġmedium Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" Calculation Ġepisode Ġcount Ġfor Ġmedia Ġ'${ medium . title ?. rom aji }' ...") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFind Ġkey Ġwith Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparent Ġ= Ġrelations . entries . find Ġ{ Ġentry Ġ-> Ġentry . value . indexOf ( medium . id . to Long ()) Ġ!= Ġ- 1 Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġid Ġ= Ġparent ?. key Ġ?: Ġmedium . id ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( relations . containsKey ( id )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( has Pre quel , Ġpre quel Id ) Ġ= Ġget Pre quel ( medium ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( has Pre quel ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrelations [ id ]?. add ( pre quel Id . to Long ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrelations [ id ]?. add (- 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġsearch Pre que ls ( relations ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠTODO : Ġmove Ġto Ġcustom ĠWorker Ġto Ġincrease Ġload Ġspeed Ġand Ġavoid Ġrate Ġlimit ĊĠĠĠ Ġsuspend Ġfun Ġfill Episode Count ( ĊĠĠĠĠĠĠĠ Ġserver Media List : ĠList < Media List Query . Medium >, Ġmedia List : ĠList < Remote Media >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġids Ġ= Ġmedia List . associate By ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġit . an il ist Id Ġ}, Ġ{ Ġmutable ListOf ( it . an il ist Id ) Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġsearch Pre que ls ( ids ) ĊĠĠĠĠĠĠĠ Ġids . forEach Ġ{ Ġentry Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġseason Count Ġ= Ġentry . value . size Ġ- Ġ 1 ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmedium Ġ= Ġserver Media List . find Ġ{ Ġmedium Ġ-> Ġmedium . id . to Long () Ġ== Ġentry . key Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Id =${ entry . key } Ġname Ġ'${ medium ?. title ?. rom aji }' Ġseason Ġcount : Ġ$ season Count " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmedia Ġ= Ġmedia List . find Ġ{ Ġmedia Ġ-> Ġmedia . an il ist Id Ġ== Ġentry . key Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmedia ?. season Ġ= Ġseason Count ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġdata Ġclass ĠAn il ist RateLimit ( val Ġtotal : ĠInt , Ġval Ġremaining : ĠInt ) ĊĊĠĠĠ Ġfun Ġ< T > Ġget Response RateLimit ( response : ĠResponse < T >): ĠAn il ist RateLimit Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠDEFAULT _ RATE _ LIMIT Ġ= Ġ 9 0 ĊĠĠĠĠĠĠĠ Ġval ĠR ATE _ LIMIT _ TOTAL _ KEY Ġ= Ġ" X - RateLimit - Limit " ĊĠĠĠĠĠĠĠ Ġval ĠR ATE _ LIMIT _ RE MAIN ING _ KEY Ġ= Ġ" X - RateLimit - Remaining " ĊĊĠĠĠĠĠĠĠ Ġ// ĠSee Ġhttps :// an il ist . gitbook . io / an il ist - apiv 2 - docs / overview / rate - limit ing Ġfor Ġdetails ĊĠĠĠĠĠĠĠ Ġ@ Opt In ( A pol lo Experimental :: class ) ĊĠĠĠĠĠĠĠ Ġval Ġhttp Context Ġ= Ġresponse . executionContext [ Ok Http ExecutionContext . KEY ] ĊĠĠĠĠĠĠĠ Ġ@ Opt In ( A pol lo Experimental :: class ) ĊĠĠĠĠĠĠĠ Ġval Ġheaders Ġ= Ġhttp Context ?. response ?. headers ĊĊĠĠĠĠĠĠĠ Ġ/* headers ?. names ()?. forEach Ġ{ Ġname Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" Response ĠHTTP Ġheader : Ġ'${ name }' Ġ=> Ġ'${ headers . get ( name )} '") ĊĠĠĠĠĠĠĠ Ġ}*/ ĊĊĠĠĠĠĠĠĠ Ġval Ġtotal Str Ġ= Ġheaders ?. get ( RATE _ LIMIT _ TOTAL _ KEY ). or Empty () ĊĠĠĠĠĠĠĠ Ġval Ġremaining Str Ġ= Ġheaders ?. get ( RATE _ LIMIT _ RE MAIN ING _ KEY ). or Empty () ĊĊĠĠĠĠĠĠĠ Ġval Ġtotal Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( total Str . isEmpty () Ġ|| Ġ! total Str . is Digits Only ()) ĠDEFAULT _ RATE _ LIMIT Ġelse Ġtotal Str . toInt () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exc : ĠNumber FormatException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . e (" Invalid Ġtotal Ġrate Ġlimit Ġvalue : Ġ'$ total Str ' !") ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDEFAULT _ RATE _ LIMIT ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġremaining Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( remaining Str . isEmpty () Ġ|| Ġ! remaining Str . is Digits Only ()) Ġ 0 Ġelse Ġremaining Str . toInt () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exc : ĠNumber FormatException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . e (" Invalid Ġremaining Ġrate Ġlimit Ġvalue : Ġ'$ remaining Str ' !") ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn ĠAn il ist RateLimit ( total , Ġremaining ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġdata Ġclass ĠAn il ist Pagination ( ĊĠĠĠĠĠĠĠ Ġval Ġtotal Items : ĠInt , ĊĠĠĠĠĠĠĠ Ġval ĠcurrentPage : ĠInt , ĊĠĠĠĠĠĠĠ Ġval Ġper Page : ĠInt , ĊĠĠĠĠĠĠĠ Ġval Ġtotal Pages : ĠInt , ĊĠĠĠĠĠĠĠ Ġval Ġhas Next Page : ĠBoolean ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġfun Ġget Response Pagination ( response : ĠResponse < Media List Query . Data >): ĠAn il ist Pagination Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠAn il ist Pagination ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtotal Items Ġ= Ġresponse . data ?. page ?. page Info ?. total Ġ?: Ġ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠcurrentPage Ġ= Ġresponse . data ?. page ?. page Info ?. currentPage Ġ?: Ġ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġper Page Ġ= Ġresponse . data ?. page ?. page Info ?. per Page Ġ?: Ġ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtotal Pages Ġ= Ġresponse . data ?. page ?. page Info ?. last Page Ġ?: Ġ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhas Next Page Ġ= Ġresponse . data ?. page ?. page Info ?. hasNext Page Ġ?: Ġfalse ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ////////////////////////////////////////////////////////////////// //////////////////////// ////// ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠBASE _ URL Ġ= Ġ" https :// graphql . an il ist . co " ĊĊĠĠĠĠĠĠĠ Ġfun Ġcreate Client (): ĠApollo Client Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( Looper . my Looper () Ġ== ĠL ooper . get Main Looper ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Only Ġthe Ġmain Ġthread Ġcan Ġget Ġthe Ġap ollo Client Ġinstance !" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlogger Ġ= ĠHttp Logging Interceptor Ġ{ ĠTim ber . d ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . level Ġ= ĠHttp Logging Interceptor . Level . BASIC ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġok HttpClient Ġ= ĠOk HttpClient . Builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Interceptor ( logger ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠApollo Client . builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. server Url ( BASE _ URL ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. ok HttpClient ( ok HttpClient ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġcreate ( client : ĠApollo Client ): ĠAn il ist Api Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠAn il ist Api ( client ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ