package Ġorg . jetbrains . bio . pub trend s . pm Ċ Ċ import Ġkotlinx . coroutines . run Blocking Ċ import Ġkotlinx . coroutines . with Timeout Ċ import Ġorg . apache . commons . net . ftp . FTP Client Ċ import Ġorg . apache . commons . net . ftp . FTP Reply Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġjava . io . Buffered OutputStream Ċ import Ġjava . io . File Ċ import Ġjava . io . IOException ĊĊ Ċ class ĠPub med FTP Handler Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠLOG Ġ= ĠLoggerFactory . getLogger ( Pub med FTP Handler :: class . java ) ĊĊĠĠĠĠĠĠĠ Ġconst Ġval ĠSERVER Ġ= Ġ" ftp . ncbi . nlm . nih . gov " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠBASE LINE _ PATH Ġ= Ġ"/ pub med / baseline " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠUPDATE _ PATH Ġ= Ġ"/ pub med / update files " ĊĊĠĠĠĠĠĠĠ Ġconst Ġval ĠTIME OUT _ MS Ġ= Ġ 2 0 0 0 0 ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠDOWN LOAD _ TIMEOUT _ MS Ġ= Ġ 1 0 0 0 0 0 L ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠYEAR Ġ= Ġ 2 2 ĊĊĠĠĠĠĠĠĠ Ġfun Ġpub med File To Id ( name : ĠString ): ĠInt Ġ= Ġname . remove Sur rounding (" pub med ${ YEAR } n ", Ġ". xml . gz "). toInt () ĊĊĠĠĠĠĠĠĠ Ġfun Ġid To Pub med File ( id : ĠInt ): ĠString Ġ= Ġ" pub med ${ YEAR } n ${ id . toString (). pad Start ( 4 , Ġ' 0 ') }. xml . gz " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġfetch ( last Id : ĠInt Ġ= Ġ 0 ): ĠPair < List < String >, ĠList < String >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġftp Ġ= ĠClose able FTP Client () ĊĊĠĠĠĠĠĠĠ Ġftp . use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . info (" Connecting Ġto Ġ$ SERVER ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconnect ( it ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . info (" Fetching Ġbaseline Ġfiles ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbaseline Files Ġ= Ġget New XML s List ( it , ĠBASE LINE _ PATH , Ġlast Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . info (" Fetching Ġupdate Ġfiles ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġupdate Files Ġ= Ġget New XML s List ( it , ĠUPDATE _ PATH , Ġlast Id ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠPair ( baseline Files , Ġupdate Files ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdownload Baseline File ( name : ĠString , Ġlocal Path : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġftp Ġ= ĠClose able FTP Client () ĊĊĠĠĠĠĠĠĠ Ġftp . use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconnect ( it ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġftp . change Working Directory ( BASE LINE _ PATH ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdownload File ( it , Ġname , Ġlocal Path ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdownload Update File ( name : ĠString , Ġlocal Path : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġftp Ġ= ĠClose able FTP Client () ĊĊĠĠĠĠĠĠĠ Ġftp . use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconnect ( it ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġftp . change Working Directory ( UPDATE _ PATH ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdownload File ( it , Ġname , Ġlocal Path ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġprivate Ġfun Ġconnect ( ftp : ĠFTP Client ) Ġ{ ĊĠĠĠĠĠĠĠ Ġftp . connect ( SERVER ) ĊĠĠĠĠĠĠĠ Ġval Ġreply Ġ= Ġftp . reply Code ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! FTP Reply . is Positive Completion ( reply )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġftp . disconnect () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" FTP Ġserver Ġrefused Ġconnection .") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġftp . enter Local Pass ive Mode () ĊĠĠĠĠĠĠĠ Ġif Ġ(! ftp . login (" anonymous ", Ġ"")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Failed Ġto Ġlog Ġin .") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠTimeout s Ġare Ġset Ġto Ġavoid Ġinfinite Ġdownload ĊĠĠĠĠĠĠĠ Ġftp . default Timeout Ġ= ĠTIME OUT _ MS ĊĠĠĠĠĠĠĠ Ġftp . setData Timeout ( TIMEOUT _ MS ) ĊĠĠĠĠĠĠĠ Ġftp . connect Timeout Ġ= ĠTIME OUT _ MS ĊĠĠĠĠĠĠĠ Ġftp . so Timeout Ġ= ĠTIME OUT _ MS ĊĠĠĠĠĠĠĠ Ġftp . control KeepAlive Timeout Ġ= ĠTIME OUT _ MS . to Long () ĊĠĠĠĠĠĠĠ Ġftp . control KeepAlive Reply Timeout Ġ= ĠTIME OUT _ MS ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! ftp . set FileType ( FTP Client . BINARY _ FILE _ TYPE )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIOException (" Failed Ġto Ġset Ġbinary Ġfile Ġtype .") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdownload File ( ftp : ĠFTP Client , Ġname : ĠString , Ġlocal Path : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlocal File Ġ= ĠFile ("$ local Path /$ name ") ĊĊĠĠĠĠĠĠĠ Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwith Timeout ( time Millis Ġ= ĠDOWN LOAD _ TIMEOUT _ MS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBuffered OutputStream ( local File . output Stream ()). use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġftp . retrieve File ( name , Ġit ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget New XML s List ( ftp : ĠFTP Client , Ġdirectory : ĠString , Ġlast Id : ĠInt ): ĠList < String > Ġ{ ĊĠĠĠĠĠĠĠ Ġftp . change Working Directory ( directory ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġftp . list Files ()?. filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . name . endsWith (". xml . gz ") Ġ&& Ġpub med File To Id ( it . name ) Ġ> Ġlast Id ĊĠĠĠĠĠĠĠ Ġ} ?. map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . name ĊĠĠĠĠĠĠĠ Ġ} Ġ?: Ġempty List () ĊĠĠĠ Ġ} Ċ }