///////////////////////////////////////////////////////////////// // Yuba RTC Browser ///////////////////////////////////////////////////////////////// $browser_version = "0.7.12.6"; require "togggle.php"; require "lib/ref/ref.php"; ref::config('expLvl', 1); ref::config('validHtml', TRUE); $db_dir = "data/skim"; $icon_size = 96; $pad = 40; $border_tools = array("sips","sox","ffmpeg","ql-thumbnail"); $hidefiles = array(".DS_Store"); ?>
// Functions function get_gps($gps_pos) { # convert: # 40 deg 44' 49.36" N, 73 deg 56' 28.18" W # to: # 40.7470444,-073.9411611 $parts = explode(" ",str_replace(array("deg ",",","'","\""),"",$gps_pos)); $lat_deg = $parts[0]; $lat_min = $parts[1]; $lat_sec = $parts[2]; $lat_dir = $parts[3]; $lon_deg = $parts[4]; $lon_min = $parts[5]; $lon_sec = $parts[6]; $lon_dir = $parts[7]; if ($lat_dir == "N") { $lat_sin = "+"; } else { $lat_sin = "-"; } if ($lon_dir == "E") { $lon_sin = "+"; } else { $lon_sin = "-"; } $latitiude = $lat_sin.($lat_deg+($lat_min/60)+($lat_sec/3600)); $longitude = $lon_sin.($lon_deg+($lon_min/60)+($lon_sec/3600)); return $latitiude.",".$longitude; } function is_serial($string) { return (@unserialize($string) !== false || $string == 'b:0;'); } 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 utf8_for_xml($string) { return preg_replace ('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $string); } 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 breadcrumbs($zpath, $pathname) { if (!$pathname) { return array(array(null,basename($zpath))); } else { $pathname_adjusted = str_replace($zpath."/", "", $pathname); $parts = explode("/", $pathname_adjusted); $i = count($parts); while ($i) { $search_path = $zpath."/".implode("/", array_slice($parts, 0, $i)); if ($i == count($parts)) { $result[] = array(null, basename($search_path)); } else { $result[] = array(md5($search_path), basename($search_path)); } $i--; } $result[] = array("",basename($zpath)); return array_reverse($result); } } function shortlabel($filename, $max = 40) { if (strlen($filename) > $max) { $prefix = substr($filename, 0, floor($max*.66)); $suffix = substr($filename, -floor($max*.33)); $return = $prefix."...".$suffix; } else { $return = $filename; } return $return; } function mb_shortlabel($filename, $max = 40) { if (mb_strlen($filename, mb_detect_encoding($filename)) > $max) { // more work is needed to figure out what is going on with non EN chars //echo "(-) "; $prefix = mb_substr($filename, 0, floor($max*.66), mb_detect_encoding($filename)); $suffix = mb_substr($filename, -floor($max*.33)); $return = $prefix."...".$suffix; } else { $return = $filename; } return $return; } function findicon($filename) { $ext = pathinfo($filename)['extension']; $good = "icons/null.png"; foreach (glob("icons/*.png") as $file) { if (pathinfo($file)['filename'] == $ext) { $good = $file; } } return $good; } ///////////////////////////////////////////////////////////////// $db_file = $_GET['db']; $pid = $_GET['pid']; $search = $_POST['query']; $parser = new plistParser(); if ($db_file) { if (!is_readable($db_file)) { echo "can't read db file"; die; } $dbo = new PDO("sqlite:".$db_file); $dbp = new PDO("sqlite:".dirname($db_file)."/pool.sqlite3"); $dbo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $dbo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $dbp->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $dbp->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Get zpath $zpath = $dbo->query("SELECT zpath FROM _skim")->fetch()['zpath']; $skim_version = $dbo->query("SELECT version FROM _skim")->fetch()['version']; // Check for initial view $view = $dbo->query("SELECT * FROM _skim")->fetch(); if (!$pid) { $pid = $dbo->query("SELECT pid FROM family WHERE (rowid=2)")->fetch()['pid']; // handle special strings $view['opts'] = unserialize($view['opts']); $view['qlmanage'] = array($view['qlmanage']); $view['profile'] = array($view['profile']); if ($view['details']) { $view['details'] = unserialize($view['details']); } if (substr($view['disks'],0,5) == "parseString(utf8_for_xml($view['disks'])); } else { $view['disks'] = $view['disks']; } if (substr($view['diskutil'],0,5) == "parseString(utf8_for_xml($view['diskutil'])); } else { $view['diskutil'] = $view['diskutil']; } if ($view['vdisks']) { $view['vdisks'] = $parser->parseString(utf8_for_xml($view['vdisks'])); } if ($view['hdiutil']) { $view['hdiutil'] = $parser->parseString(utf8_for_xml($view['hdiutil'])); } $view['Type'] = "dir"; } else { $view = $dbo->query("SELECT rowid, * FROM files WHERE (pid='".$pid."')")->fetch(); if (is_serial($view['stat'])) { $view['stat'] = unserialize($view['stat']); } $dirmdls = $dbo->query("SELECT rowid, * FROM mdls WHERE (rowid='".$view['rowid']."')")->fetch(); } // Header echo "| ";
if (is_serial($row_a['stat'])) {
$row_a['stat'] = unserialize($row_a['stat']);
}
if (!strpos($spotlight_status,"disabled")) {
$row_b = $dbo->query("SELECT * FROM mdls WHERE (rowid='".$row_a['rowid']."')")->fetch();
$row_e = @$dbo->query("SELECT * FROM milk WHERE (rowid='".$row_a['rowid']."')")->fetch();
}
if (version_compare($skim_version,"0.7.7b") > -1) {
// newer version stores rowid rather than 0 or 1 for has_exif etc
if (isset($row_a['has_exif'])) {
$row_c = $dbp->query("SELECT * FROM exiftool WHERE (rowid='".$row_a['has_exif']."')")->fetch();
}
if (isset($row_a['has_mediainfo'])) {
$row_d = $dbp->query("SELECT * FROM mediainfo WHERE (rowid='".$row_a['has_mediainfo']."')")->fetch();
}
} else {
// fetch exif and mediainfo by slower fid
$row_c = $dbp->query("SELECT * FROM exiftool WHERE (fid='".$row_a['fid']."')")->fetch();
$row_d = $dbp->query("SELECT * FROM mediainfo WHERE (fid='".$row_a['fid']."')")->fetch();
}
if ($row_a['thumb_filename']) {
$width = $row_a['thumb_width'];
$height = $row_a['thumb_height'];
$realfile = dirname($db_file).$row_a['thumb_filename'];
if (array_key_exists("thumb_tool",$row_a)) {
if (in_array($row_a['thumb_tool'], $border_tools)) {
// put a border around images that are not icons
$border = "id='thumb'";
} else {
$border = "";
}
} else {
$border = "id='thumb'";
}
$icon = " ";
foreach($row_e as $title => $val) {
if ($title == "GPS" && $val) {
if (strpos($val,"deg") != false) {
$val = get_gps($val);
}
$print = "".$val."";
} else {
$print = $val;
}
echo " ";
}
// debug file times
$fileinfo['atime (php)'] = date("F jS, Y h:i:s",$row_a['ATime']);
$fileinfo['mtime (php)'] = date("F jS, Y h:i:s",$row_a['MTime']);
$fileinfo['ctime (php)'] = date("F jS, Y h:i:s",$row_a['CTime']);
if ($row_a['stat']) {
if (is_array($row_a['stat'])) {
$fileinfo['atime (stat)'] = date("F jS, Y h:i:s",$row_a['stat']['st_atime']);
$fileinfo['mtime (stat)'] = date("F jS, Y h:i:s",$row_a['stat']['st_mtime']);
$fileinfo['ctime (stat)'] = date("F jS, Y h:i:s",$row_a['stat']['st_ctime']);
$fileinfo['btime (stat)'] = date("F jS, Y h:i:s",$row_a['stat']['st_birthtime']);
} else {
// parse old version stat
preg_match('/^Access: ([^\r\n]*)/m', $row_a['stat'], $access);
$fileinfo['atime (stat)'] = date("F jS, Y h:i:s",strtotime($access[1]));
preg_match('/^Modify: ([^\r\n]*)/m', $row_a['stat'], $modify);
$fileinfo['mtime (stat)'] = date("F jS, Y h:i:s",strtotime($modify[1]));
preg_match('/^Change: ([^\r\n]*)/m', $row_a['stat'], $change);
$fileinfo['ctime (stat)'] = date("F jS, Y h:i:s",strtotime($change[1]));
}
}
if ($row_b['spotlight']) {
$row_b['spotlight'] = $parser->parseString(utf8_for_xml($row_b['spotlight']));
$fileinfo['added (mdls)'] = date("F jS, Y h:i:s",$row_b['DateAdded']);
$fileinfo['mtime (mdls)'] = date("F jS, Y h:i:s",$row_b['ContentModificationDate']);
$fileinfo['btime (mdls)'] = date("F jS, Y h:i:s",$row_b['ContentCreationDate']);
}
ksort($fileinfo);
echo "".$title."".$print." ";
}
echo "";
foreach ($fileinfo as $title => $value) {
echo " ";
if ($dbo->query("SELECT name FROM sqlite_master WHERE name='dupes'")->fetch()) {
$dupes = $dbo->query("SELECT dupes FROM dupes WHERE (fid='".$row_a['fid']."')")->fetch();
if ($dupes) {
$count = count(unserialize($dupes['dupes']));
echo "";
}
}
echo "".$title."".$value." ";
}
echo " | ";
echo ""; r($row_a); if ($row_b['spotlight']) { r($row_b); } echo " | "; if ($row_c) { r(unserialize($row_c['tags'])); } ref::config('expLvl', 2); if ($row_d) { if (substr($row_d['info'],0,5) == "File->track); } else { r(json_decode(utf8_encode($row_d['info']), true)['media']['track']); } } echo " | "; echo "
";
echo "
"; } } } else { // this is a text search if (strlen($search) == 32) { $result = $dbo->query("SELECT * FROM files WHERE (fid = '".$search."')")->fetchAll(); $label = "hash"; } else { $result = $dbo->query("SELECT * FROM files WHERE (Filename LIKE '%".$search."%')")->fetchAll(); $label = "text"; } if (count($result)) { echo count($result)." ".$label." results "; foreach ($result as $row) { $pathbold = str_ireplace($search,"".$search."",$row['Pathname']); echo "\n".$pathbold." "; } } else { echo "No results for ".$label." ".$search; } } } } else { ///////////////////////////////////////////////////////////////// // DB List echo "toggle all"; $icons['Disk image'] = "/icons/dmg.png"; $icons['Folder'] = "/icons/directory.png"; $icons['External disk'] = "/icons/firewire.png"; $icons['Startup disk'] = "/icons/internal.png"; $bundles = glob($db_dir."/*.bundle"); foreach ($bundles as $bundle) { $exploded = explode("_", $bundle); $sorted_bundles[$exploded[1]] = $bundle; } ksort($sorted_bundles); foreach ($sorted_bundles as $key => $bundle) { echo " ";
$dbs = array_reverse(glob($bundle."/????-??-??_??-??-??.sqlite3"));
if ($dbs[0]) {
$dbo = new PDO("sqlite:".$dbs[0]);
$type = $dbo->query("SELECT type FROM _skim")->fetch()['type'];
echo " ".pathinfo($bundle)['filename']." (".$info['passed_total'].")"; echo "";
foreach ($dbs as $db_file) {
$dbo = new PDO("sqlite:".$db_file);
$info = $dbo->query("SELECT * FROM _skim")->fetch();
if (strpos($info['status'],"completed") === 0) {
$seconds = str_replace("completed_in_","",$info['status']);
$s = (int)$seconds;
$status = sprintf("%02d:%02d:%02d:%02d", $s/86400, $s/3600%24, $s/60%60, $s%60);
echo " ";
}
}
/////////////////////////////////////////////////////////////////
echo "";
} else {
echo " ";
echo "";
}
echo "".pathinfo($db_file)['filename']." ";
echo $info['version'].", ";
echo number_format($info['passed_total'])." files, ";
if ($info['image_file']) { echo $info['image_file'].", "; }
echo $status;
if (strpos($info['mdutil'],"disabled")) { echo " (no spotlight)"; }
echo " ";
}
echo "".round($time = microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"],2)." seconds ";
echo "Skim version = ".$skim_version.", RTC Browser Version = ".$browser_version." ";
?>
|