package Ġus . dragon ma . background s . update Ċ Ċ import Ġus . dragon ma . getopt . Get Opt Ċ import Ġus . dragon ma . getopt . Option Ċ import Ġjava . awt . Desktop Ċ import Ġjava . io . Buffered InputStream Ċ import Ġjava . nio . file . Files Ċ import Ġjava . nio . file . Path Ċ import Ġjava . nio . file . Paths Ċ import Ġjava . nio . file . Standard Copy Option Ċ import Ġjava . util . zip . Zip InputStream Ċ import Ġkotlin . streams . toList Ċ import Ġkotlin . system . exit Process Ċ Ċ fun Ġmain ( args : ĠArray < String >) Ġ{ ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġexit Process ( App (). run ( args )) ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠ ĠSystem . err . println ("${ App (). name }: Ġ${ e . message }") ĊĠĠĠĠĠĠĠ Ġexit Process ( 1 ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġclass ĠApp Ġ{ ĊĠĠĠ Ġval Ġname Ġ= Ġ" update - background s " ĊĊĠĠĠ Ġprivate Ġval Ġusage Ġ= Ġ" Usage : Ġ$ name Ġ[- fh ]" ĊĠĠĠ Ġprivate Ġval Ġhelp Ġ= Ġ""" $ usage ĊĠĠĠĠĠĠĠ Ġ| Ġ Ġ- f ĠĠ Ġforce Ġextraction Ġof Ġnon - updated Ġfiles ĊĠĠĠĠĠĠĠ Ġ| Ġ Ġ- h ĠĠ Ġdisplay Ġthis Ġhelp ĊĠĠĠ Ġ""" . trim Margin () ĊĊĠĠĠ Ġprivate Ġvar Ġforce Ġ= Ġfalse ĊĊĠĠĠ Ġfun Ġrun ( args : ĠArray < String >): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ ĠGet Opt ( args , Ġ" fh "). forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( it ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOption (' f ') Ġ-> Ġforce Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOption (' h ') Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ( help ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ run Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġhome Path Ġ= ĠSystem . getProperty (" user . home ") ĊĠĠĠĠĠĠĠ Ġval Ġbackground s Dir Ġ= ĠPaths . get ( home Path , Ġ" P ictures ", Ġ" Background s "). ensure Directory () ĊĠĠĠĠĠĠĠ Ġval Ġdownloads Dir Ġ= Ġbackground s Dir . resolve (" Arch ives "). ensure Directory () ĊĊĠĠĠĠĠĠĠ Ġval Ġblacklist Path Ġ= Ġbackground s Dir . resolve (" black . list "). ensure File () ĊĠĠĠĠĠĠĠ Ġval Ġwhitelist Path Ġ= Ġbackground s Dir . resolve (" white . list "). ensure File () ĊĠĠĠĠĠĠĠ Ġval Ġblacklist Ġ= Ġblacklist Path . to File (). read Lines (). to Mutable Set () ĊĠĠĠĠĠĠĠ Ġval Ġwhitelist Ġ= Ġwhitelist Path . to File (). read Lines (). to Mutable Set () ĊĊĠĠĠĠĠĠĠ Ġval Ġcredentials Ġ= ĠCredentials (" Digital ĠB las p he my ĠSign ĠIn ") ĊĊĠĠĠĠĠĠĠ Ġbackground s Dir . resolve (" resolution s . list "). to File (). read Lines () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Not Ġ{ Ġit . startsWith ('# ') Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . split (' Ġ'). map ( String :: trim ). take ( 2 ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ Ġ( resolution , Ġtag ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget Dir Ġ= Ġbackground s Dir ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. resolve ( Ratio ( resolution ). pretty Print (). replace (' :', Ġ'_ ')) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. resolve ( resolution ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. resolve (" digital bl asp he my ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. ensure Directory () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstate Ġ= Ġempty Map < String , ĠString >(). to Mutable Map () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblacklist . forEach Ġ{ Ġstate [" $ it $ tag . jpg "] Ġ= Ġ" black " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhitelist . forEach Ġ{ Ġstate [" $ it $ tag . jpg "] Ġ= Ġ" white " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ("> > ĠUpdating Ġ$ resolution . zip ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( zip File , Ġupdated ) Ġ= Ġfetch File ("$ resolution . zip ", Ġdownloads Dir , Ġcredentials ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( updated Ġ|| Ġforce ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġzip Ġ= ĠZip InputStream ( Buffered InputStream ( zip File . inputStream ())) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ("> > ĠExtract ing Ġ${ zip File . name } Ġinto Ġ$ target Dir ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġunzip @ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentry Ġ= Ġzip . next Entry Ġ?: Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( entry . isDirectory ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue @ unzip ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile Ġ= Ġtarget Dir . resolve ( entry . name ). to File () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! file . valid ates ( entry . size , Ġentry . crc )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFiles . copy ( zip , Ġfile . to Path (), ĠStandard Copy Option . REPLACE _ EXIST ING ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile . set LastModified ( entry . time ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile . validate ( entry . size , Ġentry . crc ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! state . contains ( entry . name )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate [ entry . name ] Ġ= Ġ" new " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! array Of (" black ", Ġ" white "). contains ( state [ entry . name ])) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDesktop . get Desktop (). open ( file ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconsole Ġ= ĠSystem . console () Ġ?: Ġcontinue @ unzip ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquery @ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprint ("-- ĠKeep Ġ${ entry . name }? Ġ( y / n / r ): Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( console . readLine ()?. toLowerCase ()?. trim ()?. get OrDefault ( 0 , Ġ' x ')) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ' y ' Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate [ entry . name ] Ġ= Ġ" white " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak @ query ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ' n ' Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate [ entry . name ] Ġ= Ġ" black " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak @ query ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ' r ' Ġ-> ĠDesktop . get Desktop (). open ( file ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( state [ entry . name ] Ġ== Ġ" black ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile . delete () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġclean Ġup Ġany Ġremaining Ġfiles Ġthat Ġare Ġnot Ġexplicitly Ġwh itelisted ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFiles . list ( target Dir ). map Ġ{ Ġit . fileName . toString () Ġ}. toList () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. subtract ( state . filter Values Ġ{ Ġit Ġ== Ġ" white " Ġ}. keys ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Dir . resolve ( it ). to File (). delete Re cursively () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" Deleted Ġ'$ it '") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġupdate Ġfilter Ġlists ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpattern Ġ= Ġ"$ tag \\. jpg \$ ". to Regex () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblacklist . update And Save ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate . filter Values Ġ{ Ġit Ġ== Ġ" black " Ġ}. keys . map Ġ{ Ġit . replace ( pattern , Ġ"") Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġblacklist Path ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhitelist . update And Save ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate . filter Values Ġ{ Ġit Ġ== Ġ" white " Ġ}. keys . map Ġ{ Ġit . replace ( pattern , Ġ"") Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhitelist Path ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠMutable Set < String >. update And Save ( elements : ĠCollection < String >, Ġpath : ĠPath ) Ġ{ ĊĠĠĠ Ġif Ġ( this . addAll ( elements )) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtemp Path Ġ= ĠPaths . get ("$ path . tmp ") ĊĠĠĠĠĠĠĠ Ġtemp Path . to File (). write Text ( this . sorted (). join ToString ( separator Ġ= Ġ"\ n ", Ġpostfix Ġ= Ġ"\ n ")) ĊĠĠĠĠĠĠĠ ĠFiles . move ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtemp Path , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpath , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠStandard Copy Option . ATOMIC _ MOVE ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun ĠString . get OrDefault ( i : ĠInt , Ġc : ĠChar ): ĠChar Ġ{ ĊĠĠĠ Ġif Ġ( i Ġ>= Ġ 0 Ġ&& Ġi Ġ< Ġthis . length ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġthis [ i ] ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġc Ċ } Ċ