::@echo off :: :: 20 June 2012 - Version Draft 4.1 (using end.stop) :: :: setup the constants SET MySvrIP=\\192.168.0.100\ SET MyPhotoShare=Photo$ SET SvrUser=ReadOnly SET SvrPass=@Ph0to_Fram3 :: start with a small cache of 50Mb - just to make sure everything is working ... SET cacheSize=50 ::once it's working, remove above and set max 1Gb (1 * 1024 Mb) or 1.5 or whatever ::SET /a cacheSize=1*1024 :: :: set the cache min free space = 2Mb, in bytes SET /a MinFree=2*1024*1024 :: :: set the date delimiter (used to check the archive folder names start with ????-??- (yyyy-mm-dd)) SET DateDelim="-" :: :: OK, lets go & don't forget ... :: use P: for the Photo archive :: use M: for the image Memory 'cache' (usually RAM disk, but may be USB stick etc) :: use T: for the Temp files (will be RAM disk) :: :: T: is removed after each run - if it exists now the script is running twice, so abort SET cNewest=dup_temp.err IF EXIST T:\NUL GOTO END :: note @ END the 'end.stop' is renamed %cNewest% (which should cleanly stop any other 'instance' of the script) :: :: Create the Temp RAM disk, 25Mb should be enough imdisk -a -s 25M -m T: -p "/fs:fat /q /y" :: note that imdisk uses FORMAT.EXE to format the RAM disk SET cNewest=no_temp.err IF NOT EXIST T:\NUL GOTO END :: :: Check if cache (M:) already exists (so not the first run after power-on, :: or VSuite Ramdisk has just loaded M: from hard disk or CF card etc.) IF EXIST M:\NUL GOTO got_M :: Here it must be a power-on with no cache - so create imdisk -a -s %cacheSize%M -m M: -p "/fs:fat /q /y" SET cNewest=no_cache.err IF NOT EXIST M:\NUL GOTO END :: copy a known old file (MS config.sys = 2004) into the empty cache since we must have an end-stop COPY c:\config.sys M: IF NOT EXIST M:\config.sys GOTO END :: (note COPY, even with new name, preserves the modified date of the original file) :: :got_M :: if end.stop exists, the script is running twice (or crashed w/o clearing end.stop) SET cNewest=dup_stop.err IF EXIST M:\end.stop GOTO END :: :: now open a link to the archive server NET USE P: %MySvrIP%%MyPhotoShare% %SvrPass% /USER:%MySvrIP%%SvrUser% SET cNewest=no_netP.err IF NOT EXIST P:\NUL GOTO END :: :: find the 'newest' (or only) file in the cache & set it as the end.stop :: get a dir listing of M: for file names only, newest first o-d (& don't list 'directories' /a-d) DIR M:\ /o-D /a-d /b > T:\cache.lst :: get the first line of the dir listing = this is the name of the newest file in the cache SET /P cNewest=T:\temp.lst :: and extract the files date FOR /f %%G IN ('FIND "end.stop.jpg" T:\temp.lst') DO set n_date=%%G SET n_day=%n_date:~0,2% SET n_mth=%n_date:~3,2% SET n_yr=%n_date:~6,4% :: :: OK, ready to start processing archive folders ! :: get a listing of the photo archive folders in alphabetical (i.e. date name) order. DIR P:\ /o-n /ad /b > T:\aFolders.lst :: Step through the archive folders, skipping any that are not newer than end.stop :: If we don't have enough photo's to fill the cache, the 'For' loop below will exhaust the folder list :: and automatically fall into the 'clean up' code below (without end.stop being deleted) FOR /F "tokens=1*" %%g in (T:\aFolders.lst) do call :do_photos "%%g" :: :clean_up :: the time stamps of todays cached images are in the 'wrong' order .. :: since the cache is in RAM, reverse the time stamps by recreating the images :: (what are todays images ? = all those with name.jpg.jpg) IF NOT EXIST M:\*.jpg.jpg GOTO END :: list them newest first (o-d) DIR M:\*.jpg.jpg /a-d /o-d /b > T:\temp.lst FOR /F "tokens=1*" %%G in (T:\temp.lst) do CALL :swap %%G GOTO END :: :swap IF "%1"=="" goto:eof SET param=%1 :: file = param - the second '.jpg' (i.e. - the last 4 characters) SET fname=%param:~0,-4% TYPE M:\%fname%.jpg > M:\%fname% IF EXIST M:\%fname% del /q %fname%.jpg goto:eof :: :: :do_photos :: return if we have run out of newer folders IF NOT EXIST M:\end.stop GOTO:eof :: return if we reached the end of the folder list (last line of DIR list is blank) IF "%1"="" GOTO:eof SET folder=%1 :: :: Check the folder date is NEWER than end.stop (i.e. it was created after the cache was last loaded) :: = this avoids actually fetching photo's & forcing the Server disks to 'spin up' if the first folder is older :: (the 'top level' folder Directory will be cached in Server RAM so it's disks can 'sleep') :: :: check that the folder name has the expected Date Delimiter at posn. 4 & 7 = if not, skip that folder SET f_delim=%folder:~4,1% IF NOT "%f_delim%"=="%DateDelim%" GOTO:eof SET f_delim=%folder:~7,1% IF NOT "%f_delim%"=="%DateDelim%" GOTO:eof :: now extract the folders date from it's name (yyyy-mm-dd .....) SET f_yr=%folder:~0,4% SET f_mth=%folder:~5,2% SET f_day=%folder:~8,2% :: :: REName the end.stop so that processing stops (at :do_photos) unless this folder is newer REN M:\end.stop %cNewest% :: compare the archive folder date against the (saved) end.stop date :: if folder is last year, end IF %f_yr% LSS %n_yr% GOTO:eof :: if folder is next year, go process IF %f_yr% GTR %n_yr% GOTO :go_script :: same year, if folder = older month, end IF %f_mth% LSS %n_mth% GOTO:eof :: if later month, go process IF %f_mth% GTR %n_mth% GOTO :go_script :: same month, if folder date is older or same day, end IF %f_day% LEQ %n_day% GOTO:eof :: :go_script :: Here we have a newer folder = restore the end stop .. REN M:\%cNewest% end.stop :: now check at least some jpg's exist (this 'opens' the folder and will force the Server disks to spin up) IF NOT EXIST P:\%folder%\*.jpg GOTO:eof :: only process jpg photos DIR P:\%folder%\*.jpg /o-d /a-d /b > T:\aPhotos.lst For /F "tokens=1*" %%i in (T:\aPhotos.lst) do call :do_copy "%%i" GOTO:eof :: :do_copy :: return if making space has deleted end.stop IF NOT EXIST M:\end.stop GOTO:eof :: return if we reached the last (blank) line of the photo's dir listing IF "%1"="" GOTO:eof :: get the photo SET photo=%1 COPY /b P:\%folder%\%photo% T:\%photo% :: :: compare the (jpg) photo & end.stop.jpg dates using dir /o-d (to get newest first) DIR T:\*.jpg /o-D /a-d /b > T:\newer.lst SET /P newest= T:\dList.txt :: find the line containing the bytes free (it's the line with 'Dir(s)' in it) FIND "Dir(s)" T:\size.txt :: extract the free byte count = 3rd 'token' (skip G,H so = I) FOR /F "tokens=1-3" %%G IN (T:\size.txt) DO SET cFree=%%I :: if the free space is OK, return to process the next photo IF %cFree% GTR %MinFree% GOTO:eof :: ::OK, not enough space, delete the oldest image :: get a file listing in oldest file first order DIR M:\ /oD /a-d /b > T:\temp.lst :: now get the first line of the dir = name of oldest file in the cache SET /P Oname=