Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- # Synology Media Backup Script
- # V0.1 - www.verhees.be
- class CopyTo {
- var $userdir = "son"; # user who takes the pictures
- var $delete_source_after = "4 months"; # deletes files in bulk directory after ... X months
- var $src = "/volume1/backup son"; # source directory (bulk directory of media)
- var $dst = "/volume1/pictures"; # root directory of destination directory
- var $bck = "/volume1/crons/backup"; # dir for archiving before deletion
- var $err = "/volume1/crons/backup/errors"; # dir for storing files with different MD5's
- var $lgs = "/volume1/crons"; # dir for logs
- # more stuff you don't touch ...
- var $arr_ext = array('jpg', 'jpeg', 'mp4', 'moov', 'mov', '3gp', 'avi');
- var $arr_months = array(1 => 'Januari', 2 => 'Februari', 3 => 'Maart', 4 => 'April', 5 => 'Mei', 6 => 'Juni', 7 => 'Juli', 8 => 'Augustus', 9 => 'September', 10 => 'Oktober', 11 => 'November', 12 => 'December');
- var $arr_msgs = array("cnt_dirs_new" => 0, "cnt_files_copy" => 0, "files_warning" => array());
- var $log = "";
- public function CopyTo() {
- $this->log = "\n\n[START] - CopyTo Log : ".date("d-m-Y h:i:s");
- $this->check_folders();
- $this->recurse_copy();
- $this->log .= "\n[STOP] - CopyTo Log : ".date("d-m-Y h:i:s");
- $this->dump_log();
- }
- private function check_folders() {
- if(!file_exists($this->src) && !is_dir($this->src)) {
- $this->log .= "\n[ERROR] source directory doesn't exists : ".$this->src;
- }
- if(!file_exists($this->dst) && !is_dir($this->dst)) {
- $this->log .= "\n[ERROR] destination directory doesn't exists : ".$this->dst;
- }
- }
- public function recurse_copy() {
- $src = opendir($this->src);
- $ignore = array('.', '..');
- $cnt_files = 0;
- while(false !== ($file = @readdir($src)) ) {
- if (!in_array($file, $ignore, TRUE)) {
- $cnt_files++;
- # first check the extension if it's safe/supported by the script
- $ext = $this->check_file_extension($file);
- if ($ext != false) {
- $filedata = $this->get_file_meta($this->src . '/' . $file, $ext);
- # check if datetime stamp of file is present for the right destination directory
- if (is_array($filedata)) {
- $file_dst_dir = $this->dst.'/'.$filedata['dateyear'].'-'.$filedata['datemonth'].' '.$this->arr_months[(int)$filedata['datemonth']];
- # check if destination directory exists else create it (cfr. /2015-01 Januari/ )
- $this->check_or_make_dir($file_dst_dir);
- # check if destination USER directory exists else create it (cfr. /2015-01 Januari/tim/ )
- $file_dst_dir = $file_dst_dir.'/'.$this->userdir;
- $this->check_or_make_dir($file_dst_dir);
- # check if destination file already exists if so generate an unique filename
- $filename_double = "";
- $filename_double = $this->check_md5($file, $ext, $file_dst_dir);
- $destination_filename = $file; # ($filename_double ? $filename_double : $file);
- if ($filename_double != false) {
- $this->add_log($file_dst_dir. '/' . $destination_filename, 'copy');
- copy($this->src . '/' . $file, $file_dst_dir . '/' . $destination_filename);
- }else{
- $this->add_log(".. skipped ", 'i');
- }
- # check consistency of source and destination (md5 check) if ok delete the source
- if ($this->analyse_copy($this->src.'/'.$file, $file_dst_dir.'/'.$destination_filename, $filedata, $this->get_file_meta($file_dst_dir. '/'.$destination_filename, $ext)) == false) {
- $this->add_log("consistency error ".$file_dst_dir. '/' . $destination_filename, 'e');
- }else{
- # check if the file is ready to be deleted or to be preserved.
- if ($this->check_ready_to_delete($filedata) == true) {
- $user_backup_dir = $this->bck.'/'.$this->userdir;
- $this->check_or_make_dir($user_backup_dir);
- if (copy($this->src.'/'.$file, $user_backup_dir.'/'.$file)) {
- $this->add_log("archived before deletion from source : ".$this->src . '/' . $file.' [>>] '.$user_backup_dir, 'copy');
- }
- unlink($this->src.'/'.$file);
- $this->add_log("deleted from source (was saved on ".date("Y-m-d h:i:s", $filedata['datetime_saved']).") : ".$this->src . '/' . $file, 'i');
- }
- }
- }else{
- $this->add_log("no filedata available for file".$file, 'i');
- }
- }
- }
- }
- closedir($src);
- }
- private function check_or_make_dir($dir) {
- if (!@opendir($dir)) {
- try {
- mkdir($dir);
- $this->add_log("new directory created : ".$dir, 'i');
- } catch(Exception $e) {
- $this->add_log("failed to create the destination directory ".$dir, 'e');
- $this->dump_log();
- }
- }
- }
- # check if the time window (to preserve deletion in the source directory) has expired
- private function check_ready_to_delete($original_filedata) {
- if ($this->delete_source_after) {
- if (($original_filedata['datetime_saved'] < (time() - (time() - strtotime('-'.$this->delete_source_after, time()))))) {
- return true;
- }
- }
- return false;
- }
- private function check_md5($file, $ext, $file_dst_dir) {
- if (file_exists($file_dst_dir . '/' . $file)) {
- $this->add_log("file already exists in destination ".$file_dst_dir. '/' . $file, 'w');
- # check if files are same md5 if not generate unique filename and copy.
- if (md5_file($this->src.'/'.$file) != md5_file($file_dst_dir.'/'.$file)) {
- $this->add_log("file already exists but different MD5 ", 'e');
- $this->check_or_make_dir($this->err);
- if (copy($this->src.'/'.$file, $this->err.'/'.$file)) {
- $this->add_log("archived in errors before deletion from source : ".$this->src . '/' . $file.' [>>] '.$this->err.'/'.$file, 'copy');
- }else{
- $this->add_log("failed to archive in errors before deletion from source : ".$this->src . '/' . $file.' [>>] '.$this->err.'/'.$file, 'error');
- }
- #return $this->generate_unique_filename($file, $ext, $file_dst_dir);
- }else{
- $this->add_log("file already exists but same MD5 ", 'i');
- return false;
- }
- }else{
- return $file;
- }
- }
- private function analyse_copy($source_filename, $destination_filename, $source_filedata, $destination_filedata) {
- if (md5_file($source_filename) === md5_file($destination_filename)) {
- return true;
- }
- return false;
- }
- /*
- private function analyse_copy($source_filename, $destination_filename, $source_filedata, $destination_filedata) {
- $cnt_values = count($source_filedata);
- $i = 0;
- # first check if the technical values are the same
- foreach($source_filedata as $key => $value) {
- if ($value === $destination_filedata[$key]) {
- $i++;
- }
- }
- # if so check the md5 checksum
- if ($i === $cnt_values) {
- if (md5_file($source_filename) === md5_file($destination_filename)) {
- return true;
- }
- }
- return false;
- }
- private function generate_unique_filename($file, $ext, $dir) {
- $increment = 1; //start with no suffix
- $file_info = pathinfo($file);
- while(file_exists($dir."/".$file_info['filename']."_(copy)_".$increment.'.'. $ext)) {
- $increment++;
- }
- return $file_info['filename']."_(copy)_".$increment.'.'. $ext;
- } */
- private function get_file_meta($file, $ext) {
- $data = $arr_stamps = array();
- if ($file) {
- switch(strtolower($ext)) {
- # pictures
- case 'jpg': case 'jpeg': # case 'dng': case 'gif': case 'bmp': case 'tiff': case 'png':
- try {
- $exif_data = exif_read_data($file);
- $arr_stamps['date_modified_unix'] = (@$this->get_date_modified($file) ? (int)$this->get_date_modified($file) : '');
- $arr_stamps['date_created_unix'] = (@$this->get_date_created($file) ? (int)$this->get_date_created($file) : '');
- $arr_stamps['date_original_meta'] = (is_object($exif_data['DateTimeOriginal']) && (int)$exif_data['DateTimeOriginal']->getTimestamp() > 0 ? (int)$exif_data['DateTimeOriginal']->getTimestamp() : '');
- $arr_stamps['date_meta'] = ((int)$exif_data["FileDateTime"] > 0 ? (int)$exif_data["FileDateTime"] : '');
- $arr_stamps['date_from_filename'] = (int)$this->get_date_from_filename($file);
- $arr_stamps = array_filter($arr_stamps);
- $date_created = min($arr_stamps);
- $data = array(
- 'datetime_saved' => $date_created,
- 'datetime' => $date_created,
- 'dateyear' => date("Y", $date_created),
- 'datemonth' => date("m", $date_created),
- 'mimetype' => $exif_data['MimeType'],
- 'height' => $exif_data['COMPUTED']['Height'],
- 'width' => $exif_data['COMPUTED']['Width'],
- 'filesize' => $exif_data['FileSize'],
- );
- } catch(Exception $e) {
- $this->add_log("failed to read PICTURE EXIF meta data from file ".$file." / ".$e->getMessage(), "e");
- }
- break;
- case 'mp4': case 'moov': case 'mov': case '3gp':
- include_once("/volume1/crons/getid3/getid3.php");
- try {
- $id3 = new getID3();
- $arr_vid = $id3->analyze($file);
- $arr_stamps['date_modified_unix'] = (@$this->get_date_modified($file) ? (int)$this->get_date_modified($file) : '');
- $arr_stamps['date_created_unix'] = (@$this->get_date_created($file) ? (int)$this->get_date_created($file) : '');
- $arr_stamps['date_original_meta'] = ($arr_vid['quicktime']['moov']['subatoms'][0]['creation_time_unix'] ? $arr_vid['quicktime']['moov']['subatoms'][0]['creation_time_unix'] : '');
- $arr_stamps = array_filter($arr_stamps);
- $date_created = min($arr_stamps);
- $data = array(
- 'datetime_saved' => $date_created,
- 'datetime' => $date_created,
- 'dateyear' => date("Y", $date_created),
- 'datemonth' => date("m", $date_created),
- 'mimetype' => $arr_vid['mime_type'],
- 'height' => $arr_vid['video']['resolution_y'],
- 'width' => $arr_vid['video']['resolution_x'],
- 'filesize' => $arr_vid['filesize'],
- );
- } catch (Exception $e) {
- $this->add_log("failed to read VIDEO meta data from file ".$file." / ".$e->getMessage(), "e");
- }
- break;
- # videos
- /*case 'avi': case 'avchd': case 'aaf': case 'mpeg': case 'mpg': case 'mpe': case 'm4v': case 'mp4': case 'flv':
- break;*/
- /*
- # sound
- case 'mp3': case 'm4a': case 'wma': case 'mp4': case 'aac': case 'mkv':
- break;
- # documents
- case 'pdf':
- break;
- # adobe
- case 'psd':
- break;
- */
- }
- }
- return $data;
- }
- private function validate_date($date) {
- $d = DateTime::createFromFormat('Ymd', $date);
- return $d && $d->format('Ymd') == $date;
- }
- private function get_date_modified($file) {
- return filemtime($file);
- }
- private function get_date_created($file) {
- return filectime($file);
- }
- private function get_date_from_filename($file) {
- $file = basename($file);
- $re = '/(\d{8})|([0-9]{4}-[0-9]{2}-[0-9]{2})|([0-9]{2}-[0-9]{2}-[0-9]{4})/';
- preg_match($re, $file, $matches);
- if ($matches[0] > 0 && $this->validate_date($matches[0])) {
- return strtotime($matches[0]);
- }
- return '';
- }
- private function check_file_extension($file) {
- if (in_array($ext = pathinfo($this->src. '/' .strtolower($file), PATHINFO_EXTENSION), $this->arr_ext)) {
- return $ext;
- }else{
- $this->add_log("extension not valid : ". $file, "w");
- array_push($this->arr_msgs['files_warning'], $file);
- }
- return false;
- }
- private function add_log($msg, $type = "") {
- switch($type) {
- case 'copy' : $type = " [COPY] "; break;
- case 'w' : $type = "(!) [WARNING] "; break;
- case 'e' : $type = "(!!!) [ERROR]"; break;
- case 'i' : $type = " [INFO] "; break;
- default:
- $type = "";
- }
- $this->log .= "\n".$type." : ".date("d-m-Y h:s")." - ".$msg;
- }
- private function dump_log() {
- #echo "writing log ...";
- if (count($this->arr_msgs['files_warning']) > 0)
- $this->log .= "\n===============================================\n"."WARNINGS:\n".implode($this->arr_msgs['files_warning'], "\n")."\n===============================================";
- file_put_contents($this->lgs.'/log_'.date("Ynj").'_'.$this->userdir.'_copyto.txt', $this->log, FILE_APPEND);
- exit;
- }
- }
- $copyto = new CopyTo();
- ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement