Skip to content

Instantly share code, notes, and snippets.

@cdevroe
Last active April 13, 2020 17:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cdevroe/c746c1dbdc9ddea44ae43e06dea0c99b to your computer and use it in GitHub Desktop.
Save cdevroe/c746c1dbdc9ddea44ae43e06dea0c99b to your computer and use it in GitHub Desktop.
Look at files in a directory, move them into new directories based on Date Created
<?php
/*
Created by Colin Devroe
cdevroe.com
*/
// Help
if ( isset($argv[1]) && ($argv[1] == '-h' || $argv[1] == '-help') ) :
print 'Colin\'s Photo Backup Utility' . "\n";
print '===========================================' . "\n";
print 'This script copies files into new' . "\n";
print 'directories based on their created date.' . "\n";
print '-------------------------------------------' . "\n";
print "\n";
print 'To use:' . "\n";
print 'php move.php Location true/false' . "\n";
print "\n";
print 'Locations:' . "\n";
print '- OneDrive' . "\n";
print '- Backup' . "\n";
print '- Mobile' . "\n";
print "\n";
print 'false flag will run "test" (default)' . "\n";
print 'true flag will actually copy files' . "\n";
print "\n";
exit;
endif;
// Arguments
$confirmed = (isset($argv[2]) && $argv[2] == 'true') ? $argv[2] : false; // true = actually do work, false is a test
$location_to_move_to = (isset($argv[1])) ? $argv[1] : 'OneDrive';
// Locations
$locations = [];
$locations['OneDrive'] = '/Users/cdevroe/OneDrive/Photo Archive';
$locations['Backup'] = '/Volumes/Zoar/Carbonite Photo Storage';
$locations['Mobile'] = '/Volumes/Wade Watts/Photo Archive';
// Setup
$directory_of_files = '/Users/cdevroe/Sites/photo_scripts/move';
$directory_of_moved_files = $locations[$location_to_move_to];
$filename_prefix_for_duplicates = 'duplicate_';
$number_of_files_moved = 0;
$number_of_directories_created = 0;
$number_of_possible_duplicates = 0;
$files_to_move = getAllFilesIn( $directory_of_files );
/*
Loop through all files
If not a directory or weird file:
- Determine what the Created Date is
- Create directories based on the Created Date YYYY/MM/DD
- Copy the file into the appropriate directory
- Iterate count
*/
foreach ( $files_to_move as $file ):
$file_date_created = filemtime( $file );
$directory_to_create = $directory_of_moved_files . DIRECTORY_SEPARATOR . date( "Y/m/d", $file_date_created );
if ( !file_exists( $directory_to_create ) ) :
if ( $confirmed ) :
mkdir( $directory_to_create, 0777, true );
endif;
$number_of_directories_created++;
endif;
if ( !file_exists( $directory_to_create . DIRECTORY_SEPARATOR . basename($file) ) ) :
if ( $confirmed ) :
copy( $file, $directory_to_create . DIRECTORY_SEPARATOR . basename($file));
endif;
$number_of_files_moved++;
else :
if ( $confirmed ) :
copy( $file, $directory_to_create . DIRECTORY_SEPARATOR . $filename_prefix_for_duplicates . basename($file));
endif;
$number_of_possible_duplicates++;
endif;
endforeach;
if ( $confirmed ) :
print "$number_of_directories_created directories created and $number_of_files_moved files moved. $number_of_possible_duplicates were marked as possible duplicates.";
else :
print "$number_of_directories_created directories would have been created and $number_of_files_moved files would have been moved. $number_of_possible_duplicates would be marked as possible duplicates.";
endif;
// Function to get all files within a directory and its subdirectories.
function getAllFilesIn( $path = '', &$name = array() ) {
$path = $path == '' ? dirname(__FILE__) : $path;
$lists = @scandir($path);
if ( !empty($lists) ) :
foreach ( $lists as $f ) :
if ( is_dir( $path.DIRECTORY_SEPARATOR.$f ) && $f == $directory_of_moved_files ) { continue; }
if ( is_dir( $path.DIRECTORY_SEPARATOR.$f ) && $f != ".." && $f != "." && $f != ".DS_Store" ) :
getAllFilesIn( $path.DIRECTORY_SEPARATOR.$f, $name );
else :
if( $f != ".." && $f != "." && $f != ".DS_Store" ) :
$name[] = $path.DIRECTORY_SEPARATOR.$f;
endif;
endif;
endforeach;
endif;
return $name;
}
?>
@ibuys
Copy link

ibuys commented Apr 6, 2020

Works well, but be aware that this script will strip any Finder tags from the files. There might be a way to preserve extended attributes during a copy in PHP, but I don't have the time to find it at the moment.

@cdevroe
Copy link
Author

cdevroe commented Apr 6, 2020

@ibuys Thanks for the warning. I do not personally use Finder tags but I'm glad to know this.

@cdevroe
Copy link
Author

cdevroe commented Apr 9, 2020

@ibuys One reason this happens is that I'm using copy(). Perhaps I'll switch this script to mv.

@cdevroe
Copy link
Author

cdevroe commented Apr 13, 2020

I've now updated the script to:

  • Accept argument for locations - This way I can send files to OneDrive or my two backup hard disks.
  • Argument to "confirm" - If you do not use a second argument of "true" the script will only run a "mock" run.
  • Added help information - simply run -help (this is mainly so that I don't forget and have to read the script)

I'd like to make this new stuff a bit cleaner and easier to use from the command line in the future. So any tips are welcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment