Niko's Project Corner

Automatic file maneger in PHP

Description Rule-based file manager
Languages PHP
Tags Reg­ular Ex­pres­sions
Duration Summer 2013
Modified 14th July 2013

I got tired of man­ually or­ga­niz­ing my down­loads folder, and af­ter not be­ing happy with ex­ist­ing so­lu­tions I de­cided to write a PHP script which would en­able me to eas­ily con­fig­ure new rules for file and folder man­age­ment. This is achieved by hav­ing a flex­ible class hi­er­ar­chy, so that you don't end up re­peat­ing your­self when con­fig­ur­ing new rules and ac­tions.

Cur­rently I have one class for each task, but this could be eas­ily cir­cum­vented by us­ing Clo­sures to pass in the de­sired func­tion­al­ity, in­stead of writ­ing it in­side a cus­tom class method. But the cur­rent so­lu­tion is a bit cleaner, since you can in­voke the con­struc­tor with­out know­ing about the im­ple­men­ta­tion. An ex­am­ple class can be seen be­low, which moves all video files greater than 50 Mb which con­tains "big bang the­ory" in their file name.

    class DirItemCommand_move_files_BigBangTheory extends DirItemCommand_move_files {     // Given a file name, this returns the target path where the file should be moved     public function getTargetPath($info)     {         return 'C:/Share/series/BBT/' $info['fname'];     }     public function __construct()     {         parent::__construct(new DirItemFilterCollection(array(             // Ignore folders             'by_type' => new DirItemFilterer_by_type(false),             // Ensure files are greater than 50 Mb             'by_size' => new DirItemFilterer_by_size('50M''>'),             // _VIDEO_ is a pre-defined set of file extensions             'by_ext'  => new DirItemFilterer_by_extension('_VIDEO_'),             // Filenames are matched by regular expressions             'by_name' => new DirItemFilterer_by_filename('big.+bang.+theory')         )));     } }

An other ex­am­ple moves all fold­ers which con­tain less than 3 Mb of files into a .Trash folder. Many tor­rents have cover pho­tos, readmes or sam­ple videos, and these may be left be­hind when the main files have been moved to some­where else. It is clear that by lever­ag­ing the 250 lines of PHP util­ity classes, it is triv­ial to de­fine new au­to­matic tasks.

    class DirItemCommand_move_small_folders extends DirItemCommand_move_files {     public function getTargetPath($info)     {         // Need to use substr because paths start with ./         return '.Trash/' substr($info['path'], 2);     }          public function __construct()     {         parent::__construct(new DirItemFilterCollection(array(             // Match only folders             'by_type' => new DirItemFilterer_by_type(true),             // Process those which are smaller than 3 Mb             'by_size' => new DirItemFilterer_by_size('3M''<')         )));     } }

It is an in­ter­est­ing heuris­tic that usu­ally movies have their re­lease year listed in their file name. I'm us­ing this to au­to­mat­ically iden­tify and move movie files to the cor­rect stor­age folder. Thanks to reg­ular ex­pres­sions, also this task is very easy to im­ple­ment.

    class DirItemCommand_move_files_movies extends DirItemCommand_move_files {     public function getTargetPath($info)     {         return 'C:/Share/long_movies/' $info['fname'];     }          public function __construct()     {         parent::__construct(new DirItemFilterCollection(array(             'by_type' => new DirItemFilterer_by_type(false),             'by_size' => new DirItemFilterer_by_size('600M''>'),             'by_ext'  => new DirItemFilterer_by_extension('_VIDEO_'),             // Use regular expressions to match years from 1900 to 2099             'by_name' => new DirItemFilterer_by_filename('[^0-9](19|20)[0-9]{2}[^0-9]')         )));     } }

Related blog posts: