&1 | tee -a /tmp/yuba/debug.log"; } else { $redirect = "2>> ".$error_log_file; } $tmpdir = "/tmp/yuba/".$mytime; if (!is_dir($tmpdir)) { mkdir($tmpdir,0777,true); dfm("mkdir ",$tmpdir); } // Main DB $dbo = new PDO("sqlite:".$bpath."/".$stamp.".sqlite3"); $dbo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $dbo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $dbo->query("PRAGMA page_size = 4096"); $dbo->query("PRAGMA cache_size = 10000"); $dbo->query("PRAGMA synchronous = NORMAL"); $dbo->query("PRAGMA locking_mode = NORMAL"); $dbo->query("PRAGMA journal_mode = WAL"); // Pool DB $dbp = new PDO("sqlite:".$bpath."/pool.sqlite3"); $dbp->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $dbp->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $dbp->query("PRAGMA page_size = 4096"); $dbp->query("PRAGMA cache_size = 10000"); $dbp->query("PRAGMA synchronous = NORMAL"); $dbo->query("PRAGMA locking_mode = NORMAL"); $dbp->query("PRAGMA journal_mode = WAL"); $sbatch = array(); $estring = "\n[BATCH] ".shortlabel(basename($pathname),20); dfm("BATCH INIT ".$file.":".print_r($argv,true),2); // Thumbs ////////////////////////////////////////// thumbs: if ($p['thumbs'] && $ext && $ext != "DS_Store") { dfm("THUMBS",1); $estring .= " THUMBS"; // "bad" filesizes from generic audio file icons $discard = array( 3953, 4977, 5019, 7133, 6059, 6616, 17393 ); $tfile = $tmpdir."/thumbs/".substr($fid,0,2)."/".$fid.".jpg"; $tpfile = $tmpdir."/thumbs/".substr($fid,0,2)."/".$file.".png"; // workaround for qlmanage naming convention $dfile = $bpath."/thumbs/".substr($fid, 0, 2)."/".$fid.".jpg";; if (!is_dir(dirname($tfile))) { @mkdir(dirname($tfile),0777,true); dfm("mkdir ".dirname($tfile)); } if ($ext == "DS_Store") { // file extension is in the skip list $estring .= " ->t_skip"; dfm("skipping ds_store"); goto icons; } if ($p['thumbs'] == 1 && file_exists($dfile)) { // if this is not a rebuild, first check for an existing thumb file (faster) dfm("this is not a rebuild, and an existing thumb file was found"); $estring .= " ->skip_fast"; goto icons; } // check for existing thumb generation attempt $sql = "SELECT rowid FROM thumbs WHERE fid='".$fid."'"; dfm($sql); $rowid = @$dbp->query($sql)->fetch()['rowid']; if (!$rowid) { // no prior attempt dfm("no prior attempt at thumb file generation was made for ".$fid); $stmt = $dbp->prepare("INSERT INTO thumbs VALUES (:fid, :created, :relative_path, :width, :height, :tool)"); dfm("mysql insert for thumb generation attempt"); $estring .= " ->generate"; } elseif ($rowid && $p['thumbs'] == 2) { // prior attempt but rebuild mode $stmt = $dbp->prepare("UPDATE thumbs SET fid = :fid, created = :created, relative_path = :relative_path, width = :width, height = :height, tool = :tool WHERE rowid = ".$rowid); dfm("mysql update for rebuild"); $estring .= " ->rebuild"; } else { // prior attempt dfm("a prior attempt at thumb generation was found for ".$fid); $estring .= " ->pskip"; goto icons; } $cmd['sips'] = $bin_sips." -s format jpeg -s formatOptions 80 --resampleHeightWidthMax ".$p['thumb_size']." ".$shellpath." --out ".$tfile; // add ?? "-d profile --deleteColorManagementProperties" $cmd['vips'] = $bin_vips." ".$shellpath." -o ".$tfile."[Q=90,optimize_coding] --size=".$p['thumb_size']; $cmd['sox'] = $bin_sox." ".$shellpath." -n trim 0 $(".$bin_exiftool." -s -s -s -duration# ".$shellpath." | awk '{print $1/4}') spectrogram -r -o - | ".$bin_convert." - -quality 85% ".$tfile; $cmd['ffmpeg'] = $bin_ffmpeg." -ss $(( $(".$bin_mediainfo." --Inform='Video;%Duration%' ".$shellpath." | cut -d'.' -f1) / 10000 )) -i ".$shellpath." -vframes 1 -filter:v scale='".$p['thumb_size'].":-1' -q:v 3 ".$tfile; $cmd['ql-thumbnail'] = $bin_qlthumb." ".$shellpath." ".$tfile." public.jpeg ".$p['thumb_size']." ".$p['thumb_size']." .8"; $cmd['qlmanage'] = $bin_qlmanage." -t -s ".$p['thumb_size']." -o ".dirname($tpfile)." ".$shellpath."; ".$bin_sips." -s format jpeg -s formatOptions 80 ".escapeshellarg($tpfile)." --out ".$tfile; $cmd['qltool'] = $bin_qltool." dp ".$shellpath." ".$p['thumb_size']." ".$p['thumb_size']." | base64 --decode | ".$bin_convert." - -scale 50% ".$tfile; switch ($p['thumb_mode']) { case 0: // most files if (!empty($p['t_b'][$extl])) { $priority = $p['t_b'][$extl]; } else { $priority = $p['t_b']['*']; } break; case 1: // some files if (!empty($p['t_b'][$extl]) && !in_array($p['t_b']['*'],$p['t_b'][$extl])) { $priority = $p['t_b']['*']; } else { $priority = null; } break; } dfm("thumb mode ".$p['thumb_mode']); dfm("priority for ".$extl." is: ".print_r($priority,true)); $stmt->BindValue(":fid",$fid); $stmt->BindValue(":created",time()); if (!is_array($priority)) { $priority = array($priority); } foreach ($priority as $tool) { if (empty($cmd[$tool])) { continue; } dfm($cmd[$tool]); shell_exec("( ".$cmd[$tool]." ) ".$redirect); $estring .= " ->".$tool; $checksize = @filesize($tfile); if ($checksize) { if (in_array($checksize,$discard)) { $estring .= " ->bdiscard"; dfm($checksize." is in the banned size array"); } else { $estring .= " ->use"; dfm ("generated ".$tfile." filesize is ".$checksize); $stmt->BindValue(":tool",$tool); $stmt->BindValue(":relative_path",substr($dfile, strlen($bpath))); dfm("getimagesize on ".$tfile); list($width, $height) = getimagesize($tfile); $stmt->BindValue(":width",$width); $stmt->BindValue(":height",$height); if (!is_dir(dirname($dfile))) { @mkdir(dirname($dfile)); dfm("mkdir ".dirname($dfile)); } rename($tfile,$dfile); dfm("moving ".$tfile." to ".$dfile); break; } } else { $estring .= " ->discard"; dfm($tool." did not produce a file"); } } $sbatch[] = $stmt; $estring .= " ->db"; } // Icons ////////////////////////////////////////// icons: if ($p['icons'] && $ext != "DS_Store") { dfm("ICONS",1); $estring .= " ICONS"; if ($p['icon_mode'] != 0 && in_array($extl, $p['i_skip'])) { $estring .= " ->i_skip"; dfm("file extension is in the skip list"); goto meta; } $tfile = $tmpdir."/icons/".substr($fid,0,2)."/".$fid.".png"; if (!is_dir(dirname($tfile))) { @mkdir(dirname($tfile),0777,true); dfm("mkdir ".dirname($tfile)); } // we can't check for files (faster) here because they are stored by md5_file hash $sql = "SELECT rowid FROM icons WHERE fid='".$fid."'"; dfm($sql); $rowid = @$dbp->query($sql)->fetch()['rowid']; if (!$rowid) { dfm("no prior attempt was found"); $stmt = $dbp->prepare("INSERT INTO icons VALUES (:fid, :hash, :created, :relative_path, :tool)"); } elseif ($rowid && $p['icons'] == 2) { dfm("a prior attempt was found but we are in rebuild mode"); $stmt = $dbp->prepare("UPDATE icons SET fid = :fid, hash = :hash, created = :created, relative_path = :relative_path, tool = :tool WHERE rowid = ".$rowid); $estring .= " ->rebuild"; } else { dfm("a prior attempt was found, skipping"); $estring .= " ->pskip"; goto meta; } $cmd['flacicon'] = $bin_flacicon." ".$shellpath." ".$p['icon_size']." ".$tfile; $cmd['ql-icon'] = $bin_qlicon." --input=".$shellpath." --width=".$p['icon_size']." --height=".$p['icon_size']." | ".$bin_pngquant." - -o ".$tfile; $cmd['iff'] = $bin_iff." --input=".$shellpath." --width=".($p['icon_size']/2)." --height=".($p['icon_size']/2)." | ".$bin_pngquant." - -o ".$tfile; $cmd['qltool'] = $bin_qltool." di ".$shellpath." ".$p['icon_size']." ".$p['icon_size']." | base64 --decode | ".$bin_convert." - -scale 50% - | ".$bin_pngquant." - -o ".$tfile; if ($p['icon_mode'] == 2) { dfm("icon mode 2, bypassing hash check"); $tool = "ql-icon"; shell_exec("( ".$cmd[$tool]." ) ".$redirect); $stmt->BindValue(":tool",$tool); dfm($cmd[$tool]); $estring .= " ->".$tool; $checksize = @filesize($tfile); if ($checksize) { dfm("generated ".$tfile." filesize is ".$checksize); $dfile = $bpath."/icons/".substr($fid, 0, 2)."/".$fid.".png"; if (!is_dir(dirname($dfile))) { @mkdir(dirname($dfile)); } rename($tfile,$dfile); dfm("moving ".$tfile." to ".$dfile); $stmt->BindValue(":created",time()); $stmt->BindValue(":relative_path",substr($dfile,strlen($bpath))); $stmt->BindValue(":hash",null); $estring .= " ->use"; } else { $estring .= " ->discard"; dfm($tool." produced a bad file (size=".$checksize.")"); } } else { $gfind = array("[","]","{","}"); $greplace = array("\[","\]","\{","\}"); $globsafe = str_replace($gfind,$greplace,$pathname); if ($btype == "dir") { dfm($pathname." is a dir, proceeding with directory check"); $stmt->BindValue(":fid",$fid); if ($ext || file_exists($pathname."/Icon\r")) { dfm("Ext or custom icon found, processing ".$pathname." with iff"); $tools = array("iff"); } elseif (glob($globsafe."/".globstring($p['album_files']),GLOB_BRACE) && $test = glob($globsafe."/".globstring($p['cover_exts'],$p['cover_files']),GLOB_BRACE)) { dfm("Album files and cover found, processing ".$pathname." with flacdiricon"); $cmd['flacdiricon'] = $bin_flacdiricon." ".$shellpath." ".$p['icon_size']." ".escapeshellarg(array_shift($test))." ".$tfile; $tools = array("flacdiricon"); } else { dfm("glob ".$pathname."/".globstring($p['album_files'])); dfm("glob ".$pathname."/".globstring($p['cover_exts'],$p['cover_files'])); dfm("Nothing found, skipping ".$pathname); $tools = array(); } } else { $stmt->BindValue(":fid",$fid); if (in_array($extl, $p['i_sox'])) { $tools = array("flacicon","ql-icon","iff"); } else { $tools = array("ql-icon","iff"); } } $mytool = ""; foreach ($tools as $tool) { if (!@filesize($tfile)) { shell_exec("( ".$cmd[$tool]." ) ".$redirect); dfm($cmd[$tool]); $estring .= " ->".$tool; $mytool = $tool; } } $checksize = @filesize($tfile); if ($checksize) { dfm ("generated ".$tfile." filesize is ".$checksize); dfm("md5_file on ".$tfile); $hash = md5_file($tfile); $stmt->BindValue(":hash",$hash); $sql = "SELECT * FROM icons WHERE hash='".$hash."'"; dfm($sql); $row = @$dbp->query($sql)->fetchAll()[0]; if ($row) { dfm("found another record with the same hash"); $estring .= " ->recycle"; $stmt->BindValue(":created",$row['created']); $stmt->BindValue(":relative_path",$row['relative_path']); $stmt->BindValue(":tool",$row['tool']); } else { dfm("no existing hash record"); $dfile = $bpath."/icons/".substr($hash, 0, 2)."/".$hash.".png"; if (!is_dir(dirname($dfile))) { @mkdir(dirname($dfile)); } rename($tfile,$dfile); dfm("moving ".$tfile." to ".$dfile); $stmt->BindValue(":created",time()); $stmt->BindValue(":relative_path",substr($dfile,strlen($bpath))); $stmt->BindValue(":tool",$mytool); $estring .= " ->use"; } } else { if (empty($tools)) { $estring .= " ->gskip"; } else { $estring .= " ->discard"; } dfm("tool = ".$mytool." produced a bad file (size=".$checksize.")"); } } $sbatch[] = $stmt; $estring .= " ->db"; } // Metadata ////////////////////////////////////////// meta: if ($p['meta'] && $btype == "file" && $ext != "DS_Store") { dfm("META",1); $estring .= " META"; if (!in_array($extl, $p['e_files']) && !in_array($extl, $p['m_files'])) { $estring .= " ->notmedia"; dfm("file extension ".$extl." is not a media file"); goto hashy; } if (in_array($extl, $p['e_files'])) { $sql = "SELECT EXISTS(SELECT 1 FROM exiftool WHERE fid='".$fid."')"; dfm($sql); $check = @$dbp->query($sql)->fetch(); if (!reset($check)) { dfm("creating exiftool dump"); $cmd = $bin_exiftool." -php ".$shellpath; dfm($cmd); $arrstring = shell_exec($cmd); if (substr($arrstring,0,5) == "Array") { $rawexif = eval("return ".$arrstring); $stmt = $dbp->prepare("INSERT INTO exiftool VALUES (:fid, :tags)"); $stmt->BindValue(":fid",$fid); $stmt->BindValue(":tags",serialize($rawexif[0])); $sbatch[] = $stmt; $estring .= " ->etool"; } } else { $estring .= " ->e_found"; dfm("existing exiftool dump found"); } } if (in_array($extl, $p['m_files'])) { $sql = "SELECT EXISTS(SELECT 1 FROM mediainfo WHERE fid='".$fid."')"; dfm($sql); $check = @$dbp->query($sql)->fetch(); if (!reset($check)) { dfm("creating mediainfo dump"); $stmt = $dbp->prepare("INSERT INTO mediainfo VALUES (:fid, :info)"); $stmt->BindValue(":fid",$fid); $stmt->BindValue(":info",shell_exec("( ".$bin_mediainfo." --Output=JSON ".$shellpath." ) ".$redirect)); $sbatch[] = $stmt; $estring .= " ->minfo"; } else { $estring .= " ->m_found"; dfm("existing mediainfo dump found"); } } } // Hash ////////////////////////////////////////// hashy: if ($p['hash'] && $btype == "file" && $ext != ".DS_Store") { dfm("HASH",1); $estring .= " HASH"; $size = filesize($pathname); dfm("file ".$pathname." is ".$size); $limit = $p['hash_limit']*1000000000; $sql = "SELECT EXISTS(SELECT 1 FROM md5 WHERE fid='".$fid."')"; dfm($sql); $check = @$dbp->query($sql)->fetch(); if (reset($check)) { $estring .= " ->exists"; dfm("hash already exists for ".$pathname); } elseif ($p['hash_limit'] && ($size > $limit)) { $estring .= " ->too big"; dfm("file is too big to hash"); } else { $estring .= " ->generating"; dfm("generating hash for ".$pathname); $stmt = $dbp->prepare("INSERT INTO md5 VALUES (:fid, :hash)"); $stmt->BindValue(":fid",$fid); $stmt->BindValue(":hash",md5_file($pathname)); $sbatch[] = $stmt; } $estring .= " ->done"; } // Contents ////////////////////////////////////////// contents: if ($p['contents'] && $btype == "file") { dfm("CONTENTS",1); $estring .= " CONTENTS"; $cpath = $bpath."/contents/".substr($fid, 0, 2); $cfile = $cpath."/".$fid.".zip"; if (in_array($extl, $p['c_files'])) { $max_size = $p['contents_limit'] * 1000; if ($ext == ".DS_Store") { // store all DS_Store files no matter how big dfm("flagging ds_store file for inclusion"); $my_size = 1; } else { $my_size = filesize($pathname); dfm("file ".$pathname." is ".$my_size); } if (!file_exists($cfile) && $my_size < $max_size) { if (!is_dir($cpath)) { mkdir($cpath); dfm("mkdir ",$cpath); } $estring .= " ->zip"; dfm("creating a zip archive of ".$pathname); $zip = new ZipArchive(); $zip->open($cfile, ZipArchive::CREATE); $zip->addfile($pathname,basename($pathname)); $zip->close(); $stmt = $dbp->prepare("INSERT INTO contents VALUES (:fid, :created, :relative_path)"); $stmt->BindValue(":fid",$fid); $stmt->BindValue(":created",time()); $stmt->BindValue(":relative_path",substr($cfile, strlen($bpath))); $sbatch[] = $stmt; } } } // Spotlight ////////////////////////////////////////// if (@$argv[8]) { dfm("SPOTLIGHT",1); $estring .= " SPOTLIGHT"; $cmd = "mdls -plist - ".$shellpath." ".$redirect; dfm($cmd); $mdls = shell_exec($cmd); if (substr_count(@$mdls,"\n") > 1) { $spotlight = $parser->parseString(utf8_for_xml($mdls)); } else { $spotlight = array(); } $stmt = $dbo->prepare("INSERT INTO mdls VALUES (:id,".implode(",",$ibuild).")"); $stmt->BindValue(":id",$bdone+1); foreach ($mb as $key => $list) { foreach ($list as $item) { if (@$spotlight["kMDItem".$item]) { $stmt->BindValue(":pid",$pid); $stmt->BindValue(":spotlight",$mdls); switch($key) { case "i": case "t": $stmt->BindValue(":".$item,$spotlight["kMDItem".$item]); break; case "a": $stmt->BindValue(":".$item,serialize($spotlight["kMDItem".$item])); break; case "d": $stmt->BindValue(":".$item,strtotime($spotlight["kMDItem".$item])); break; } } } } $estring .= " ->db"; $stmt->execute(); } // Inserts ////////////////////////////////////////// dfm("SQL",1); foreach ($sbatch as $stmt) { $stmt->execute(); dfm($stmt->queryString); } dm($dm); echo msg($estring,false); echo "\n"."PROGRESS:".round(($bdone/$btotal)*100,2)."\n"; ?>