package Ġcom . github . si ro que . silver ra ing r ab ber Ċ Ċ import Ġcom . github . si ro que . silver ra ing r ab ber . utils . DateTime Utils . re format DateString Ċ import Ġcom . github . si ro que . silver ra ing r ab ber . utils . File Utilities . flush File Ċ import Ġcom . github . si ro que . silver ra ing r ab ber . utils . File Utilities . make S ure Directory Exists Ċ import Ġcom . github . si ro que . silver ra ing r ab ber . Mp 3 Tag Writer . write Tags Ċ import Ġcom . github . si ro que . silver ra ing r ab ber . parsers . Web Page Extractor . get Broadcast Ċ import Ġcom . github . si ro que . silver ra ing r ab ber . parsers . Web Page Extractor . get Broadcast List Items Ċ import Ġcom . github . si ro que . silver ra ing r ab ber . models . Broadcast Ċ import Ġcom . github . si ro que . silver ra ing r ab ber . models . Broadcast Category Ċ import Ġcom . github . si ro que . silver ra ing r ab ber . parsers . Web Page Extractor . get Broadcast Category List Items Ċ import Ġokhttp 3 . Ok HttpClient Ċ import Ġokhttp 3 . Request Ċ import Ġjava . io . File Ċ import Ġjava . io . InputStream Ċ import Ġjava . util . logging . Logger Ċ Ċ object ĠBroadcast Sn atch er Ġ{ ĊĠĠĠ Ġprivate Ġvar Ġlogger : ĠLogger Ġ= ĠLogger . getLogger (" com . github . si ro que . silver ra ing r ab ber . Broadcast Sn atch er ") ĊĠĠĠ Ġprivate Ġconst Ġval ĠbaseUrl Ġ= Ġ" https :// www . silver . ru " ĊĠĠĠ Ġprivate Ġconst Ġval Ġlect ure Archive Url Ġ= Ġ" https :// www . silver . ru / admin _ materials / ark h iv - lek ts iy /" ĊĊĠĠĠ Ġfun Ġfetch ( root DirectoryPath : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġmake S ure Directory Exists ( root DirectoryPath ) ĊĠĠĠĠĠĠĠ Ġval Ġcategory Items Ġ= Ġget Broadcast Category List Items ( baseUrl , Ġ"/ program ms ") ĊĠĠĠĠĠĠĠ Ġval Ġclient Ġ= ĠOk HttpClient () ĊĠĠĠĠĠĠĠ Ġcategory Items . forEach Indexed Ġ{ Ġindex , Ġcategory Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Progress : Ġ${ category Items . size / 1 0 0 . 0 * index }% Ġ(${ category . title }) ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( category . title Ġ== Ġ" ÐĲ ÑĢ Ñħ Ð¸Ð² ĠÐ» ÐµÐº ÑĨÐ¸ Ð¹ ") Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfetch Archive Broadcast s ( baseUrl , Ġcategory , Ġroot DirectoryPath , Ġclient ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfetch Broadcast s ( baseUrl , Ġcategory , Ġroot DirectoryPath , Ġclient ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfetch Archive Broadcast s ( ĊĠĠĠĠĠĠĠ ĠbaseUrl : ĠString , ĊĠĠĠĠĠĠĠ Ġcategory : ĠBroadcast Category , ĊĠĠĠĠĠĠĠ Ġroot DirectoryPath : ĠString , ĊĠĠĠĠĠĠĠ Ġclient : ĠOk HttpClient ĊĠĠĠ Ġ) Ġ{ Ċ // ĠĠĠĠĠĠĠ Ġval Ġbroadcast List Items Ġ= Ġget Archive Broadcast List Items ( baseUrl , Ġcategory ) ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfetch Broadcast s ( ĊĠĠĠĠĠĠĠ ĠbaseUrl : ĠString , ĊĠĠĠĠĠĠĠ Ġcategory : ĠBroadcast Category , ĊĠĠĠĠĠĠĠ Ġroot DirectoryPath : ĠString , ĊĠĠĠĠĠĠĠ Ġclient : ĠOk HttpClient ĊĠĠĠ Ġ): ĠArrayList < Broadcast > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcomplete Broadcast s Ġ= ĠArrayList < Broadcast >() ĊĠĠĠĠĠĠĠ Ġval Ġcategory Output Path Ġ= Ġoutput Path For Category ( category , Ġroot DirectoryPath ) ĊĠĠĠĠĠĠĠ Ġmake S ure Directory Exists ( category Output Path ) Ċ // ĠĠĠĠĠĠĠ Ġdrop Directory Content ( category Output Path ) ĊĊĠĠĠĠĠĠĠ Ġvar Ġend Of Feed Reached Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġvar Ġpage Index Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġlatest Broadcast Date Ġ= Ġ"" ĊĠĠĠĠĠĠĠ Ġwhile Ġ(! end Of Feed Reached ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( end Of Feed Reached ) Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpage Url Ġ= Ġcategory . url Ġ+ Ġ"? P AG EN _ 1 =$ page Index & P AG EN _ 1 =${ page Index + 1 }" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbroadcast List Items Ġ= Ġget Broadcast List Items ( baseUrl , Ġpage Url ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( broadcast List Items . isEmpty () Ġ|| Ġbroadcast List Items . any Ġ{ Ġitem Ġ-> Ġitem . date Ġ== Ġ Ġlatest Broadcast Date } ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ|| ĠFile ( filePath For Broadcast ( broadcast List Items . first (). date , Ġbroadcast List Items . first (). title , Ġcategory Output Path )). exists ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġend Of Feed Reached Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbroadcast List Items . forEach Indexed Ġ{ Ġitem Index , Ġlist Item Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbroadcast File Ġ= ĠFile ( filePath For Broadcast ( list Item . date , Ġlist Item . title , Ġcategory Output Path )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( list Item . date Ġ!= Ġlatest Broadcast Date Ġ&& Ġ! broadcast File . exists ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info (" ĠĠ ĠDownloading Ġ$ list Item ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget Broadcast ( baseUrl , Ġlist Item , Ġcategory )?. let Ġ{ Ġbroadcast Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmp 3 FilePath Ġ= Ġfetch Mp 3 File ( broadcast , Ġcategory Output Path , Ġclient ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomplete Broadcast s . add ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBroadcast ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbroadcast . title , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcategory . host Names , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbroadcast . category , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbroadcast . category Url , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbroadcast . date , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbroadcast . description , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbroadcast . url , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbroadcast . stream Url , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbroadcast . img Url , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmp 3 FilePath ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info (" ĠĠ ĠSk ipping Ġbroadcast Ġlist Ġitem Ġ$ list Item ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( page Index Ġ== Ġ 0 Ġ&& Ġitem Index Ġ== Ġ 0 ) Ġlatest Broadcast Date Ġ= Ġlist Item . date ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpage Index ++ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġcomplete Broadcast s ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġoutput Path For Category ( category : ĠBroadcast Category , Ġroot DirectoryPath : ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlegal Category Path Ġ= Ġcategory . title . replace ( Regex ("[ ? |< >] "), Ġ"") ĊĠĠĠĠĠĠĠ Ġreturn Ġ"${ root DirectoryPath }\\ $ legal Category Path " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfetch Mp 3 File ( ĊĠĠĠĠĠĠĠ Ġbroadcast : ĠBroadcast , ĊĠĠĠĠĠĠĠ Ġoutput DirectoryPath : ĠString , ĊĠĠĠĠĠĠĠ Ġclient : ĠOk HttpClient ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġprintln ( broadcast ) ĊĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠRequest . Builder (). url ( broadcast . stream Url ). build () ĊĠĠĠĠĠĠĠ Ġclient . new Call ( request ). execute (). use Ġ{ Ġresponse Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! response . is Successful ) Ġlogger . se vere (" ĠĠĠĠ ĠFailed Ġto Ġfetch Ġaudio Ġfile Ġfor Ġbroadcast Ġ$ broadcast ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget Mp 3 Path Ġ= ĠfilePath For Broadcast ( broadcast . date , Ġbroadcast . title , Ġoutput DirectoryPath ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( write Broadcast ToFile ( response . body !!. byte Stream (), Ġtarget Mp 3 Path )){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġimage Stream Ġ= Ġfetch Image Stream (" https :// cdn - st 2 . r tr - vest i . ru / vh / pictures / q / 7 1 7 / 1 6 9 . jpg ", Ġclient ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( write Tags ( broadcast , Ġimage Stream , Ġtarget Mp 3 Path )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtarget Mp 3 Path ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfetch Image Stream ( img Url : ĠString ?, Ġclient : ĠOk HttpClient ): ĠByteArray ? Ġ{ ĊĠĠĠĠĠĠĠ Ġimg Url ?. let { ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info (" ĠĠ ĠStart Ġfetching Ġimage Ġfrom Ġurl : Ġ$ img Url ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠRequest . Builder (). url ( img Url ). build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclient . new Call ( request ). execute (). use Ġ{ Ġresponse Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ(! response . is Successful ) Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġresponse . body !!. byte Stream (). read Bytes () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġwrite Broadcast ToFile ( inputStream : ĠInputStream , Ġoutput FilePath : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠoutputFile Ġ= Ġflush File ( output FilePath ) ĊĠĠĠĠĠĠĠ Ġlogger . info (" ĠĠ ĠGo ing Ġto Ġstore Ġaudio Ġfile Ġat Ġpath : Ġ${ outputFile . absolute Path }") ĊĠĠĠĠĠĠĠ Ġval ĠoutputStream Ġ= ĠoutputFile . output Stream () ĊĊĠĠĠĠĠĠĠ ĠinputStream . use Ġ{ Ġinput Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream . use Ġ{ Ġoutput Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput . copy To ( output ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠoutputFile . exists () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠfilePath For Broadcast ( broadcast Date : ĠString , Ġbroadcast Title : ĠString , Ġroot Output DirectoryPath : ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdate Ġ= Ġre format DateString ( broadcast Date , Ġ" dd ĠM MMM Ġy yyy ĠHH : mm ", Ġ" yyyy MM dd _ HH mm ") ĊĠĠĠĠĠĠĠ Ġval Ġlegal FileName = Ġ(" $ date Ġ$ broadcast Title "). replace ( Regex (" [: \\\\ /* \" ? |< >] "), Ġ"_ ") ĊĠĠĠĠĠĠĠ Ġval Ġlegal Path Ġ= Ġroot Output DirectoryPath . replace ( Regex ("[ ? |< >] "), Ġ"") ĊĠĠĠĠĠĠĠ Ġreturn Ġ"${ legal Path }/${ legal FileName }. mp 3 " ĊĠĠĠ Ġ} Ċ }