package Ġcom . github . dav in ke vin . podcast server . update . up dat ers . fr anc et v Ċ Ċ import Ġcom . fasterxml . jackson . annotation . JsonIgnore Properties Ċ import Ġcom . fasterxml . jackson . annotation . JsonProperty Ċ import Ġcom . fasterxml . jackson . databind . ObjectMapper Ċ import Ġcom . fasterxml . jackson . module . kotlin . readValue Ċ import Ġcom . github . dav in ke vin . podcast server . extension . java . util . or Null Ċ import Ġorg . js oup . J soup Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġorg . springframework . util . Digest Utils Ċ import Ġorg . springframework . web . reactive . function . client . Web Client Ċ import Ġorg . springframework . web . reactive . function . client . body To Mono Ċ import Ġreactor . core . publisher . Flux Ċ import Ġreactor . core . publisher . Mono Ċ import Ġreactor . kotlin . core . publisher . switch If Empty Ċ import Ġreactor . kotlin . core . publisher . to Mono Ċ import Ġreactor . kotlin . core . util . function . component 1 Ċ import Ġreactor . kotlin . core . util . function . component 2 Ċ import Ġjava . net . URI Ċ import Ġjava . time . Instant Ċ import Ġjava . time . Zone Id Ċ import Ġjava . time . Z onedDateTime Ċ import Ġjava . util .* Ċ import Ġcom . github . dav in ke vin . podcast server . service . image . Image Service Ċ import Ġcom . github . dav in ke vin . podcast server . update . up dat ers .* Ċ import Ġjava . time . Clock Ċ Ċ class ĠFrance Tv Updater ( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġfr ance Tv Client : ĠWeb Client , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġfr ance Tv Api : ĠWeb Client , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġimage : ĠImage Service , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġmapper : ĠObjectMapper , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġclock : ĠClock Ċ ): ĠUp dater Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġlog Ġ= ĠLoggerFactory . getLogger ( Fr ance Tv Updater :: class . java ) ĊĊĠĠĠ Ġoverride Ġfun Ġfind Items ( podcast : ĠPod cast ToUpdate ): ĠFlux < Item From Update > Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġurl Ġ= Ġpod cast . url . to ASCII String () ĊĊĠĠĠĠĠĠĠ Ġlog . debug (" Fetch Ġ$ url ") ĊĊĠĠĠĠĠĠĠ Ġval Ġreplay Ġ= Ġreplay Url ( podcast . url ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġfr ance Tv Client ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. get () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. uri ( replay ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. retrieve () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. body To Mono < String >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ ĠJ soup . parse ( it , Ġurl ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Iterable Ġ{ Ġit . select (". c - wall ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Iterable Ġ{ Ġit . select (". c - card - video ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . class Names (). none Ġ{ Ġc Ġ-> Ġc . contains (" un available ") Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Iterable Ġ{ Ġit . select (" a [ href ]") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . attr (" href ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ Ġurl To Item ( it ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġurl To Item ( path Url : ĠString ): ĠMono < Item From Update > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġfr ance Tv Client ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. get () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. uri ( path Url ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. retrieve () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. body To Mono < String >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ ĠJ soup . parse ( it , Ġ" https :// www . france . tv /") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Iterable Ġ{ Ġit . select (" script ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . html () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġ" FT V Player Videos " Ġin Ġit Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. to Mono () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . substring After Last (" FT V Player Videos Ġ= Ġ"). trim (' ; ') Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Iterable Ġ{ Ġmapper . readValue < Set < Fr ance Tv Page Item >>( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . content Id Ġin Ġpath Url Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. to Mono () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġ"/ tools / get Infos Oe uv re / v 2 /? id Diff usion =${ it . video Id }" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ Ġfr ance Tv Api . get () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. uri ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. retrieve () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. body To Mono < Fr ance Tv Item >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ Ġit . to Mono (). zip With ( image . fetch Cover Information Or Option ( it . image )) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġ( france Tv Item , Ġcover ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠItem From Update ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtitle Ġ= Ġfr ance Tv Item . title () !! , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdescription Ġ= Ġfr ance Tv Item . syn opsis !! , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpub Date Ġ= Ġfr ance Tv Item . pub Date ( clock ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġurl Ġ= ĠURI (" https :// www . france . tv $ path Url "), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcover Ġ= Ġcover . or Null (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠmimeType Ġ= Ġ" video / mp 4 " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. onError Resume Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . error (" Error Ġduring Ġfetch Ġof Ġ$ path Url ", Ġit ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMono . empty () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġsignature Of ( url : ĠURI ): ĠMono < String > Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġreplay Ġ= Ġreplay Url ( url ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġfr ance Tv Client ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. get () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. uri ( replay ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. retrieve () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. body To Mono < String >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ ĠJ soup . parse ( it , Ġurl . to ASCII String ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Iterable Ġ{ Ġit . select (". c - wall ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Iterable Ġ{ Ġit . select (". c - card - video ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . class Names (). none Ġ{ Ġc Ġ-> Ġc . contains (" un available ") Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Iterable Ġ{ Ġit . select (" a [ href ]") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . attr (" href ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. sort () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. reduce Ġ{ Ġt , Ġu Ġ-> Ġ""" $ t -$ u """ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ ĠDigest Utils . md 5 Digest As Hex ( it . toByteArray ()) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. switch If Empty (" ". to Mono ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġtype () Ġ= ĠType (" Fr ance Tv ", Ġ" Fr ance âĢ¢ tv ") ĊĊĠĠĠ Ġoverride Ġfun Ġcompatibility ( url : ĠString ): ĠInt Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġ" www . france . tv " Ġin Ġurl Ġ-> Ġ 1 ĊĠĠĠĠĠĠĠ Ġelse Ġ-> ĠInteger . MAX _ VALUE ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġreplay Url ( url : ĠURI ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ"${ url . to ASCII String () }/ to utes - les - videos /" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. substring After (" https :// www . france . tv /") ĊĊĠĠĠ Ġ} Ċ } ĊĊ Ċ @ JsonIgnore Properties ( ignore Unknown Ġ= Ġtrue ) Ċ private Ġdata Ġclass ĠFrance Tv Page Item ( val Ġcontent Id : ĠString , Ġval Ġvideo Id : ĠString ) Ċ Ċ @ JsonIgnore Properties ( ignore Unknown Ġ= Ġtrue ) Ċ private Ġdata Ġclass ĠFrance Tv Item ( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġt itre : ĠString ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠ Ġval Ġsyn opsis : ĠString ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġsa ison : ĠString ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġepisode : ĠString ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠ Ġ@ field : JsonProperty (" so us _ tit re ") Ġprivate Ġval Ġsous T itre : ĠString ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġdiff usion : ĠDiff usion ?, ĊĠĠĠĠĠĠĠ Ġ@ field : JsonProperty (" image _ secure ") Ġval Ġimage : ĠURI ? Ġ= Ġnull Ċ ) Ġ{ ĊĊĠĠĠ Ġfun Ġtitle (): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġseason Ġ= Ġsa ison Ġ?: Ġ"" ĊĠĠĠĠĠĠĠ Ġval Ġep Ġ= Ġepisode Ġ?: Ġ"" ĊĠĠĠĠĠĠĠ Ġval Ġsub Title Ġ= Ġsous T itre Ġ?: Ġ"" ĊĊĠĠĠĠĠĠĠ Ġval Ġseason Is Present ĠĠĠĠ Ġ= Ġseason . isNotEmpty () ĊĠĠĠĠĠĠĠ Ġval Ġepisode Is Present ĠĠĠ Ġ= Ġep . isNotEmpty () ĊĠĠĠĠĠĠĠ Ġval Ġsub Title Is Present ĠĠ Ġ= Ġsub Title . isNotEmpty () ĊĠĠĠĠĠĠĠ Ġ/* ĊĠĠĠĠĠĠĠĠ Ġ* ĠRemove Ġsome Ġcomparison Ġfor Ġpurpose Ġof Ġcode Ġcoverage Ġanalysis . ĠOrders Ġshould Ġbe Ġkept Ġfor Ġlogical Ġpurpose ĊĠĠĠĠĠĠĠĠ Ġ* Ġhttps :// github . com / jac oco / jac oco / issues / 9 2 1 ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġseason Is Present ĠĠĠ Ġ&& ĠĠĠ Ġ! episode Is Present ĠĠ Ġ&& ĠĠĠ Ġsub Title Is Present ĠĠĠ Ġ-> Ġ"$ tit re Ġ- ĠS $ season Ġ- Ġ$ sub Title " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġseason Is Present ĠĠĠ Ġ&& ĠĠĠ Ġ! episode Is Present Ġ/* && ĠĠĠ Ġsub Title IsEmpty ĠĠ Ġ*/ Ġ-> Ġ"$ tit re Ġ- ĠS $ season " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġseason Is Present ĠĠĠ Ġ&& Ġ/* Ġ! episode IsEmpty ĠĠĠĠ Ġ&& Ġ*/ Ġsub Title Is Present ĠĠĠ Ġ-> Ġ"$ tit re Ġ- ĠS ${ season } E $ episode Ġ- Ġ$ sub Title " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġseason Is Present Ġ/* Ġ&& ĠĠĠ Ġ! episode IsEmpty ĠĠĠĠ Ġ&& ĠĠĠ Ġsub Title IsEmpty ĠĠ Ġ*/ Ġ-> Ġ"$ tit re Ġ- ĠS ${ season } E $ ep " ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/* season IsEmpty ĠĠĠ Ġ&& Ġ*/ Ġepisode Is Present ĠĠĠ Ġ&& ĠĠĠ Ġsub Title Is Present ĠĠĠ Ġ-> Ġ"$ tit re Ġ- ĠE $ ep Ġ- Ġ$ sub Title " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/* season IsEmpty ĠĠĠ Ġ&& ĠĠĠ Ġepisode IsEmpty ĠĠĠĠĠ Ġ&& Ġ*/ Ġsub Title Is Present ĠĠĠ Ġ-> Ġ"$ tit re Ġ- Ġ$ sub Title " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ/* season IsEmpty ĠĠĠ Ġ&& Ġ*/ Ġepisode Is Present Ġ/* Ġ&& ĠĠĠ Ġsub Title IsEmpty ĠĠ Ġ*/ Ġ-> Ġ"$ tit re Ġ- ĠE $ ep " ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġt itre ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġpub Date ( clock : ĠClock ): ĠZ onedDateTime Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( diff usion ?. timestamp Ġ== Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠZ onedDateTime . now ( clock ) ĊĊĠĠĠĠĠĠĠ Ġreturn ĠZ onedDateTime . of Instant ( Instant . of Epoch Second ( diff usion . timestamp ), ĠZ ONE _ ID ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ JsonIgnore Properties ( ignore Unknown Ġ= Ġtrue ) ĊĠĠĠ Ġinternal Ġdata Ġclass ĠDiff usion ( val Ġtimestamp : ĠLong ?) Ċ } Ċ Ċ private Ġval ĠZ ONE _ ID Ġ= ĠZone Id . of (" Europe / Par is ") ĊĊ Ċ private Ġfun ĠImage Service . fetch Cover Information Or Option ( url : ĠURI ?): ĠMono < Optional < Item From Update . Cover >> Ġ{ ĊĠĠĠ Ġreturn ĠMono . just OrEmpty ( url ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ Ġfetch Cover Information ( url !! ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ ĠItem From Update . Cover ( it . width , Ġit . height , Ġit . url ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ ĠOptional . of < Item From Update . Cover >( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. switch If Empty Ġ{ ĠOptional . empty < Item From Update . Cover >(). to Mono () Ġ} Ċ } Ċ