This commit is contained in:
2017-06-16 00:14:32 -07:00
parent 62dab3d734
commit 403c9a8efc
2 changed files with 488 additions and 119 deletions

150
Yuba.php
View File

@@ -3,20 +3,46 @@
error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
date_default_timezone_set("America/Los_Angeles");
$time_start = microtime(true);
// Yuba
// //
//////////////////////////////////////////
$version = "0.3.8.1";
$version = "0.4.6";
// Stat each file before and after reading (will fail on ctime unless volume is RO)
if (in_array("-paranoid", $argv)) { $wopt_paranoid = 1; } else { $wopt_paranoid = 0; }
// Do not descend into matching directories
$wopt_nodescend = array("*.app", "*.sparsebundle", "*.Spotlight-V100", "*.fseventsd");
// Treat these directories as files
$wopt_bundles = array( "app",
"bundle",
"sparsebundle",
"photoslibrary",
"aplibrary",
"apvault",
"abbu",
"calendar",
"framework",
"plugin",
"kext",
"rtfd"
);
foreach ($wopt_bundles as $bundle) {
$wopt_nodescend[] = "*.".$bundle;
}
// Ignore matching files and directories
$wopt_ignore = array(".DS_Store", "*.jdk");
$wopt_ignore = array( ".DS_Store",
".DocumentRevisions-V100",
".Spotlight-V100",
".TemporaryItems",
".apdisk",
".com.apple.timemachine.donotpresent",
".fseventsd",
".metadata-never-index",
".neofinder.abemeda.volinfo.xml"
);
if (in_array("-hash", $argv)) { $wopt_hash = 1; } else { $wopt_hash = 0; }
//$wopt_hash_limit = ""; // don't hash large files nyi
@@ -35,8 +61,15 @@ $bin_exiftool = "/opt/local/bin/exiftool";
// Functions
function debugStat() {
global $shellpath;
echo "\n\n";
echo $shellpath." - ".chop(@shell_exec("stat -x ".$shellpath." | tail -n1"));
echo "\n\n";
}
function stringPrint($string) {
echo $string.str_repeat(" ", (10-strlen($string)));
echo $string.@str_repeat(" ", (10-strlen($string)));
}
function getWoptString() {
@@ -143,12 +176,11 @@ if (isset($argv[2]) && is_dir($argv[2])) {
// File checks
date_default_timezone_set("America/Los_Angeles");
$time_start = microtime(true);
$stamp = date("Y-m-d_H-i-s", time());
$wopt_tmpdir = "/tmp/WalkWalk_".$stamp."/";
if (!is_dir($wopt_tmpdir)) { mkdir($wopt_tmpdir); }
$base = preg_replace("/[^A-Za-z0-9\.]/", "_", basename($zpath));
if (!$base) { $base = "root"; }
$dbfile = $dbprefix."/".$stamp."_".$base.".sqlite3";
if (file_exists($dbfile)) { echo "File \"".$dbfile."\" already exists!"; die; }
@@ -208,12 +240,26 @@ if ($zpath == "/") {
}
$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
// use mysql?
//$dbo = new PDO("mysql:dbname=testdb;host=127.0.0.1", $user, $pass);
$dbo = new PDO("sqlite:".$dbfile);
$dbo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// test: try to set values for better performance
//$dbo->query("PRAGMA page_size = 4096");
//$dbo->query("PRAGMA cache_size = 10000");
//$dbo->query("PRAGMA locking_mode = EXCLUSIVE");
//$dbo->query("PRAGMA synchronous = NORMAL");
//$dbo->query("PRAGMA journal_mode = WAL");
//$dbo->query("PRAGMA cache_size = 5000");
// end test
$dbo->exec("CREATE TABLE files (
id INTEGER PRIMARY KEY,
parent INTEGER,
@@ -222,6 +268,7 @@ $dbo->exec("CREATE TABLE files (
Filename TEXT,
Extension TEXT,
Type TEXT,
items INTEGER,
stat TEXT,
LinkTarget TEXT,
RealPath TEXT,
@@ -265,7 +312,7 @@ $dbo->exec("CREATE TABLE thumbs (
thumb BLOB
)");
$dbo->exec("CREATE TABLE IF NOT EXISTS _walkwalk (
$dbo->exec("CREATE TABLE _walkwalk (
version TEXT,
opts TEXT,
host TEXT,
@@ -274,13 +321,15 @@ $dbo->exec("CREATE TABLE IF NOT EXISTS _walkwalk (
nodescended INTEGER,
ignored INTEGER,
stats TEXT,
qlmanage TEXT,
sysvers TEXT,
diskutil TEXT,
disks TEXT,
profile TEXT,
status TEXT
)");
$stmt = $dbo->prepare("INSERT INTO _walkwalk VALUES (:version, :opts, :host, :zpath, :type, :nodescended, :ignored, :stats, :diskutil, :disks, :profile, :status)");
$stmt = $dbo->prepare("INSERT INTO _walkwalk VALUES (:version, :opts, :host, :zpath, :type, :nodescended, :ignored, :stats, :qlmanage, :sysvers, :diskutil, :disks, :profile, :status)");
$stmt->BindValue(":version",$version." (".posix_getuid().")");
$stmt->BindValue(":opts",serialize(getWoptString()));
$stmt->BindValue(":host",$host);
@@ -289,6 +338,8 @@ $stmt->BindValue(":type",$type);
$stmt->BindValue(":nodescended",null);
$stmt->BindValue(":ignored",null);
$stmt->BindValue(":stats",$dstats);
$stmt->BindValue(":qlmanage",$qlmanage);
$stmt->BindValue(":sysvers",$sysvers);
$stmt->BindValue(":diskutil",$diskutil);
$stmt->BindValue(":disks",$disks);
$stmt->BindValue(":profile",$profile);
@@ -302,12 +353,18 @@ $ignored = 0;
$files = new RecursiveIteratorIterator(
new RecursiveCallbackFilterIterator(
new RecursiveDirectoryIterator(
$zpath,
// start in parent dir to include self
dirname($zpath),
RecursiveDirectoryIterator::SKIP_DOTS
),
function ($current, $key, $iterator) use ($wopt_ignore, $wopt_nodescend) {
global $nodescended, $ignored;
global $nodescended, $ignored, $zpath;
$clean = true;
// ensure we don't traverse zpath siblings
if ($zpath != "/" && (substr($current->getRealpath(), 0, strlen($zpath)+1) != $zpath."/") && ($current->getRealpath() != $zpath)) {
$clean = false;
}
// filenames to ignore
if (is_array($wopt_ignore)) {
foreach ($wopt_ignore as $wildcard) {
if (fnmatch($wildcard, $current->getFilename())) {
@@ -317,6 +374,7 @@ $files = new RecursiveIteratorIterator(
}
}
}
// directories to ignore
if (is_array($wopt_nodescend)) {
foreach ($wopt_nodescend as $wildcard) {
if (fnmatch($wildcard, $current->getPath())) {
@@ -375,7 +433,7 @@ die;
if (posix_getuid()) {
echo "You are not root. Checking file readability: ";
echo bashcolor("You are not root. Checking file readability: ", "red");
$oops = 0;
foreach ($files as $splFileInfo) {
@@ -398,6 +456,11 @@ if (posix_getuid()) {
echo "Exiting!\n"; die;
}
}
} else {
echo bashcolor("Running as root. Some QuickLook plugins may not be available.", "red");
}
// Filetypes for special handling
@@ -496,11 +559,21 @@ $e_files = array( "ai",
"xmp",
"zip" );
foreach ($e_files as $ext) { $e_files[] = strtoupper($ext); }
foreach ($m_files as $ext) { $m_files[] = strtoupper($ext); }
// Inserts
foreach ($files as $splFileInfo) {
$type = $splFileInfo->getType();
if ($type == "dir") {
foreach ($wopt_bundles as $bundle) {
$check = ".".$bundle;
if (substr($splFileInfo->getFilename(), -(strlen($check)), strlen($check)) == $check) { $type = "bundle"; }
}
}
if ($type != "link") { $atime = $splFileInfo->getATime(); }
$pathname = $splFileInfo->getPathname();
$path = $splFileInfo->getPath();
@@ -508,6 +581,8 @@ foreach ($files as $splFileInfo) {
$extension = $splFileInfo->getExtension();
$shellpath = escapeshellarg($pathname);
debugStat();
if (!$type) { echo "\nBREAK: can't determine type of ".$pathname; die; }
if ($type != "link") {
@@ -516,11 +591,18 @@ foreach ($files as $splFileInfo) {
} else {
$stat = null;
}
echo str_replace($zpath."/","",$pathname).": ";
$pad = 140;
if (strlen($pathname) < $pad) {
echo str_repeat(" ",($pad-strlen($pathname)));
if ($type == "dir" || $type == "bundle" ) {
$items = chop(@shell_exec("find ".$shellpath." \( ! -regex '.*/\..*' \) | wc -l 2>&1"))-1;
} else {
$items = null;
}
$echolabel = basename($pathname);
echo $echolabel.": ";
$pad = 80;
if (strlen($echolabel) < $pad) {
echo str_repeat(" ",($pad-strlen($echolabel)));
}
// Determine ID of parent dir by querying database
@@ -528,13 +610,15 @@ foreach ($files as $splFileInfo) {
$parent = $dbo->query("SELECT id FROM files WHERE (Pathname='".str_replace("'", "''", $path)."')")->fetch()['id'];
stringPrint("parent");
debugStat();
// Gather file attributes
$stmt = $dbo->prepare("INSERT INTO files VALUES (:id, :parent, :Pathname, :Path, :Filename, :Extension, :Type, :stat, :LinkTarget, :RealPath, :Inode, :Size, :Perms, :Owner, :ATime, :MTime, :CTime, :gfi_type, :gfi_attr, :gfi_created, :hash, :tinfo)");
$stmt = $dbo->prepare("INSERT INTO files VALUES (:id, :parent, :Pathname, :Path, :Filename, :Extension, :Type, :items, :stat, :LinkTarget, :RealPath, :Inode, :Size, :Perms, :Owner, :ATime, :MTime, :CTime, :gfi_type, :gfi_attr, :gfi_created, :hash, :tinfo)");
if ($type == "dir") {
$size = shell_exec("du -ks ".$shellpath)*1024;
} elseif ($type == "file") {
} elseif ($type == "file" || $type == "bundle") {
$size = $splFileInfo->getSize();
} else {
$size = null;
@@ -548,6 +632,7 @@ foreach ($files as $splFileInfo) {
$stmt->BindValue(":parent",0);
}
$stmt->BindValue(":items",@$items);
$stmt->BindValue(":stat",@$stat);
$stmt->BindValue(":Pathname",$pathname);
@@ -573,6 +658,8 @@ foreach ($files as $splFileInfo) {
}
debugStat();
stringPrint("attr");
$gfiparts = explode("\n", chop(shell_exec($bin_gfi." -P ".$shellpath." 2>&1")));
@@ -601,7 +688,16 @@ foreach ($files as $splFileInfo) {
}
$thumb = $wopt_tmpdir.$filename.".png";
@exec("qlmanage -t -f ".$wopt_thumb_factor." -o ".$wopt_tmpdir." ".$shellpath." 2>&1");
/*
// insane workaround for insane apple bug
if (@pathinfo($pathname)['extension'] == "mp3" | "MP3" | "m4a" | "M4A" | "m4b" | "M4B" ) {
$zprefix = "sudo qlmanage";
} else {
$zprefix = "qlmanage";
}
*/
$zprefix = "qlmanage";
@exec($zprefix." -t -f ".$wopt_thumb_factor." -o ".$wopt_tmpdir." ".$shellpath." 2>&1");
stringPrint("thumb");
if ($size && !file_exists($thumb) && (in_array($extension, $m_files) || in_array($extension, $e_files))) {
@exec("ffmpegthumbnailer -i ".$shellpath." -o \"".$thumb."\" -s ".$wopt_thumb_size." -c png 2>&1");
@@ -613,6 +709,8 @@ foreach ($files as $splFileInfo) {
$stmt->BindValue(":tinfo",serialize(getimagesize($thumb)));
}
debugStat();
$stmt->execute();
stringPrint("->files");
@@ -628,7 +726,7 @@ foreach ($files as $splFileInfo) {
$parser = new plistParser();
$spotlight = $parser->parseString($mdls);
$stmt->BindValue(":DateAdded",@$spotlight['kMDItemDateAdded']);
$stmt->BindValue(":DateAdded",@strtotime($spotlight['kMDItemDateAdded']));
$stmt->BindValue(":ContentType",@$spotlight['kMDItemContentType']);
$stmt->BindValue(":Creator",@$spotlight['kMDItemCreator']);
$stmt->BindValue(":Kind",@$spotlight['kMDItemKind']);
@@ -677,6 +775,8 @@ foreach ($files as $splFileInfo) {
// Gather thumbnail
debugStat();
$stmt = $dbo->prepare("INSERT INTO thumbs VALUES (:id, :thumb)");
if (file_exists($thumb) && filesize($thumb)) {
$stmt->BindValue(":thumb",file_get_contents($thumb));
@@ -688,10 +788,10 @@ foreach ($files as $splFileInfo) {
// Set fileatime back to original value
if ($type != "link" && is_writable($pathname)) {
@exec("touch -at `date -r ".$atime." +%Y%m%d%H%M.%S` ".$shellpath." 2>&1");
stringPrint("touch");
}
//if ($type != "link" && is_writable($pathname)) {
// @exec("touch -at `date -r ".$atime." +%Y%m%d%H%M.%S` ".$shellpath." 2>&1");
// stringPrint("touch");
// }
echo "\n";