This commit is contained in:
2018-08-08 23:12:47 -07:00
parent cbf6506290
commit ff19eeab6c
232 changed files with 319180 additions and 1246 deletions

521
Yuba.php
View File

@@ -1,41 +1,42 @@
#!/usr/bin/php
<?php
// Yuba
// //
//////////////////////////////////////////
$version = "0.6.1.2";
$version = "0.6.9";
ini_set('memory_limit', '4096M');
date_default_timezone_set("America/Los_Angeles");
$time_start = microtime(true);
include('ProgressBar.php');
// Includes & Prefs
//////////////////////////////////////////
require("functions.php");
require("filetypes.php");
$wopt_noprofile = 1;
$p = unserialize(file_get_contents("prefs.php"));
// Path & application variables
//////////////////////////////////////////
if (in_array("-nohash", $argv)) { $wopt_hash = 0; } else { $wopt_hash = 1; }
if (in_array("-nothumbs", $argv)) { $wopt_thumbs = 0; } else { $wopt_thumbs = 1; }
if (in_array("-nometa", $argv)) { $wopt_meta = 0; } else { $wopt_meta = 1; }
if (!isset($argv[1])) { echo "Input error"; die; }
$zpath = realpath(@$argv[1]);
$bdest = realpath(@$argv[2]);
if (!is_dir($zpath) | !is_dir($bdest)) { echo "Usage: walk <path> <dest>"; die; }
if (@$argv[2]) { $bdest = realpath($argv[2]); } else { $bdest = realpath($p['bdest']); }
if (!is_dir($zpath) | !is_dir($bdest)) { echo "Filepath error"; die; }
// Check for bundle
if ($zpath == "/") { $blabel = "root"; } else { $blabel = preg_replace("/[^A-Za-z0-9\.]/", "_", basename($zpath)); }
if (is_writable($zpath)) { $wopt_paranoid = 1; } else { $wopt_paranoid = 0; }
if (is_writable($zpath)) { $p['paranoid'] = 1; } else { $p['paranoid'] = 0; }
$bpath = chop($bdest,"/")."/".substr(crc32($zpath),0,3)."_".$blabel.".bundle";
if (!is_dir($bpath)) { mkdir($bpath); }
if (!is_dir($bpath."/thumbs")) { mkdir($bpath."/thumbs"); }
$wopt_hash_limit = 1; // don't hash if exceeds in gigs, 0 for unlimited
$wopt_thumb_size = "512";
// Treat these directories as files
$wopt_bundles = array( "app",
$p['bundles'] = array( "app",
"bundle",
"sparsebundle",
"photoslibrary",
@@ -49,12 +50,12 @@ $wopt_bundles = array( "app",
"rtfd"
);
foreach ($wopt_bundles as $bundle) {
$wopt_nodescend[] = "*.".$bundle;
foreach ($p['bundles'] as $bundle) {
$p['nodescend'][] = "*.".$bundle;
}
// Ignore matching files and directories
$wopt_ignore = array( ".DS_Store",
$p['ignore'] = array( ".DS_Store",
".DocumentRevisions-V100",
".Spotlight-V100",
".TemporaryItems",
@@ -65,278 +66,24 @@ $wopt_ignore = array( ".DS_Store",
".neofinder.abemeda.volinfo.xml"
);
$max_label = 50;
// Metadata tools
$bin_gfi = "/Applications/Xcode.app/Contents/Developer/usr/bin/GetFileInfo";
$bin_mediainfo = "/opt/local/bin/mediainfo";
$bin_exiftool = "/opt/local/bin/exiftool";
$bin_tq = "/opt/local/bin/ql-thumbnail-lossy";
$bin_tv = "/opt/local/bin/vipsthumbnail";
$bin_tf = "/usr/local/bin/ffmpegthumbnailer";
$bin_gfi = __DIR__."/bin/GetFileInfo";
$bin_mediainfo = __DIR__."/bin/mediainfo";
$bin_exiftool = __DIR__."/bin/exiftool";
$bin_ffmpeg = __DIR__."/bin/ffmpeg";
$bin_qlthumb = __DIR__."/bin/ql-thumbnail";
// Media extensions
// Banner
//////////////////////////////////////////
$t_files['ffmpeg'] = array( "mkv",
"avi",
"mpeg",
"mpg",
"vob",
"mp4",
"m4v",
"m2v",
"m2ts",
"asf",
"wmv",
"rm",
"divx",
"fla",
"flv",
"webm" );
$t_files['vips'] = array( "jpg",
"jpeg",
"tif",
"tiff",
"gif",
"psd",
"png" );
$m_files = array( "mkv",
"ogg",
"avi",
"wav",
"mpeg",
"mpg",
"vob",
"mp4",
"m2v",
"mp3",
"asf",
"wma",
"wmv",
"qt",
"mov",
"rm",
"ifo",
"ac3",
"dts",
"aac",
"ape",
"flac",
"aiff",
"m2ts" );
$e_files = array( "ai",
"aiff",
"ape",
"asf",
"avi",
"bmp",
"divx",
"dng",
"doc",
"docx",
"eps",
"epub",
"exe",
"exif",
"fla",
"flac",
"flv",
"gif",
"icc",
"iso",
"jpg",
"jpeg",
"m2ts",
"m4a",
"m4b",
"m4v",
"mkv",
"mobi",
"azw",
"azw3",
"mov",
"qt",
"mp3",
"mp4",
"mpeg",
"mpg",
"m2v",
"nef",
"numbers",
"ogg",
"pages",
"pdf",
"pict",
"png",
"ppm",
"ppt",
"psd",
"psb",
"qif",
"raw",
"rtf",
"sr2",
"srf",
"svg",
"swf",
"tiff",
"tif",
"torrent",
"vcf",
"vob",
"wav",
"webm",
"wma",
"wmv",
"xls",
"xlsx",
"xmp",
"zip" );
foreach ($e_files as $ext) { $e_files[] = strtoupper($ext); }
foreach ($m_files as $ext) { $m_files[] = strtoupper($ext); }
foreach ($t_files['ffmpeg'] as $ext) { $t_files['ffmpeg'][] = strtoupper($ext); }
foreach ($t_files['vips'] as $ext) { $t_files['vips'][] = strtoupper($ext); }
// Functions
//////////////////////////////////////////
/*
function getParents($zpath, $pathname) {
$path = dirname($pathname);
$parts = explode("/",trim(substr($path,strlen(basename($zpath))),"/"));
foreach ($parts as $index => $part) {
$parents[] = array($part, md5($zpath."/".implode("/",array_slice($parts, 0, $index+1))));
}
return $parents;
}
*/
function shortlabel($pathname, $max, $min = null) {
$basename = basename($pathname);
$suffix = "(...).".pathinfo($basename,PATHINFO_EXTENSION);
if (strlen($basename) > $max) {
$return = substr($basename, 0, ($max-strlen($suffix))).$suffix;
} else {
$return = $basename;
}
if (strlen($return) < $min) {
$out = $return.@str_repeat(" ", ($min-strlen($return)));
} else {
$out = $return;
}
return $out;
}
function human_filesize($bytes, $decimals = 2) {
$size = array('B','kB','MB','GB','TB','PB','EB','ZB','YB');
$factor = floor((strlen($bytes) - 1) / 3);
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$size[$factor];
}
function stringPrint($string) {
echo $string.@str_repeat(" ", (10-strlen($string)));
}
function getWoptString() {
global $wopt_bundles, $wopt_ignore, $wopt_hash, $wopt_hash_limit, $wopt_meta, $wopt_thumbs, $wopt_thumb_size, $wopt_paranoid;
return array( array("bundles", $wopt_bundles),
array("ignore", $wopt_ignore),
array("hash", $wopt_hash),
array("wopt_hash_limit", $wopt_hash_limit),
array("metadata", $wopt_meta),
array("thumbs", $wopt_thumbs),
array("thumb_size", $wopt_thumb_size),
array("wopt_paranoid", $wopt_paranoid),
);
}
class plistParser extends XMLReader {
public function parseString($string) { $this->XML($string); return $this->process(); }
private function process() {
$this->read();
if($this->nodeType !== XMLReader::DOC_TYPE || $this->name !== "plist") { throw new Exception(sprintf("Error parsing plist. nodeType: %d -- Name: %s", $this->nodeType, $this->name), 2); }
if(!$this->next("plist") || $this->nodeType !== XMLReader::ELEMENT || $this->name !== "plist") { throw new Exception(sprintf("Error parsing plist. nodeType: %d -- Name: %s", $this->nodeType, $this->name), 3); }
$plist = array(); while($this->read()) { if($this->nodeType == XMLReader::ELEMENT) { $plist[] = $this->parse_node(); } }
if(count($plist) == 1 && $plist[0]) { return $plist[0]; } else { return $plist; }
}
private function parse_node() {
if($this->nodeType !== XMLReader::ELEMENT) return;
switch($this->name) {
case 'data': return base64_decode($this->getNodeText()); break;
case 'real': return floatval($this->getNodeText()); break;
case 'string': return $this->getNodeText(); break;
case 'integer': return intval($this->getNodeText()); break;
case 'date': return $this->getNodeText(); break;
case 'true': return true; break;
case 'false': return false; break;
case 'array': return $this->parse_array(); break;
case 'dict': return $this->parse_dict(); break;
default: throw new Exception(sprintf("Not a valid plist. %s is not a valid type", $this->name), 4);
}
}
private function parse_dict() {
$array = array(); $this->nextOfType(XMLReader::ELEMENT);
do { if($this->nodeType !== XMLReader::ELEMENT || $this->name !== "key") { if(!$this->next("key")) { return $array; } } $key = $this->getNodeText(); $this->nextOfType(XMLReader::ELEMENT); $array[$key] = $this->parse_node(); $this->nextOfType(XMLReader::ELEMENT, XMLReader::END_ELEMENT); }
while($this->nodeType && !$this->isNodeOfTypeName(XMLReader::END_ELEMENT, "dict")); return $array;
}
private function parse_array() {
$array = array(); $this->nextOfType(XMLReader::ELEMENT);
do { $array[] = $this->parse_node(); $this->nextOfType(XMLReader::ELEMENT, XMLReader::END_ELEMENT); }
while($this->nodeType && !$this->isNodeOfTypeName(XMLReader::END_ELEMENT, "array")); return $array;
}
private function getNodeText() { $string = $this->readString(); $this->nextOfType(XMLReader::END_ELEMENT); return $string; }
private function nextOfType() { $types = func_get_args(); $this->read(); while($this->nodeType && !(in_array($this->nodeType, $types))) { $this->read(); } }
private function isNodeOfTypeName($type, $name) { return $this->nodeType === $type && $this->name === $name; }
}
function parseMediaInfo ($xml) {
$xml = simplexml_load_string($xml);
$data = array();
$data['version'] = (string) $xml['version'];
foreach ($xml->File->track as $track) {
$trackType = strtolower($track['type']);
$trackId = isset($track['streamid']) ? $track['streamid'] : 1;
$trackId = (string)$trackId;
$trackData = [];
foreach ($track as $rawKey => $rawVal) {
$key = strtolower($rawKey);
$val = (string)$rawVal;
if ($key == 'stream_identifier') { continue; }
if (!array_key_exists($key, $trackData)) {
$trackData[$key] = array($val);
} elseif (!in_array($val, $trackData[$key])) {
$trackData[$key][] = $val;
}
}
if ($trackType == 'general') {
$data['file']['general'] = $trackData;
} else {
$data['file'][$trackType][$trackId] = $trackData;
}
}
return $data;
}
function bashcolor($str,$fgcolor="white",$bgcolor=null) {
static $fgcolors = array('black' => '0;30', 'dark gray' => '1;30', 'blue' => '0;34', 'light blue' => '1;34', 'green' => '0;32', 'light green' => '1;32', 'cyan' => '0;36', 'light cyan' => '1;36', 'red' => '0;31', 'light red' => '1;31', 'purple' => '0;35', 'light purple' => '1;35', 'brown' => '0;33', 'yellow' => '1;33', 'light gray' => '0;37', 'white' => '1;37', 'underline' => '4');
static $bgcolors = array('black' => '40', 'red' => '41', 'green' => '42', 'yellow' => '43', 'blue' => '44', 'magenta' => '45', 'cyan' => '46', 'light gray' => '47');
$out="";
if (!isset($fgcolors[$fgcolor])) { $fgcolor='white'; }
if (!isset($bgcolors[$bgcolor])) { $bgcolor=null; }
if ($fgcolor) { $out .= "\033[{$fgcolors[$fgcolor]}m"; }
if ($bgcolor) { $out .= "\033[{$bgcolors[$bgcolor]}m"; }
$out .= $str."\033[0m";
return $out;
}
$banner = "Yuba: ".$zpath." -> ".$bpath;
echo $banner."\n".str_repeat("-", strlen($banner))."\n";
// Disk info
//////////////////////////////////////////
echo "Gathering system info...\n";
$host = gethostname();
$disks = shell_exec("diskutil list 2>&1");
@@ -382,13 +129,19 @@ if ($zpath == "/") {
$type = "Folder";
}
$profile = shell_exec("system_profiler SPHardwareDataType SPStorageDataType SPThunderboltDataType SPUSBDataType 2>&1");
if ($wopt_noprofile) {
$profile = "disabled";
} else {
$profile = shell_exec("system_profiler SPHardwareDataType SPStorageDataType SPThunderboltDataType SPUSBDataType 2>&1");
}
$qlmanage = shell_exec("qlmanage -m 2>&1");
$sysvers = shell_exec("sw_vers 2>&1");
// Database
//////////////////////////////////////////
echo "Building database...\n";
$stamp = date("Y-m-d_H-i-s", time());
$dbo = new PDO("sqlite:".$bpath."/".$stamp.".sqlite3");
@@ -594,7 +347,7 @@ $dbo->exec("CREATE TABLE files (
$stmt = $dbo->prepare("INSERT INTO _walkwalk VALUES (:version, :opts, :host, :uid, :zpath, :bpath, :type, :passed_file, :passed_dir, :passed_link, :passed_total, :nodescended, :ignored, :dupes, :stats, :qlmanage, :sysvers, :diskutil, :disks, :profile, :status)");
$stmt->BindValue(":version",$version);
$stmt->BindValue(":opts",serialize(getWoptString()));
$stmt->BindValue(":opts",serialize($p));
$stmt->BindValue(":host",$host);
$stmt->BindValue(":uid",posix_getuid());
$stmt->BindValue(":zpath",$zpath);
@@ -612,36 +365,37 @@ $stmt->execute();
// Iterator
//////////////////////////////////////////
$passed_file = $passed_dir = $passed_link = $nodescended = $ignored = 0;
$first_run = 1;
$passed_file = $passed_dir = $passed_link = $passed_total = $nodescended = $ignored = 0;
$files = new RecursiveIteratorIterator(
new RecursiveCallbackFilterIterator(
new RecursiveDirectoryIterator(
$zpath,
RecursiveDirectoryIterator::SKIP_DOTS
),
function ($current, $key, $iterator) use ($wopt_ignore, $wopt_nodescend) {
global $nodescended, $ignored, $passed_file, $passed_dir, $passed_link;
function ($current, $key, $iterator) use ($p) {
global $nodescended, $ignored, $passed_file, $passed_dir, $passed_link, $passed_total, $first_run;
$clean = true;
// identify ignore files
if (is_array($wopt_ignore)) {
foreach ($wopt_ignore as $wildcard) {
if (is_array($p['ignore'])) {
foreach ($p['ignore'] as $wildcard) {
if (fnmatch($wildcard, $current->getFilename())) {
$clean = false;
$ignored++;
if ($first_run) { $ignored++; }
}
}
}
// identify nodescend dirs
if (is_array($wopt_nodescend)) {
foreach ($wopt_nodescend as $wildcard) {
if (is_array($p['nodescend'])) {
foreach ($p['nodescend'] as $wildcard) {
if (fnmatch($wildcard, $current->getPath())) {
$clean = false;
$nodescended++;
if ($first_run) { $nodescended++; }
}
}
}
//tally stats
if ($clean) {
if ($clean && $first_run) {
if ($current->getType() == "file") {
$passed_file++;
} elseif ($current->getType() == "dir") {
@@ -649,6 +403,7 @@ $files = new RecursiveIteratorIterator(
} elseif ($current->getType() == "link") {
$passed_link++;
}
$passed_total++;
}
return $clean;
}
@@ -657,60 +412,58 @@ $files = new RecursiveIteratorIterator(
RecursiveIteratorIterator::CATCH_GET_CHILD
);
// Banner
// Tally
//////////////////////////////////////////
echo "Yuba ".$version."\n";
echo "-----------------------------------------------\n";
$banner = $zpath." -> ".$bpath;
echo $banner."\n";
echo str_repeat("-", strlen($banner))."\n";
foreach ($files as $null) { }
$first_run = 0;
// Permissions
//////////////////////////////////////////
if (posix_getuid()) {
echo bashcolor("You are not root. Checking file readability: ", "red");
echo ProgressBar::start($passed_total,"File permissions");
echo "\n";
echo "You are not root. Checking file readability";
$oops = 0;
foreach ($files as $splFileInfo) {
$path = $splFileInfo->getRealPath();
if (!is_readable($path)) {
if ($path && !is_readable($path)) {
$oops = 1;
echo "x";
} else {
echo ".";
}
echo ProgressBar::next();
//echo "\t".$path."\n";
}
echo ProgressBar::finish();
echo "\n\n";
echo "\n";
if ($oops) {
echo "Some files could not be read. Continue? (Y/n)";
$line = trim(fgets(fopen("php://stdin","r")));
$line = $line ?: "y";
if($line != "y"){
echo "Exiting!\n"; die;
}
echo "Some files could not be read. Stopping.";
die;
}
} else {
echo bashcolor("Running as root. Some QuickLook plugins may not be available.", "red");
echo "\n\n";
echo "Running as root. Some QuickLook plugins may not be available.";
echo "\n";
}
$fixatimes = 0;
if ($wopt_paranoid) {
echo bashcolor("\nFilesystem is writable. You can choose:\n(c) Preserve ctimes (default)\n(a) Preserve atimes\n", "purple");
$line = trim(fgets(fopen("php://stdin","r"))) ?: "c";
if ($line == "a") { $fixatimes = 1; }
if ($p['paranoid']) {
echo "Filesystem is writable. ";
if ($p['fixatimes']) {
echo "Preserving atimes.";
} else {
echo "Preserving ctimes.";
}
echo "\n";
}
// Pool DB
@@ -726,9 +479,11 @@ $dbp->exec("CREATE TABLE IF NOT EXISTS thumbs (fid TEXT, created INTEGER, relati
// Prescan
//////////////////////////////////////////
$i = 0;
$family = array();
$fids = array();
echo ProgressBar::start($passed_total,"Prescan");
foreach ($files as $splFileInfo) {
$pathname = $splFileInfo->getPathname();
@@ -762,28 +517,21 @@ foreach ($files as $splFileInfo) {
$family[$pkey]['children'][] = $key;
if ($i % 5000 == 0) {
echo "\r\033[K\rPrescan: ".$pathname;
}
$i++;
echo ProgressBar::next();
}
echo "\r\033[K\rPrescan: done\n";
echo ProgressBar::finish();
// Debug record of duplicate FIDs
$dupes = array_filter($dx, function($a) { return count($a) > 2; });
ob_start();
var_dump($dupes);
$dxo = ob_get_clean();
$dupes = array_filter($dx, function($a) { return count($a) > 1; });
$dxo = var_export($dupes, true);
if (strlen($dxo)) {
file_put_contents($bpath."/".$stamp."_dupes.txt",$dxo);
$dupecount = count($dupes,COUNT_RECURSIVE) - count($dupes);
echo "\n".bashcolor(floor(($dupecount/$i)*100)." percent of files look like duplicates","green")."\n\n";
echo floor(($dupecount/$passed_total)*100)." percent of files look like duplicates\n";
}
// Write family to DB
@@ -796,11 +544,10 @@ $message .= $passed_link." links, ";
$message .= $ignored." ignored, ";
$message .= ($dupecount ? $dupecount : 0)." dupes";
echo ProgressBar::start($i,$message);
echo ProgressBar::start(count($family),$message);
foreach ($family as $key => $item) {
echo ProgressBar::next();
$stmt = $dbo->prepare("INSERT INTO family VALUES (:pid, :fid, :children)");
$stmt->BindValue(":pid",$key);
if (@$item['fid']) {
@@ -811,6 +558,8 @@ foreach ($family as $key => $item) {
}
$stmt->execute();
echo ProgressBar::next();
}
echo ProgressBar::finish();
@@ -822,7 +571,7 @@ $stmt = "UPDATE _walkwalk SET ";
$stmt .= "passed_file=".$passed_file.", ";
$stmt .= "passed_dir=".$passed_dir.", ";
$stmt .= "passed_link=".$passed_link.", ";
$stmt .= "passed_total=".$i.", ";
$stmt .= "passed_total=".$passed_total.", ";
$stmt .= "nodescended=".$nodescended.", ";
$stmt .= "ignored=".$ignored.", ";
$stmt .= "dupes=".($dupecount ? $dupecount : 0);
@@ -831,13 +580,9 @@ $dbo->exec($stmt);
// Thumbnails
//////////////////////////////////////////
if ($wopt_thumbs) {
if ($p['thumbs']) {
$message = "Generating thumbnails...";
echo ProgressBar::start(count($fx),$message);
$tempdir = "/tmp/".$blabel."_".$stamp;
if (!is_dir($tempdir)) { mkdir($tempdir); }
echo ProgressBar::start(count($fx),"Generating thumbnails");
foreach ($fx as $array) {
@@ -845,24 +590,25 @@ if ($wopt_thumbs) {
$pathname = $array[1];
$ext = pathinfo($pathname,PATHINFO_EXTENSION);
$tpath = $bpath."/thumbs/".substr($fid, 0, 2);
if (!is_dir($tpath)) { mkdir($tpath); }
$tfile = $tpath."/".$fid.".jpg";
// HACK for ql-thumbnail bug
$t_skip = array("emlx");
if (count($t_skip) && in_array($ext, $t_skip)) {
echo ProgressBar::next(1, "Skipping ".shortlabel(basename($pathname),$max_label));
echo ProgressBar::next("Skipping ".shortlabel($pathname));
continue;
}
// if no thumb file, then poll database
if (file_exists($tfile)) {
echo ProgressBar::next(1, "Thumb file found for ".shortlabel(basename($pathname),$max_label));
echo ProgressBar::next("Thumb file found for ".shortlabel($pathname));
continue;
} elseif ($dbp->query("SELECT EXISTS(SELECT 1 FROM thumbs WHERE fid='".$fid."')")->fetch()[0]) {
echo ProgressBar::next(1, "Thumb record found for ".shortlabel(basename($pathname),$max_label));
echo ProgressBar::next("Thumb record found for ".shortlabel($pathname));
continue;
} else {
echo ProgressBar::next(1, "Generating thumb for ".shortlabel(basename($pathname),$max_label));
echo ProgressBar::next("Generating thumb for ".shortlabel($pathname));
}
$stmt = $dbp->prepare("INSERT INTO thumbs VALUES (:fid, :created, :relative_path, :width, :height, :tool)");
@@ -870,31 +616,31 @@ if ($wopt_thumbs) {
$stmt->BindValue(":created",time());
$shellpath = escapeshellarg($pathname);
$tempfile = $tempdir."/".$fid.".jpg";
// first try to make a thumb with external tools
$cmd = null;
if (in_array($ext, $t_files['vips'])) {
$cmd = $bin_tv." ".$shellpath." -o ".$tempfile."[Q=90,optimize_coding] --size=".$wopt_thumb_size;
$stmt->BindValue(":tool","vips");
if (in_array($ext, $t_files['sips'])) {
//$cmd = $bin_tv." ".$shellpath." -o ".$tfile."[Q=90,optimize_coding] --size=".$p['thumb_size'];
$cmd = "sips -s format jpeg -s formatOptions 80 --resampleHeightWidthMax ".$p['thumb_size']." ".$shellpath." --out ".$tfile;
$stmt->BindValue(":tool","sips");
} elseif (in_array($ext, $t_files['ffmpeg'])) {
$cmd = $bin_tf." -i ".$shellpath." -o ".$tempfile." -s ".$wopt_thumb_size." -c jpg -q 8.5";
//$cmd = $bin_tf." -i ".$shellpath." -o ".$tfile." -s ".$p['thumb_size']." -c jpg -q 8.5";
$cmd = $bin_ffmpeg." -ss $(( $(".$bin_mediainfo." --Inform='Video;%Duration%' ".$shellpath.") / 10000 )) -i ".$shellpath." -vframes 1 -filter:v scale='400:-1' -q:v 3 ".$tfile;
$stmt->BindValue(":tool","ffmpeg");
}
if ($cmd) { shell_exec($cmd." 2>&1"); }
// if those tools failed, try quicklook
if (!@filesize($tempfile)) {
$cmd = $bin_tq." ".$shellpath." ".$tempfile." public.jpeg-2000 ".$wopt_thumb_size." ".$wopt_thumb_size." .8";
if (!@filesize($tfile)) {
//$cmd = $bin_qlthumb." ".$shellpath." ".$tfile." public.jpeg-2000 ".$p['thumb_size']." ".$p['thumb_size']." .8";
$cmd = $bin_qlthumb." ".$shellpath." ".$tfile." public.jpeg ".$p['thumb_size']." ".$p['thumb_size']." .8";
shell_exec($cmd." 2>&1");
$stmt->BindValue(":tool","quicklook");
}
// success, move thumb into the bundle
if (file_exists($tempfile) && @filesize($tempfile)) {
if (!is_dir($tpath)) { mkdir($tpath); }
rename($tempfile,$tfile);
if (file_exists($tfile) && @filesize($tfile)) {
$stmt->BindValue(":relative_path",substr($tfile, strlen($bpath)));
list($width, $height) = getimagesize($tfile);
$stmt->BindValue(":width",$width);
@@ -912,10 +658,9 @@ if ($wopt_thumbs) {
// External metadata
//////////////////////////////////////////
if ($wopt_meta) {
if ($p['meta']) {
$message = "Collecting external metadata...";
echo ProgressBar::start(count($fx),$message);
echo ProgressBar::start(count($fx),"Collecting external metadata");
foreach ($fx as $array) {
@@ -925,10 +670,10 @@ if ($wopt_meta) {
$ext = pathinfo($pathname,PATHINFO_EXTENSION);
if (!in_array($ext, $e_files) && !in_array($ext, $m_files)) {
echo ProgressBar::next(1, "Not a media file: ".shortlabel($pathname,$max_label));
echo ProgressBar::next("Not a media file: ".shortlabel($pathname));
continue;
} else {
echo ProgressBar::next(1, "Metadata: ".shortlabel($pathname,$max_label));
echo ProgressBar::next("Metadata: ".shortlabel($pathname));
}
if (in_array($ext, $e_files)) {
@@ -961,10 +706,10 @@ if ($wopt_meta) {
// Hashes
//////////////////////////////////////////
if ($wopt_hash) {
if ($p['hash']) {
if ($wopt_hash_limit) {
$message = "Generating hashes for files under".$wopt_hash_limit."GB";
if ($p['hash_limit']) {
$message = "Generating hashes for files under ".$p['hash_limit']."GB";
} else {
$message = "Generating hashes for all files";
}
@@ -975,14 +720,14 @@ if ($wopt_hash) {
$fid = $array[0];
$pathname = $array[1];
$size = filesize($pathname);
$limit = $wopt_hash_limit*1000000000;
$limit = $p['hash_limit']*1000000000;
$check = $dbp->query("SELECT EXISTS(SELECT 1 FROM md5 WHERE fid='".$fid."')")->fetch()[0];
if ($check) {
echo ProgressBar::next(1, "Hash already exists: ".shortlabel($pathname,$max_label));
} elseif ($wopt_hash_limit && ($size > $limit)) {
echo ProgressBar::next(1, "Too big to hash: ".shortlabel($pathname,$max_label)." (".human_filesize($size).")");
echo ProgressBar::next("Hash already exists: ".shortlabel($pathname));
} elseif ($p['hash_limit'] && ($size > $limit)) {
echo ProgressBar::next("Too big to hash: ".shortlabel($pathname)." (".human_filesize($size).")");
} else {
echo ProgressBar::next(1, "Generating hash: ".shortlabel($pathname,$max_label));
echo ProgressBar::next("Generating hash: ".shortlabel($pathname));
$stmt = $dbp->prepare("INSERT INTO md5 VALUES (:fid, :hash)");
$stmt->BindValue(":fid",$fid);
$stmt->BindValue(":hash",md5_file($pathname));
@@ -997,11 +742,12 @@ if ($wopt_hash) {
// Files
//////////////////////////////////////////
echo ProgressBar::start($i);
echo ProgressBar::start($passed_total,"Processing files");
$j = 0;
foreach ($files as $splFileInfo) {
echo "\n";
// DB
$stmt = $dbo->prepare("INSERT INTO files VALUES (:pid, :fid, :Pathname, :Path, :Filename, :Extension, :Type, :Inode, :Perms, :Owner, :ATime, :CTime, :MTime, :LinkTarget, :RealPath, :stat, :items, :newest, :gfi_type, :gfi_attr, :gfi_created, :Size, :Title, :PixelWidth, :PixelHeight, :Duration, :DateTimeOriginal, :Origin, :GPS, :Author, :spotlight, :kMDItemDateAdded, :kMDItemLastUsedDate, :kMDItemUseCount, :kMDItemContentModificationDate, :kMDItemContentType, :kMDItemCreator, :kMDItemFSCreatorCode, :kMDItemKind, :kMDItemFSTypeCode, :kMDItemUserTags, :kMDItemFSInvisible, :kMDItemNumberOfPages, :kMDItemPageHeight, :kMDItemPageWidth, :kMDItemWhereFroms, :kMDItemEncodingApplications, :has_exif, :has_mediainfo, :has_hash, :thumb_filename, :thumb_width, :thumb_height, :ProfileDescription, :BitDepth, :Compression, :Orientation, :LensType, :VideoFormat, :AudioFormat, :Tracks, :Profile, :Bitrate)");
@@ -1010,7 +756,7 @@ foreach ($files as $splFileInfo) {
$type = $splFileInfo->getType();
if ($type == "dir") {
foreach ($wopt_bundles as $bundle) {
foreach ($p['bundles'] as $bundle) {
$check = ".".$bundle;
if (substr($splFileInfo->getFilename(), -(strlen($check)), strlen($check)) == $check) { $type = "bundle"; }
}
@@ -1052,14 +798,14 @@ foreach ($files as $splFileInfo) {
}
stringPrint(shortlabel(basename($pathname),$max_label,$max_label+10));
echo shortlabel($pathname,50,1);
// ------------------------------------------------ //
// Get stat
if ($type != "link") {
$stat = chop(@shell_exec("stat -x ".$shellpath." 2>&1"));
$stat = chop(@shell_exec("stat -x ".$shellpath." 2>&1"));
} else {
$stat = null;
}
@@ -1067,7 +813,7 @@ foreach ($files as $splFileInfo) {
// Cache stat
if ($type != "link" && $wopt_paranoid) {
if ($type != "link" && $p['paranoid']) {
$pre_access = null;
$pre_modify = null;
$pre_change = null;
@@ -1313,16 +1059,9 @@ function parseItem($data, $item) {
unset($breakout);
print_r($fetch_exif);
print_r($fetch_media);
//print_r($fetch_exif);
//print_r($fetch_media);
} else {
stringPrint(" ");
stringPrint(" ");
stringPrint(" ");
stringPrint(" ");
}
// Write to DB
@@ -1332,16 +1071,14 @@ function parseItem($data, $item) {
// Set fileatime back to original value
if ($type != "link" && is_writable($pathname) && $fixatimes) {
if ($type != "link" && is_writable($pathname) && $p['fixatimes']) {
@exec("touch -at `date -r ".$atime." +%Y%m%d%H%M.%S` ".$shellpath." 2>&1");
stringPrint("touch");
}
echo "\n";
// Double check stat for file against pre-run value
if ($type != "link" && $wopt_paranoid) {
if ($type != "link" && $p['paranoid']) {
$restat = chop(@shell_exec("stat -x ".$shellpath." 2>&1"));
$post_access = null;
@@ -1366,18 +1103,12 @@ function parseItem($data, $item) {
$message[] = "CTIME";
}
if (count($message)) { stringPrint("Change: ".implode(", ", $message)); }
if (count($message)) { stringPrint("Changed: ".implode(", ", $message)); }
}
$update = ProgressBar::next(1, substr($pathname,0,80));
if (floor($j/100) == ($j/100)) {
echo "\n\n-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n";
echo $update;
echo "\n-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n\n";
}
$j++;
echo "\n";
echo ProgressBar::next();
}