diff --git a/Yuba.php b/Yuba.php index 08ad1aa..17bfdbf 100755 --- a/Yuba.php +++ b/Yuba.php @@ -1,11 +1,135 @@ #!/usr/bin/php 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; + } // Path arguments @@ -22,8 +146,8 @@ if (isset($argv[2]) && is_dir($argv[2])) { date_default_timezone_set("America/Los_Angeles"); $time_start = microtime(true); $stamp = date("Y-m-d_H-i-s", time()); -$tmpdir = "/tmp/WalkWalk_".$stamp."/"; -if (!is_dir($tmpdir)) { mkdir($tmpdir); } +$wopt_tmpdir = "/tmp/WalkWalk_".$stamp."/"; +if (!is_dir($wopt_tmpdir)) { mkdir($wopt_tmpdir); } $base = preg_replace("/[^A-Za-z0-9\.]/", "_", basename($zpath)); $dbfile = $dbprefix."/".$stamp."_".$base.".sqlite3"; if (file_exists($dbfile)) { echo "File \"".$dbfile."\" already exists!"; die; } @@ -90,62 +214,163 @@ $profile = shell_exec("system_profiler SPHardwareDataType SPStorageDataType SPTh $dbo = new PDO("sqlite:".$dbfile); $dbo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); -$dbo->exec("CREATE TABLE IF NOT EXISTS \"".$base."\" ( +$dbo->exec("CREATE TABLE files ( id INTEGER PRIMARY KEY, parent INTEGER, - path TEXT, - ext TEXT, - type TEXT, - size INTEGER, + Pathname TEXT, + Path TEXT, + Filename TEXT, + Extension TEXT, + Type TEXT, + stat TEXT, + LinkTarget TEXT, + RealPath TEXT, + Inode INTEGER, + Size INTEGER, + Perms INTEGER, + Owner TEXT, + ATime INTEGER, + MTime INTEGER, + CTime INTEGER, + gfi_type TEXT, + gfi_attr TEXT, + gfi_created TEXT, hash TEXT, - perms INTEGER, - owner TEXT, - inode INTEGER, - mtime INTEGER, - atime INTEGER, - ctime INTEGER, - mdls TEXT, - tags TEXT, - mediainfo TEXT, - exiftool TEXT, - tinfo TEXT)"); + tinfo TEXT + )"); -$dbo->exec("CREATE TABLE IF NOT EXISTS thumbs ( +$dbo->exec("CREATE TABLE mdls ( id INTEGER PRIMARY KEY, - thumb BLOB)"); + hasmeta INTEGER, + DateAdded TEXT, + ContentType TEXT, + Creator TEXT, + Kind TEXT, + UserTags TEXT, + FSInvisible INTEGER, + PixelWidth INTEGER, + PixelHeight INTEGER, + spotlight TEXT + )"); + +$dbo->exec("CREATE TABLE metadata ( + id INTEGER PRIMARY KEY, + duration TEXT, + mediainfo TEXT, + exiftool TEXT + )"); + +$dbo->exec("CREATE TABLE thumbs ( + id INTEGER PRIMARY KEY, + thumb BLOB + )"); $dbo->exec("CREATE TABLE IF NOT EXISTS _walkwalk ( version TEXT, + opts TEXT, host TEXT, zpath TEXT, type TEXT, + nodescended INTEGER, + ignored INTEGER, stats TEXT, diskutil TEXT, disks TEXT, - profile TEXT)"); + profile TEXT, + status TEXT + )"); -$insert = "INSERT INTO _walkwalk VALUES (:version, :host, :zpath, :type, :stats, :diskutil, :disks, :profile)"; -$stmt = $dbo->prepare($insert); +$stmt = $dbo->prepare("INSERT INTO _walkwalk VALUES (:version, :opts, :host, :zpath, :type, :nodescended, :ignored, :stats, :diskutil, :disks, :profile, :status)"); $stmt->BindValue(":version",$version." (".posix_getuid().")"); +$stmt->BindValue(":opts",serialize(getWoptString())); $stmt->BindValue(":host",$host); $stmt->BindValue(":zpath",$zpath); $stmt->BindValue(":type",$type); +$stmt->BindValue(":nodescended",null); +$stmt->BindValue(":ignored",null); $stmt->BindValue(":stats",$dstats); $stmt->BindValue(":diskutil",$diskutil); $stmt->BindValue(":disks",$disks); $stmt->BindValue(":profile",$profile); +$stmt->BindValue(":status","aborted"); $stmt->execute(); // Iterate -$dir_iter = new RecursiveDirectoryIterator($zpath, - RecursiveDirectoryIterator::SKIP_DOTS - ); -$iter = new RecursiveIteratorIterator($dir_iter, - RecursiveIteratorIterator::SELF_FIRST, - RecursiveIteratorIterator::CATCH_GET_CHILD - ); - +$nodescended = 0; +$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; + $clean = true; + if (is_array($wopt_ignore)) { + foreach ($wopt_ignore as $wildcard) { + if (fnmatch($wildcard, $current->getFilename())) { + $clean = false; + $ignored++; + echo "\nSkipping: ".$current->getRealpath()."\n\n"; + } + } + } + if (is_array($wopt_nodescend)) { + foreach ($wopt_nodescend as $wildcard) { + if (fnmatch($wildcard, $current->getPath())) { + $clean = false; + $nodescended++; + echo "\nNodescending: ".$current->getRealpath()."\n\n"; + } + } + } + return $clean; + } + ), + RecursiveIteratorIterator::SELF_FIRST, + RecursiveIteratorIterator::CATCH_GET_CHILD + ); + +// Debug input array + +/* +foreach ($files as $splFileInfo) { + echo "====================================================================================\n"; + print_r($splFileInfo); + echo "====================================================================================\n"; + echo "getRealPath = ".$splFileInfo->getRealPath()."\n"; + echo "getPathname = ".$splFileInfo->getPathname()."\n"; + echo "isLink = ".$splFileInfo->isLink()."\n"; + if ($splFileInfo->isLink()) { + echo "getLinkTarget = ".$splFileInfo->getLinkTarget()."\n"; + } else { + echo "getLinkTarget = N/A\n"; + } + echo "getType = ".$splFileInfo->getType()." (".filetype($splFileInfo->getPathname()).")\n"; + echo "isDir = ".$splFileInfo->isDir()."\n"; + echo "isFile = ".$splFileInfo->isFile()."\n"; + echo "-----------------------------------------------------------------------\n"; + echo "getPath = ".$splFileInfo->getPath()."\n"; + echo "getFilename = ".$splFileInfo->getFilename()."\n"; + echo "getBasename = ".$splFileInfo->getBasename()." (".basename($splFileInfo->getPathname()).")\n"; + echo "getExtension = ".$splFileInfo->getExtension()."\n"; + echo "-----------------------------------------------------------------------\n"; + if (!$splFileInfo->isLink()) { + echo "getATime = ".$splFileInfo->getAtime()." (".fileatime($splFileInfo->getPathname()).")\n"; + echo "getMTime = ".$splFileInfo->getMtime()." (".filemtime($splFileInfo->getPathname()).")\n"; + echo "getCTime = ".$splFileInfo->getCtime()." (".filectime($splFileInfo->getPathname()).")\n"; + echo "getInode = ".$splFileInfo->getInode()." (".fileinode($splFileInfo->getPathname()).")\n"; + echo "getPerms = ".$splFileInfo->getPerms()." (".fileperms($splFileInfo->getPathname()).")\n"; + echo "getGroup = ".$splFileInfo->getGroup()." (".filegroup($splFileInfo->getPathname()).")\n"; + echo "getOwner = ".$splFileInfo->getOwner()." (".fileowner($splFileInfo->getPathname()).")\n"; + echo "getSize = ".$splFileInfo->getSize()." (".filesize($splFileInfo->getPathname()).")\n"; + } + } +die; +*/ + // Check perms if (posix_getuid()) { @@ -153,7 +378,7 @@ if (posix_getuid()) { echo "You are not root. Checking file readability: "; $oops = 0; - foreach ($iter as $splFileInfo) { + foreach ($files as $splFileInfo) { $path = $splFileInfo->getRealPath(); if (!is_readable($path)) { $oops = 1; @@ -175,7 +400,7 @@ if (posix_getuid()) { } } -// Filetypes +// Filetypes for special handling $m_files = array( "mkv", "ogg", @@ -271,104 +496,226 @@ $e_files = array( "ai", "xmp", "zip" ); -// Insert +// Inserts -foreach ($iter as $splFileInfo) { - $path = $splFileInfo->getRealPath(); - echo $path.": "; - $line = array(); - $info = pathinfo($path); - $select = "SELECT id from \"".$base."\" WHERE (path=\"".$info['dirname']."\")"; - $slct = $dbo->query($select); - $row = $slct->fetchObject(); - if (@$row->id) { - $line['parent'] = $row->id; +foreach ($files as $splFileInfo) { + + $type = $splFileInfo->getType(); + if ($type != "link") { $atime = $splFileInfo->getATime(); } + $pathname = $splFileInfo->getPathname(); + $path = $splFileInfo->getPath(); + $filename = $splFileInfo->getFilename(); + $extension = $splFileInfo->getExtension(); + $shellpath = escapeshellarg($pathname); + + if (!$type) { echo "\nBREAK: can't determine type of ".$pathname; die; } + + if ($type != "link") { + $stat = chop(@shell_exec("stat -x ".$shellpath." 2>&1")); + if ($wopt_paranoid && !$atime) { echo "\nBREAK: Cannot determine atime of ".$pathname; die; } } else { - $line['parent'] = 0; + $stat = null; } - $line['path'] = $path; - $line['ext'] = strtolower(@$info['extension']); - $line['type'] = filetype($path); - if ($line['type'] == "dir") { - $line['size'] = @shell_exec("du -ks \"".$path."\"")*1024; + + echo str_replace($zpath."/","",$pathname).": "; + $pad = 140; + if (strlen($pathname) < $pad) { + echo str_repeat(" ",($pad-strlen($pathname))); + } + + // Determine ID of parent dir by querying database + + $parent = $dbo->query("SELECT id FROM files WHERE (Pathname='".str_replace("'", "''", $path)."')")->fetch()['id']; + stringPrint("parent"); + + // 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)"); + + if ($type == "dir") { + $size = shell_exec("du -ks ".$shellpath)*1024; + } elseif ($type == "file") { + $size = $splFileInfo->getSize(); } else { - $line['size'] = filesize($path); + $size = null; } - echo floor($line['size']/1024)."k; "; - $line['hash'] = md5_file($path); - echo "hashed; "; - $line['perms'] = fileperms($path); - $line['owner'] = fileowner($path).":".filegroup($path); - $line['inode'] = fileinode($path); - $line['mtime'] = filemtime($path); - $line['atime'] = fileatime($path); - $line['ctime'] = filectime($path); - echo "perms; "; - $spotlight = shell_exec("mdls \"".$path."\" 2>&1"); - if ($spotlight != $path.": could not find ".$path.".\n") { - $line['mdls'] = $spotlight; - if (strpos($spotlight, "kMDItemUserTags")) { - $jlines = array_slice(explode("\n", @shell_exec("mdls -name kMDItemUserTags -raw \"".$path."\" 2>&1")), 1, -1); - $colors = array(); - foreach ($jlines as $jline) { - $colors[] = chop($jline,","); - } - $line['tags'] = serialize($colors); + $stmt->BindValue(":Size",@$size); + stringPrint(floor($size/1024)."k"); + + if ($parent) { + $stmt->BindValue(":parent",$parent); + } else { + $stmt->BindValue(":parent",0); + } + + $stmt->BindValue(":stat",@$stat); + + $stmt->BindValue(":Pathname",$pathname); + $stmt->BindValue(":Path",$path); + $stmt->BindValue(":Filename",$filename); + $stmt->BindValue(":Extension",$extension); + $stmt->BindValue(":Type",$type); + + if ($type == "link") { + + $stmt->BindValue(":LinkTarget",$splFileInfo->getLinkTarget()); + $stmt->BindValue(":RealPath",$splFileInfo->getRealPath()); + + } else { + + $stmt->BindValue(":Inode",$splFileInfo->getInode()); + $stmt->BindValue(":Perms",$splFileInfo->getPerms()); + $stmt->BindValue(":Owner",$splFileInfo->getOwner().":".$splFileInfo->getGroup()); + + $stmt->BindValue(":ATime",$atime); + $stmt->BindValue(":CTime",$splFileInfo->getCTime()); + $stmt->BindValue(":MTime",$splFileInfo->getMTime()); + + } + + stringPrint("attr"); + + $gfiparts = explode("\n", chop(shell_exec($bin_gfi." -P ".$shellpath." 2>&1"))); + if (is_array($gfiparts)) { + foreach ($gfiparts as $line) { + list($label, $value) = explode(": ", $line); + $gfi[$label] = isset($value) ? trim($value,"\"") : null; } } - echo "mdls; "; - $thumb = $tmpdir.basename($path).".png"; - @exec("qlmanage -t -f ".$thumb_factor." -o ".$tmpdir." \"".$path."\" 2>&1"); - if (!file_exists($thumb) && (in_array($line['ext'], $m_files) | in_array($line['ext'], $e_files))) { - @exec("ffmpegthumbnailer -i \"".$path."\" -o \"".$thumb."\" -s ".$thumb_size." -c png 2>&1"); - echo "ffmpeg-"; + + $writegfitype = @$gfi['type'].":".@$gfi['creator']; + if ($writegfitype == "\\0\\0\\0\\0:\\0\\0\\0\\0" || $writegfitype == ":") { $writegfitype = null; } + + $stmt->BindValue("gfi_type",$writegfitype); + $stmt->BindValue("gfi_attr",@$gfi['attributes']); + $stmt->BindValue("gfi_created",strtotime($gfi['created'])); + + stringPrint("gfi"); + + if ($wopt_hash && $type != "link") { + $stmt->BindValue(":hash",md5_file($pathname)); + StringPrint("hash"); + } else { + $stmt->BindValue(":hash",null); + StringPrint("(x)hash"); + } + + $thumb = $wopt_tmpdir.$filename.".png"; + @exec("qlmanage -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"); + stringPrint("fthumb"); + } else { + stringPrint("(x)fthumb"); } if (file_exists($thumb) && filesize($thumb)) { - $line['thumb'] = file_get_contents($thumb); - $line['tinfo'] = serialize(getimagesize($thumb)); + $stmt->BindValue(":tinfo",serialize(getimagesize($thumb))); } - echo "thumb; "; - if ($line['ext'] && in_array($line['ext'], $m_files)) { - $line['mediainfo'] = shell_exec("mediainfo \"".$path."\" 2>&1"); - } - echo "media; "; - if ($line['ext'] && in_array($line['ext'], $e_files)) { - $line['exiftool'] = shell_exec("exiftool \"".$path."\" 2>&1"); - } - echo "exif "; - $insert = "INSERT INTO \"".$base."\" VALUES (:id, :parent, :path, :ext, :type, :size, :hash, :perms, :owner, :inode, :mtime, :atime, :ctime, :mdls, :tags, :mediainfo, :exiftool, :tinfo)"; - $stmt = $dbo->prepare($insert); - $stmt->BindValue(":parent",$line['parent']); - $stmt->BindValue(":path",$line['path']); - $stmt->BindValue(":ext",$line['ext']); - $stmt->BindValue(":type",$line['type']); - $stmt->BindValue(":size",$line['size']); - $stmt->BindValue(":hash",$line['hash']); - $stmt->BindValue(":perms",$line['perms']); - $stmt->BindValue(":owner",$line['owner']); - $stmt->BindValue(":inode",$line['inode']); - $stmt->BindValue(":mtime",$line['mtime']); - $stmt->BindValue(":atime",$line['atime']); - $stmt->BindValue(":ctime",$line['ctime']); - $stmt->BindValue(":mdls",$line['mdls']); - $stmt->BindValue(":tags",@$line['tags']); - $stmt->BindValue(":mediainfo",@$line['mediainfo']); - $stmt->BindValue(":exiftool",@$line['exiftool']); - $stmt->BindValue(":tinfo",@$line['tinfo']); + $stmt->execute(); - echo "-> sql"; - $insert = "INSERT INTO thumbs VALUES (:id, :thumb)"; - $stmt = $dbo->prepare($insert); - $stmt->BindValue(":thumb",@$line['thumb']); - $stmt->execute(); - if (@$line['thumb']) { - echo " (thumb)"; + stringPrint("->files"); + + // Gather spotlight metadata + + $stmt = $dbo->prepare("INSERT INTO mdls VALUES (:id, :hasmeta, :DateAdded, :ContentType, :Creator, :Kind, :UserTags, :FSInvisible, :PixelWidth, :PixelHeight, :spotlight)"); + $mdls = shell_exec("mdls -plist - ".$shellpath." 2>&1"); + stringPrint("mdls"); + + if ($mdls != $pathname.": could not find ".$pathname.".\n") { + + $stmt->BindValue(":hasmeta",1); + $parser = new plistParser(); + $spotlight = $parser->parseString($mdls); + + $stmt->BindValue(":DateAdded",@$spotlight['kMDItemDateAdded']); + $stmt->BindValue(":ContentType",@$spotlight['kMDItemContentType']); + $stmt->BindValue(":Creator",@$spotlight['kMDItemCreator']); + $stmt->BindValue(":Kind",@$spotlight['kMDItemKind']); + if (isset($spotlight['kMDItemUserTags'])) { + $stmt->BindValue(":UserTags",serialize($spotlight['kMDItemUserTags'])); + } + $stmt->BindValue(":FSInvisible",@$spotlight['kMDItemFSInvisible']); + $stmt->BindValue(":PixelWidth",@$spotlight['kMDItemPixelWidth']); + $stmt->BindValue(":PixelHeight",@$spotlight['kMDItemPixelHeight']); + $stmt->BindValue(":spotlight",serialize($spotlight)); + + } else { + $stmt->BindValue(":hasmeta",0); } + $stmt->execute(); + stringPrint("->mdls"); + + // Gather external metadata + + $stmt = $dbo->prepare("INSERT INTO metadata VALUES (:id, :duration, :mediainfo, :exiftool)"); + + if ($type != "dir" && in_array($extension, $m_files)) { + $minfo = parseMediaInfo(shell_exec($bin_mediainfo." --Output=XML ".$shellpath." 2>&1")); + if ($minfo['file']['general']['duration'][0]) { + $stmt->BindValue(":duration",$minfo['file']['general']['duration'][0]); + } else { + $stmt->BindValue(":duration",null); + } + $stmt->BindValue(":mediainfo",serialize($minfo)); + stringPrint("minfo"); + } else { + $stmt->BindValue(":duration",null); + $stmt->BindValue(":mediainfo",null); + stringPrint("(x)info"); + } + + if ($type != "dir" && $type != "link" && in_array($extension, $e_files)) { + $stmt->BindValue(":exiftool",serialize(eval("return ".`$bin_exiftool -php $shellpath`))); + stringPrint("etool"); + } else { + $stmt->BindValue(":exiftool",null); + stringPrint("(x)etool"); + } + $stmt->execute(); + stringPrint("->meta"); + + // Gather thumbnail + + $stmt = $dbo->prepare("INSERT INTO thumbs VALUES (:id, :thumb)"); + if (file_exists($thumb) && filesize($thumb)) { + $stmt->BindValue(":thumb",file_get_contents($thumb)); + } else { + $stmt->BindValue(":thumb",null); + } + $stmt->execute(); + stringPrint("->thumb"); + + // 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"); + } + echo "\n"; + // Double check stat for file against pre-run value + + echo bashcolor(str_replace(array("\n"," "),array(" ",""),$stat)."\n","blue"); + + if ($wopt_paranoid && $type != "link") { + $restat = chop(@shell_exec("stat -x ".$shellpath." 2>&1")); + echo bashcolor(str_replace(array("\n"," "),array(" ",""),$restat)."\n","green"); + if ($stat != $restat) { echo "\nBREAK: stat changed on ".$pathname; die; } + } + } -$fbanner = "Finished in ".floor($time = microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"])." seconds"; +// Footer + +$seconds = floor($time = microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"]); +$fbanner = "Finished in ".$seconds." seconds"; echo str_repeat("-", strlen($fbanner))."\n".$fbanner."\n"; +echo "Files ignored: ".$ignored." / Files nodescended: ".$nodescended."\n"; + +// Write app summary values + +$dbo->exec("UPDATE _walkwalk SET nodescended=".$nodescended.", ignored=".$ignored.", status='completed_in_".$seconds."'"); ?> \ No newline at end of file diff --git a/web/icons/3dm.png b/web/icons/3dm.png new file mode 100644 index 0000000..6edd73e Binary files /dev/null and b/web/icons/3dm.png differ diff --git a/web/icons/abbu.png b/web/icons/abbu.png new file mode 100644 index 0000000..2b94774 Binary files /dev/null and b/web/icons/abbu.png differ diff --git a/web/icons/aep.png b/web/icons/aep.png new file mode 100644 index 0000000..450ffca Binary files /dev/null and b/web/icons/aep.png differ diff --git a/web/icons/ai.png b/web/icons/ai.png new file mode 100644 index 0000000..60e0f2f Binary files /dev/null and b/web/icons/ai.png differ diff --git a/web/icons/aif.png b/web/icons/aif.png new file mode 100644 index 0000000..b963416 Binary files /dev/null and b/web/icons/aif.png differ diff --git a/web/icons/aiff.png b/web/icons/aiff.png new file mode 100644 index 0000000..b963416 Binary files /dev/null and b/web/icons/aiff.png differ diff --git a/web/icons/aplibrary.png b/web/icons/aplibrary.png new file mode 100644 index 0000000..237359d Binary files /dev/null and b/web/icons/aplibrary.png differ diff --git a/web/icons/app.png b/web/icons/app.png new file mode 100644 index 0000000..1cbe630 Binary files /dev/null and b/web/icons/app.png differ diff --git a/web/icons/apvault.png b/web/icons/apvault.png new file mode 100644 index 0000000..d64eee5 Binary files /dev/null and b/web/icons/apvault.png differ diff --git a/web/icons/avi.png b/web/icons/avi.png new file mode 100644 index 0000000..48731a2 Binary files /dev/null and b/web/icons/avi.png differ diff --git a/web/icons/bdmv.png b/web/icons/bdmv.png new file mode 100644 index 0000000..abb856a Binary files /dev/null and b/web/icons/bdmv.png differ diff --git a/web/icons/bundle.png b/web/icons/bundle.png new file mode 100644 index 0000000..2638971 Binary files /dev/null and b/web/icons/bundle.png differ diff --git a/web/icons/directory.png b/web/icons/directory.png new file mode 100644 index 0000000..035e14d Binary files /dev/null and b/web/icons/directory.png differ diff --git a/web/icons/directory_alias.png b/web/icons/directory_alias.png new file mode 100644 index 0000000..f97c023 Binary files /dev/null and b/web/icons/directory_alias.png differ diff --git a/web/icons/directory_invisible.png b/web/icons/directory_invisible.png new file mode 100644 index 0000000..2d9ea11 Binary files /dev/null and b/web/icons/directory_invisible.png differ diff --git a/web/icons/disc.png b/web/icons/disc.png new file mode 100644 index 0000000..0597a19 Binary files /dev/null and b/web/icons/disc.png differ diff --git a/web/icons/dmg.png b/web/icons/dmg.png new file mode 100644 index 0000000..75b5b9b Binary files /dev/null and b/web/icons/dmg.png differ diff --git a/web/icons/dwg.png b/web/icons/dwg.png new file mode 100644 index 0000000..87da2c2 Binary files /dev/null and b/web/icons/dwg.png differ diff --git a/web/icons/dxf.png b/web/icons/dxf.png new file mode 100644 index 0000000..f0dbbf8 Binary files /dev/null and b/web/icons/dxf.png differ diff --git a/web/icons/eps.png b/web/icons/eps.png new file mode 100644 index 0000000..6bb3af7 Binary files /dev/null and b/web/icons/eps.png differ diff --git a/web/icons/firewire.png b/web/icons/firewire.png new file mode 100644 index 0000000..3450217 Binary files /dev/null and b/web/icons/firewire.png differ diff --git a/web/icons/flac.png b/web/icons/flac.png new file mode 100644 index 0000000..b963416 Binary files /dev/null and b/web/icons/flac.png differ diff --git a/web/icons/framework.png b/web/icons/framework.png new file mode 100644 index 0000000..2638971 Binary files /dev/null and b/web/icons/framework.png differ diff --git a/web/icons/gz.png b/web/icons/gz.png new file mode 100644 index 0000000..e79f0b7 Binary files /dev/null and b/web/icons/gz.png differ diff --git a/web/icons/home.png b/web/icons/home.png new file mode 100644 index 0000000..61cd22a Binary files /dev/null and b/web/icons/home.png differ diff --git a/web/icons/html.png b/web/icons/html.png new file mode 100644 index 0000000..574a2f1 Binary files /dev/null and b/web/icons/html.png differ diff --git a/web/icons/image.png b/web/icons/image.png new file mode 100644 index 0000000..3b8588e Binary files /dev/null and b/web/icons/image.png differ diff --git a/web/icons/internal.png b/web/icons/internal.png new file mode 100644 index 0000000..173e9ba Binary files /dev/null and b/web/icons/internal.png differ diff --git a/web/icons/iso.png b/web/icons/iso.png new file mode 100644 index 0000000..75b5b9b Binary files /dev/null and b/web/icons/iso.png differ diff --git a/web/icons/kext.png b/web/icons/kext.png new file mode 100644 index 0000000..2638971 Binary files /dev/null and b/web/icons/kext.png differ diff --git a/web/icons/m2ts.png b/web/icons/m2ts.png new file mode 100644 index 0000000..52aad0e Binary files /dev/null and b/web/icons/m2ts.png differ diff --git a/web/icons/m4a.png b/web/icons/m4a.png new file mode 100644 index 0000000..e07308c Binary files /dev/null and b/web/icons/m4a.png differ diff --git a/web/icons/m4v.png b/web/icons/m4v.png new file mode 100644 index 0000000..2e33fe9 Binary files /dev/null and b/web/icons/m4v.png differ diff --git a/web/icons/mask.png b/web/icons/mask.png new file mode 100644 index 0000000..c175b0f Binary files /dev/null and b/web/icons/mask.png differ diff --git a/web/icons/mkv.png b/web/icons/mkv.png new file mode 100644 index 0000000..32bfc57 Binary files /dev/null and b/web/icons/mkv.png differ diff --git a/web/icons/mp3.png b/web/icons/mp3.png new file mode 100644 index 0000000..a5f7ecc Binary files /dev/null and b/web/icons/mp3.png differ diff --git a/web/icons/mp4.png b/web/icons/mp4.png new file mode 100644 index 0000000..2e33fe9 Binary files /dev/null and b/web/icons/mp4.png differ diff --git a/web/icons/music_null.png b/web/icons/music_null.png new file mode 100644 index 0000000..25b7613 Binary files /dev/null and b/web/icons/music_null.png differ diff --git a/web/icons/null.png b/web/icons/null.png new file mode 100644 index 0000000..2106fc6 Binary files /dev/null and b/web/icons/null.png differ diff --git a/web/icons/null_alias.png b/web/icons/null_alias.png new file mode 100644 index 0000000..947f034 Binary files /dev/null and b/web/icons/null_alias.png differ diff --git a/web/icons/null_invisible.png b/web/icons/null_invisible.png new file mode 100644 index 0000000..05e83fa Binary files /dev/null and b/web/icons/null_invisible.png differ diff --git a/web/icons/overlay.png b/web/icons/overlay.png new file mode 100644 index 0000000..7b4aa60 Binary files /dev/null and b/web/icons/overlay.png differ diff --git a/web/icons/pdf.png b/web/icons/pdf.png new file mode 100644 index 0000000..a5f27c1 Binary files /dev/null and b/web/icons/pdf.png differ diff --git a/web/icons/photoslibrary.png b/web/icons/photoslibrary.png new file mode 100644 index 0000000..4853faa Binary files /dev/null and b/web/icons/photoslibrary.png differ diff --git a/web/icons/pkg.png b/web/icons/pkg.png new file mode 100644 index 0000000..ab72667 Binary files /dev/null and b/web/icons/pkg.png differ diff --git a/web/icons/plist.png b/web/icons/plist.png new file mode 100644 index 0000000..64bf1e6 Binary files /dev/null and b/web/icons/plist.png differ diff --git a/web/icons/plugin.png b/web/icons/plugin.png new file mode 100644 index 0000000..2638971 Binary files /dev/null and b/web/icons/plugin.png differ diff --git a/web/icons/psd.png b/web/icons/psd.png new file mode 100644 index 0000000..78a4861 Binary files /dev/null and b/web/icons/psd.png differ diff --git a/web/icons/rar.png b/web/icons/rar.png new file mode 100644 index 0000000..cd56cff Binary files /dev/null and b/web/icons/rar.png differ diff --git a/web/icons/rtf.png b/web/icons/rtf.png new file mode 100644 index 0000000..b4902ca Binary files /dev/null and b/web/icons/rtf.png differ diff --git a/web/icons/rtfd.png b/web/icons/rtfd.png new file mode 100644 index 0000000..b4902ca Binary files /dev/null and b/web/icons/rtfd.png differ diff --git a/web/icons/scpt.png b/web/icons/scpt.png new file mode 100644 index 0000000..85bac3f Binary files /dev/null and b/web/icons/scpt.png differ diff --git a/web/icons/sh.png b/web/icons/sh.png new file mode 100644 index 0000000..06aae07 Binary files /dev/null and b/web/icons/sh.png differ diff --git a/web/icons/sparsebundle.png b/web/icons/sparsebundle.png new file mode 100644 index 0000000..75b5b9b Binary files /dev/null and b/web/icons/sparsebundle.png differ diff --git a/web/icons/sparseimage.png b/web/icons/sparseimage.png new file mode 100644 index 0000000..75b5b9b Binary files /dev/null and b/web/icons/sparseimage.png differ diff --git a/web/icons/srt.png b/web/icons/srt.png new file mode 100644 index 0000000..f74b09c Binary files /dev/null and b/web/icons/srt.png differ diff --git a/web/icons/tar.png b/web/icons/tar.png new file mode 100644 index 0000000..4a9920b Binary files /dev/null and b/web/icons/tar.png differ diff --git a/web/icons/trash_empty.png b/web/icons/trash_empty.png new file mode 100644 index 0000000..e27da4c Binary files /dev/null and b/web/icons/trash_empty.png differ diff --git a/web/icons/trash_full.png b/web/icons/trash_full.png new file mode 100644 index 0000000..5b06860 Binary files /dev/null and b/web/icons/trash_full.png differ diff --git a/web/icons/vob.png b/web/icons/vob.png new file mode 100644 index 0000000..61e57cb Binary files /dev/null and b/web/icons/vob.png differ diff --git a/web/icons/wav.png b/web/icons/wav.png new file mode 100644 index 0000000..b963416 Binary files /dev/null and b/web/icons/wav.png differ diff --git a/web/icons/webloc.png b/web/icons/webloc.png new file mode 100644 index 0000000..f3b8179 Binary files /dev/null and b/web/icons/webloc.png differ diff --git a/web/icons/wmv.png b/web/icons/wmv.png new file mode 100644 index 0000000..d717a57 Binary files /dev/null and b/web/icons/wmv.png differ diff --git a/web/icons/zip.png b/web/icons/zip.png new file mode 100644 index 0000000..41ecacc Binary files /dev/null and b/web/icons/zip.png differ diff --git a/web/image.php b/web/image.php new file mode 100644 index 0000000..58c7817 --- /dev/null +++ b/web/image.php @@ -0,0 +1,21 @@ +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +header('Content-Type: image/png'); +echo $dbo->query("SELECT thumb FROM thumbs WHERE (id=".$id.")")->fetch()['thumb']; + +?> \ No newline at end of file diff --git a/web/rtc.php b/web/rtc.php new file mode 100644 index 0000000..b7933b4 --- /dev/null +++ b/web/rtc.php @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + $string) { + if (substr($string, 0, 2) == "a:") { + $array[$key] = unserialize($string); + } + } + return $array; + } + +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 dumpme($mixed = null) { + ob_start(); + var_dump($mixed); + $content = ob_get_contents(); + ob_end_clean(); + return $content; + } + +function breadcrumbs($dbo, $pathname) { + $zpath = $dbo->query("SELECT zpath FROM _walkwalk")->fetch()['zpath']; + $pathname_adjusted = str_replace($zpath."/", "", $pathname); + $parts = explode("/", $pathname_adjusted); + $i = count($parts); + while ($i) { + $search_path = $zpath."/".implode("/", array_slice($parts, 0, $i)); + $id = $dbo->query("SELECT id FROM files WHERE (Pathname='".$search_path."')")->fetch()['id']; + $result[] = array($id, basename($search_path)); + $i--; + } + $home = array("0",basename($zpath)); + if (basename($zpath) == $pathname) { + return array($home); + } else { + $result[] = $home; + return array_reverse($result); + } + } + +$db_dir = "db/"; +$db = $_GET['db']; +$id = $_GET['id']; +$view = $_GET['view']; +$sort = $_GET['sort']; +$db_file = $db_dir.$db.".sqlite3"; + +if (!$view) { $view = "icon"; } + +// there is no db, show a list of sqlite files + +if (!$db) { + + echo "
"; + $files = glob($db_dir."*.sqlite3"); + rsort($files); + foreach ($files as $file) { + $dbo = new PDO("sqlite:".$file); + $dbo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); + $row = $dbo->query("SELECT * FROM _walkwalk")->fetchAll(); + if ($row[0]['type'] == "External disk") { $icon = "icons/firewire.png"; } + if ($row[0]['type'] == "Startup disk") { $icon = "icons/internal.png"; } + if ($row[0]['type'] == "Disk image") { $icon = "icons/image.png"; } + if ($row[0]['type'] == "Folder") { $icon = "icons/directory.png"; } + echo "\n
"; + echo "\n"; + $parts = explode("_",basename($file, ".sqlite3")); + echo "\n".$parts[2]." (".$parts[0].")"; + echo "\n".$dbo->query("SELECT Count(*) FROM files")->fetch()['Count(*)']." Files"; + if ($dbo->query("SELECT status FROM _walkwalk")->fetch()[0] == "aborted") { + echo " (Aborted)"; + } + echo "\n"; + echo "\n
"; + } + + } else { + + $dbo = new PDO("sqlite:".$db_file); + $dbo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); + $zpath = $dbo->query("SELECT zpath FROM _walkwalk")->fetch()['zpath']; + + // there is no id, must be initial view + + if (!$id) { + + $id = 0; + $type = "dir"; + $myview['Pathname'] = basename($zpath); + + } else { + + $myview = $dbo->query("SELECT * FROM files WHERE (id=".$id.")")->fetchAll()[0]; + $type = $myview['Type']; + + } + + echo "
"; + + $crumb = breadcrumbs($dbo, $myview['Pathname']); + foreach ($crumb as $myparts) { + if ($crumb[count($crumb)-1] != $myparts) { + echo "\n".$myparts[1].""; + echo " > "; + } else { + echo $myparts[1]; + } + } + + echo ""; + + if ($view == "icon") { + echo "icon | list"; + } else { + echo "icon | list"; + } + + echo "
"; + + echo "
"; + + echo "
"; + + // directory view + + if ($type == "dir") { + + $items = $dbo->query("SELECT * FROM files WHERE (parent=".$id.")")->fetchAll(); + + if ($view == "icon") { + + foreach ($items as $item) { + echo "\n
"; + echo "\n"; + if ($item['Type'] == "dir") { + + echo ""; + + } elseif (isset($item['tinfo'])) { + + list ($twidth, $theight) = unserialize($item['tinfo']); + echo ""; + + } else { + + echo ""; + + } + + echo ""; + echo "\n".$item['Filename']; + if ($item['Type'] == "dir") { + echo " (".count($dbo->query("SELECT * FROM files WHERE (parent=".$item['id'].")")->fetchAll())." Items)"; + } + echo "\n"; + echo "\n".human_filesize($item['Size']).""; + echo "\n
"; + + } + + } else { + + echo "list"; + + } + + } else { + + // file view + + echo "
";
+		
+		$fdeep = $dbo->query("SELECT * FROM files WHERE (id=".$id.")")->fetchAll()[0];
+		$sdeep = $mdls = $dbo->query("SELECT * FROM mdls WHERE (id=".$id.")")->fetchAll()[0];
+		$mdeep = $meta = $dbo->query("SELECT * FROM metadata WHERE (id=".$id.")")->fetchAll()[0];
+		
+		echo "

".$fdeep['Pathname']."


"; + + if (isset($fdeep['tinfo'])) { + echo "
"; + } else { + echo "
"; + } + + echo dumpme(array_unserialize($fdeep)); + echo "

Spotlight


"; + echo dumpme(array_unserialize($sdeep)); + echo "

Mediainfo


"; + echo dumpme(array_unserialize($mdeep)); + + echo "
"; + + } + + } + +echo str_repeat("
", 100); + +?> + +
+ + \ No newline at end of file