package Ġau . com . null pointer . images . organ ise Ċ Ċ import Ġcom . d rew . im aging . FileType Ċ import Ġcom . d rew . im aging . FileType Detector Ċ import Ġcom . d rew . im aging . Image Metadata Reader Ċ import Ġcom . d rew . metadata . Directory Ċ import Ġcom . d rew . metadata . ex if . Ex if Sub IF DD irectory Ċ import Ġjava . io . Buffered InputStream Ċ import Ġjava . nio . file . Files Ċ import Ġjava . nio . file . Path Ċ import Ġjava . nio . file . Paths Ċ import Ġjava . nio . file . attribute . Basic File Attributes Ċ import Ġjava . time . Instant Ċ import Ġjava . util . stream . Collectors . toList Ċ Ċ fun Ġmain ( args : ĠArray < String >) Ġ{ ĊĠ Ġcheck ( args . isNotEmpty ()) Ġ{ Ġ" Missing Ġdirectories " Ġ} ĊĠ Ġprintln (" Optim ising Ġimages Ġin Ġ${ args [ 0 ]} ") ĊĊĠ Ġval Ġroots Ġ= Ġargs . map Ġ{ Ġroot Ġ-> ĊĠĠĠ Ġif Ġ( root . startsWith (" ~ ")) Ġ{ ĊĠĠĠĠĠ Ġroot . replace (" ~ ", ĠSystem . getProperty (" user . home ")) ĊĠĠĠ Ġ} Ġelse Ġroot ĊĠ Ġ} ĊĊĠ Ġfor Ġ( root Ġin Ġroots ) Ġ{ ĊĠĠĠ Ġval Ġdetails Ġ= ĠFiles . walk ( Paths . get ( root )) ĊĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġ! Files . isDirectory ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġ. map (:: getFile Details ) ĊĠĠĠĠĠĠĠ Ġ. collect ( toList ()) ĊĊĠĠĠ Ġprintln (" Images :") ĊĠĠĠ Ġdetails . filter Ġ{ Ġit . type Ġ!= ĠFile Type . Unknown Ġ}. forEach (:: println ) ĊĠĠĠ Ġprintln ("\ n Other :") ĊĠĠĠ Ġdetails . filter Ġ{ Ġit . type Ġ== ĠFile Type . Unknown Ġ}. forEach (:: println ) ĊĠ Ġ} Ċ } Ċ Ċ fun ĠgetFile Details ( path : ĠPath ): ĠFile Details Ġ{ ĊĠ Ġval Ġdetails Ġ= ĠFile Details . for Path ( path ) ĊĊĠ Ġval Ġtype Ġ= ĠFiles . new InputStream ( path ). use Ġ{ Ġins Ġ-> ĊĠĠĠ Ġif Ġ( ins . available () Ġ< Ġ 8 ) Ġ{ ĊĠĠĠĠĠ Ġreturn @ use ĠFile Type . Unknown ĊĠĠĠ Ġ} ĊĠĠĠ ĠFile Type Detector . detect FileType ( Buffered InputStream ( ins )) ĊĠ Ġ} ĊĊĠ Ġif Ġ( type Ġ== ĠFile Type . Unknown ) Ġ{ ĊĠĠĠ Ġreturn Ġdetails ĊĠ Ġ} ĊĊĊĠ Ġval Ġmetadata Ġ= ĠImage Metadata Reader . read Metadata ( path . to File ()) ĊĠ Ġval Ġex if Ġ= Ġmetadata . getFirst Directory OfType ( Ex if Sub IF DD irectory :: class . java ) ĊĊĠ Ġreturn Ġdetails . copy ( type Ġ= Ġtype , Ġex if Created Ġ= Ġex if ?. date Original ?. to Instant ()) Ċ } Ċ Ċ data Ġclass ĠFile Details ( ĊĠĠĠ Ġval Ġname : ĠString , ĊĠĠĠ Ġval Ġsize : ĠLong , ĊĠĠĠ Ġval Ġcreated : ĠInstant , ĊĠĠĠ Ġval Ġupdated : ĠInstant , ĊĠĠĠ Ġval Ġtype : ĠFile Type Ġ= ĠFile Type . Unknown , ĊĠĠĠ Ġval Ġex if Created : ĠInstant ? Ġ= Ġnull Ċ ) Ġ{ ĊĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠ Ġfun Ġfor Path ( path : ĠPath ): ĠFile Details Ġ{ ĊĠĠĠĠĠ Ġval Ġattrs Ġ= ĠFiles . read Attributes ( path , ĠBasic File Attributes :: class . java ) ĊĠĠĠĠĠ Ġreturn ĠFile Details ( ĊĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġpath . toString (), ĊĠĠĠĠĠĠĠĠĠ Ġsize Ġ= Ġattrs . size (), ĊĠĠĠĠĠĠĠĠĠ Ġcreated Ġ= Ġattrs . creation Time (). to Instant (), ĊĠĠĠĠĠĠĠĠĠ Ġupdated Ġ= Ġattrs . lastModified Time (). to Instant () ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ }