0.6.9
This commit is contained in:
521
Yuba.php
521
Yuba.php
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user