package Ġcom . nil h cem . d roid con de . sc raper Ċ Ċ import Ġcom . nil h cem . d roid con de . sc raper . model . Room Ċ import Ġcom . nil h cem . d roid con de . sc raper . model . Session Ċ import Ġcom . nil h cem . d roid con de . sc raper . model . Speaker Ċ import Ġorg . js oup . J soup Ċ import Ġorg . js oup . nodes . Document Ċ import Ġorg . js oup . safety . Whitelist Ċ import Ġorg . js oup . select . Elements Ċ import Ġjava . util . concurrent . TimeUnit Ċ import Ġkotlin . text . Regex Option . IGNORE _ CASE Ċ Ċ class ĠSc raper Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠBASE _ URL Ġ= Ġ" http :// d roid con . de " ĊĠĠĠĠĠĠĠ Ġval ĠSPE AK ERS _ URL Ġ= Ġ"$ BASE _ URL / en / program / speaker " ĊĠĠĠĠĠĠĠ Ġval ĠSLOT _ TIME _ REGEX Ġ= Ġ""" (\ d { 2 }) / (\ d { 2 }) / (\ d { 4 }) Ġ- Ġ(\ d { 2 }): (\ d { 2 }) Ġto Ġ(\ d { 2 }): (\ d { 2 }) """. to Regex () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun ĠgetS peak ers (): ĠList < Speaker > Ġ{ ĊĠĠĠĠĠĠĠ Ġprintln (" Get Ġspeak ers ") ĊĠĠĠĠĠĠĠ Ġreturn Ġj soup ( SPE AK ERS _ URL ). select (" div . view - content Ġ. views - row ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . select (". views - field - field - profile - last - name Ġ. field - content Ġa "). attr (" href ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. distinct () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Indexed Ġ{ Ġindex , Ġurl Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Get Ġspeaker : Ġ# " Ġ+ ĠInteger . toString ( index ) Ġ+ Ġ" Ġ- Ġurl : Ġ" Ġ+ Ġurl ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith Ġ( js oup ( url ). select ("# main - content ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġselect ("# main - content - header Ġh 1 "). fmt Text () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġphoto Ġ= Ġselect (". image - style - profile - default "). attr (" src "). replace ( Regex ("\\ ? it ok = .* $ "), Ġ"") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbio Ġ= Ġselect (". views - field - field - profile - v ita Ġdiv "). fmt Text () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġjob Ġ= Ġselect (". views - field - field - profile - job - title Ġdiv "). fmt Text () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcompany Ġ= Ġselect (". views - field - field - profile - organization Ġdiv Ġa "). fmt Text () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlinks Ġ= Ġselect (". views - field - field - profile - links Ġa "). map Ġ{ Ġit . attr (" href ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsessions Ġ= Ġselect (". view - nc ms - speaker - sessions - current Ġa "). map Ġ{ Ġit . attr (" href ") Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtitle Ġ= Ġget Speaker Title ( job , Ġcompany ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtwitter Url Ġ= Ġlinks . filter Ġ{ Ġit . contains (" twitter . com /", Ġtrue ) Ġ}. first OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtwitter Handle Ġ= Ġget Handle From Url ( twitter Url ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgithub Url Ġ= Ġlinks . filter Ġ{ Ġit . contains (" github . com /", Ġtrue ) Ġ}. first OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgithub Handle Ġ= Ġget Handle From Url ( github Url ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġwebsite Ġ= Ġlinks . filter Ġ{ Ġ! it . equals ( twitter Url ) Ġ&& Ġ! it . equals ( github Url ) Ġ}. first OrNull () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠS peaker ( index Ġ+ Ġ 1 , Ġname , Ġtitle , Ġphoto , Ġbio , Ġwebsite , Ġtwitter Handle , Ġgithub Handle , Ġsessions ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Speaker Title ( job : ĠString , Ġcompany : ĠString ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsb Ġ= ĠStringBuilder () ĊĠĠĠĠĠĠĠ Ġif Ġ(! job . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsb . append ( job ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ(! company . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! sb . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsb . append (" Ġ@ Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsb . append ( company ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( sb . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsb . toString () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Sessions ( speak ers : ĠList < Speaker >): ĠList < Session > Ġ{ ĊĠĠĠĠĠĠĠ Ġprintln (" Get Ġsessions ") ĊĠĠĠĠĠĠĠ Ġreturn Ġspeak ers ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ Ġit . sessions Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. distinct () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Indexed Ġ{ Ġindex , Ġurl Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfull Url Ġ= Ġ"$ BASE _ URL $ url " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Get Ġsession : Ġ# " Ġ+ ĠInteger . toString ( index ) Ġ+ Ġ" Ġ- Ġurl : Ġ" Ġ+ Ġfull Url ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith ( js oup ( full Url ). select (". block - content ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtitle Ġ= Ġselect (". node - header Ġh 1 Ġa "). fmt Text () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdescription Ġ= Ġselect (". field - name - field - session - description Ġ. field - items "). fmt Text () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġroom Id Ġ= ĠRoom . get Room Id ( select (". field - name - field - session - room "). text ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdate Range Ġ= Ġselect (". field - name - field - session - datetime "). text () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġspeak ers Id Ġ= Ġspeak ers ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . sessions . contains ( url ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . id Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstart At Ġ= Ġget Start At ( date Range ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġduration Ġ= Ġget Duration ( date Range ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSession ( index Ġ+ Ġ 1 , Ġtitle , Ġdescription , Ġspeak ers Id , Ġstart At , Ġduration , Ġroom Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Start At ( date Range : ĠString ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġvalues Ġ= ĠSLOT _ TIME _ REGEX . match Ent ire ( date Range )?. group Values ?. sub List ( 1 , Ġ 6 ) ĊĠĠĠĠĠĠĠ Ġif Ġ( values Ġ!= Ġnull Ġ&& Ġvalues . size Ġ== Ġ 5 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ"${ values [ 2 ]} -${ values [ 0 ]} -${ values [ 1 ]} Ġ${ values [ 3 ]} :${ values [ 4 ]}" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Duration ( date Range : ĠString ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġvalues Ġ= ĠSLOT _ TIME _ REGEX . match Ent ire ( date Range )?. group Values ?. sub List ( 4 , Ġ 8 )?. map Ġ{ Ġit . to Long () Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( values Ġ!= Ġnull Ġ&& Ġvalues . size Ġ== Ġ 4 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ(( TimeUnit . HOUR S . to Minutes ( values [ 2 ]) Ġ+ Ġvalues [ 3 ]) Ġ- Ġ( TimeUnit . HOUR S . to Minutes ( values [ 0 ]) Ġ+ Ġvalues [ 1 ])). toInt () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġj soup ( url : ĠString , Ġnb Retries : ĠInt Ġ= Ġ 3 ): ĠDocument Ġ{ ĊĠĠĠĠĠĠĠ Ġ( 0 .. nb Retries ). forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠJ soup . connect ( url ). get () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . err . println (" Error : Ġ${ e . message }. ĠRetry ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it Ġ== Ġnb Retries Ġ- Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġe ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" This Ġshould Ġnot Ġhappen ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠElements . fmt Text (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠJ soup . clean ( html (), Ġ"", ĠWh itelist . basic (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDocument . Output Settings (). pretty Print ( false )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace ( Regex ("& nbsp ;", ĠIG NORE _ CASE ), Ġ" Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace ( Regex ("& amp ;", ĠIG NORE _ CASE ), Ġ"& ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace ( Regex ("& gt ;", ĠIG NORE _ CASE ), Ġ"> "). replace ( Regex ("& lt ;", ĠIG NORE _ CASE ), Ġ"< ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace ( Regex ("< br [ \\ s / ]* >", ĠIG NORE _ CASE ), Ġ"\ n ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace ( Regex ("< p >", ĠIG NORE _ CASE ), Ġ""). replace ( Regex ("</ p >", ĠIG NORE _ CASE ), Ġ"\ n ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace ( Regex ("</ ? ul >", ĠIG NORE _ CASE ), Ġ"") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace ( Regex ("< li >", ĠIG NORE _ CASE ), Ġ" âĢ¢ Ġ"). replace ( Regex ("</ li >", ĠIG NORE _ CASE ), Ġ"\ n ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace ( Regex ("\ n \ n âĢ¢ Ġ", ĠIG NORE _ CASE ), Ġ"\ n âĢ¢ Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace ( Regex ("< a \\ s [^ > ]* >", ĠIG NORE _ CASE ), Ġ""). replace ( Regex ("</ a >", ĠIG NORE _ CASE ), Ġ"") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace ( Regex ("</ ? strong >", ĠIG NORE _ CASE ), Ġ"") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace ( Regex ("</ ? em >", ĠIG NORE _ CASE ), Ġ"") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace ( Regex ("\\ s *\ n \\ s * "), Ġ"\ n "). replace ( Regex (" ^\ n "), Ġ""). replace ( Regex ("\ n $ "), Ġ"") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Handle From Url ( url : ĠString ?): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( url Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġurl Without Last Slash Ġ= Ġif Ġ( url . last () Ġ== Ġ'/') Ġurl . substring ( 0 , Ġurl . length Ġ- Ġ 1 ) Ġelse Ġurl ĊĠĠĠĠĠĠĠ Ġreturn Ġurl Without Last Slash . substring ( url Without Last Slash . lastIndexOf ("/") Ġ+ Ġ 1 ) ĊĠĠĠ Ġ} Ċ } Ċ