<?

/////////////////////////////////////////////////////////////////
// Yuba RTC Browser
/////////////////////////////////////////////////////////////////

$browser_version = "0.4.5";

date_default_timezone_set("America/Los_Angeles");

$method = "id";

?>

<html>
<head>

<meta charset="utf-8">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://raw.githubusercontent.com/bd808/php-unserialize-js/master/phpUnserialize.js"></script>

<style>

body { margin: 20px; font-family: helvetica; font-size: 16px; }
*:focus { outline: none !important }
a { color: black; }

div { font-size: 11px; }
div.container { display: flex; flex-flow: row wrap; justify-content: center; }
div.flexfill { width: 220px; height: 1px; }
div.item { width: 190px; height: 220px; padding: 20px; }
div.item img.thumb { margin-bottom: 20px; padding: 5px; border: 1px solid #e7e6dc; }
div.item img:not(.thumb) { margin-left: -10px; }

span.material { display: block; word-break:break-all; }
span.materialsub { display: block; color: #bdbdbd; }
i { font-style: normal; color: red; }

div#spacer { display: inline; float: left; width: 5px; }
div#label { display: inline; float: left; width: 10px; height: 10px; border-radius: 50%; }
div#label.Red { background: #ef7063; }
div#label.Orange { background: #f3ad5f; }
div#label.Yellow { background: #f8d76b; }
div#label.Green { background: #9bde76; }
div#label.Blue { background: #73bcf4; }
div#label.Purple { background: #cc94e2; }
div#label.Gray { background: #a4a4a7; }

td { height: 32px; padding-left: 10px; padding-right: 10px; }
td.list { font-size: 11px; }

pre { overflow-x:scroll; }

div.item {
	user-drag: none;
	user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	-webkit-user-drag: none;
	-webkit-user-select: none;
	-webkit-tap-highlight-color: rgba(0,0,0,0);
	}

.tooltip:hover:after{
	font-size: 9px;
	display: block;
    unicode-bidi: embed;
    font-family: monospace;
    white-space: pre;
    background: #333;
    background: rgba(0,0,0,.8);
    border-radius: 5px;
    bottom: 26px;
    color: #fff;
    content: attr(tooltip);
    right: 20%;
    padding: 5px 15px;
    position: absolute;
    z-index: 98;
    width: 500px;
}

</style>

</head>
<body>

<?

$db_dir = "data/db/";
$db = $_GET['db'];
$id = $_GET['id'];
$view = $_GET['view'];
$sort = $_GET['sort'];
$db_file = $db_dir.$db.".sqlite3";

if (!$view) { $view = "icon"; }

function array_unserialize($array) {
	foreach ($array as $key => $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 human_date($epoch, $short = null) {
	if ($short) {
	    return date("m/d/Y", $epoch);
		} else {
		return date("m/d/Y g:iA", $epoch);
		}
	}

function dumpme($mixed = null) {
  ob_start();
  var_dump($mixed);
  $content = ob_get_contents();
  ob_end_clean();
  return $content;
  }

function hasicon($filename) {
	$ext = pathinfo($filename)['extension'];
	$good = "icons/null.png";
	foreach (glob("icons/*.png") as $file) {
		if (pathinfo($file)['filename'] == $ext) {
			$good = $file;
			}
		}
	return $good;
	}

function makeicon($dbo, $id) {

	global $db, $view, $sort;
	
	$item = $dbo->query("SELECT * FROM files WHERE (id=".$id.")")->fetchAll()[0];
	$mdls = $dbo->query("SELECT * FROM mdls WHERE (id=".$id.")")->fetchAll()[0];
	
	if ($view == "list") {
		$size = 32;
		$multiplier = 8;
		} else {
		$size = 128;
		$multiplier = 2;
		}

	if ($mdls['FSInvisible']) {
		$diricon = "/icons/directory_invisible.png";
		$fileicon = "/icons/null_invisible.png";
		} elseif ($mdls['Kind'] == "Alias" || $item['Type'] == "link") {
		$diricon = "/icons/directory_alias.png";
		$fileicon = "/icons/null_alias.png";
		} else {
		$diricon = "/icons/directory.png";
		$fileicon = hasicon($item['Filename']);
		}

	$out = "\n<a href='finder.php?db=".$db."&id=".$item['id']."&view=".$view."&sort=".$sort."'>";

	$isdir = false;
		
	if ($item['Type'] == "link") {
		$target_type = $dbo->query("SELECT Type FROM files WHERE (pathname='".$item['RealPath']."')")->fetch()['Type'];
		}

	if ($item['Type'] == "dir" || $target_type == "dir") {
		
		$out .= "<img src='".$diricon."' width='".$size."' height='".$size."'></a>";
		
		} elseif (isset($item['tinfo'])) {
					
		list ($twidth, $theight) = unserialize($item['tinfo']);
		$out .= "<img src='/image.php?db=".$db."&id=".$item['id']."' width='".($twidth/$multiplier)."' height='".($theight/$multiplier)."' class='thumb'>";
					
		} else {
					
		$out .= "<img src='".$fileicon."' width='".$size."' height='".$size."'>";
					
		}
					
	$out .= "</a>";
		
	return $out;	
		
	}

function breadcrumbs($dbo, $pathname) {

	$zpath = $dbo->query("SELECT zpath FROM _walkwalk")->fetch()['zpath'];
	$pathname_adjusted = str_replace($zpath."/", "", $pathname);
	
	//echo "pathname = ".$pathname."<br>pathname_adjusted = ".$pathname_adjusted."<br>zpath = ".$zpath."<br>";
	
	$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='".str_replace("'", "''", $search_path)."')")->fetch()['id'];
		if ($i == count($parts)) {
			$result[] = array(null, basename($search_path));
			} else {
			$result[] = array($id, basename($search_path));
			}
		$i--;
		}

	if ($pathname == $zpath) {
		return array(array(null,basename($zpath)));
		} else {
		$result[] = array("1",basename($zpath));
		return array_reverse($result);
		}
		
	}

// there is no db, show a list of sqlite files

if (!$db) {

	echo "<div class='container'>";
	$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"; }

		$version = $dbo->query("SELECT version FROM _walkwalk")->fetch()['version'];

		$base = basename($file,".sqlite3");
		echo "\n<div class='item'>";
		echo "\n<a href='?db=".$base."&id=1&view=".$view."&sort=name'><img src='".$icon."' title='".$row[0]['stats']."' width='128' height='128'></a>";
		$title = substr($base, 20,strlen($base));
		$date = substr($base, 0,10);
		echo "\n<span class='material'>".$title." (".$date.")</a></span>";
		
		if (str_replace(".","",substr($version,0,5)) > 44) {
			 echo "\n<span class='materialsub'>".$dbo->query("SELECT items FROM files WHERE (".$method."=1)")->fetch()['items']." items";
			}
		if ($dbo->query("SELECT status FROM _walkwalk")->fetch()['status'] == "aborted") {
			echo " <i>(Aborted)</i>";
			}
		echo "\n<span class='materialsub'>".$version."</span>";
		echo "\n</span>";
		echo "\n</div>";
		
		$dbo = null;

		}
		
	} else {
	
	$dbo = new PDO("sqlite:".$db_file);
	$dbo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
	
	$dbo->query("PRAGMA page_size = 8192");
	$dbo->query("PRAGMA cache_size = 20000");
	$dbo->query("PRAGMA locking_mode = EXCLUSIVE");
	$dbo->query("PRAGMA synchronous = NORMAL");
	$dbo->query("PRAGMA journal_mode = WAL");
	
	$zpath = $dbo->query("SELECT zpath FROM _walkwalk")->fetch()['zpath'];
	
	$myview = $dbo->query("SELECT * FROM files WHERE (".$method."=".$id.")")->fetchAll()[0];
	$type = $myview['Type'];

	echo "<table width='100%'><tr><td>";

	echo "<a href='finder.php'>&larr;</a>&nbsp;&nbsp;";

	$crumb = breadcrumbs($dbo, $myview['Pathname']);
	
	foreach ($crumb as $myparts) {
		if ($myparts[0] === null) {
			echo $myparts[1];
			} else {
			echo "\n<a href='finder.php?db=".$db."&id=".$myparts[0]."&view=".$view."&sort=".$sort."'>".$myparts[1]."</a> > ";
			}
		}

	echo "</td><td width='200'>";

	if ($view == "icon") {
		echo "icon | <a href='finder.php?db=".$db."&id=".$id."&view=list&sort=".$sort."'>list</a>";
		} else {
		echo "<a href='finder.php?db=".$db."&id=".$id."&view=icon&sort=".$sort."'>icon</a> | list";
		}
	
	echo " | ";
	
	echo "<select onchange=\"window.location = 'finder.php?db=".$db."&id=".$id."&view=".$view."&sort='+this.value;\">";
	echo "<option value='name' "; if ($sort == "name") { echo "selected"; } echo ">name</option>";
	echo "<option value='size' "; if ($sort == "size") { echo "selected"; } echo ">size</option>";
	echo "<option value='modified' "; if ($sort == "modified") { echo "selected"; } echo ">modified</option>";
	echo "</select>";

	echo "</td></tr></table>";

	echo "<hr>";

	echo "<div class='container'>";
	
	$row = $dbo->query("SELECT * FROM _walkwalk")->fetchAll();
	if ($row[0]['type'] == "Startup disk") { echo "Finder.php cannot handle \"/\""; die; }
	
	if ($type == "dir") {
		
		if ($sort == "name") { $sortby = "Filename ASC"; }
		if ($sort == "size") { $sortby = "Size DESC"; }
		if ($sort == "modified") { $sortby = "MTime DESC"; }
		
		//$build = unserialize($dbo->query("SELECT children FROM patch WHERE (id=".$id.")")->fetch()['children']);
		//$items = $dbo->query("SELECT * FROM files WHERE id IN (".implode(", ", $build).") ORDER BY ".$sortby)->fetchAll();
		//foreach ($dbo->query("SELECT id FROM patch WHERE (parent=".$id.")")->fetchAll() as $array) { $build[] = $array['id']; }
		//$items = $dbo->query("SELECT * FROM files WHERE id IN (".implode(", ", $build).") ORDER BY ".$sortby)->fetchAll();
		$items = $dbo->query("SELECT * FROM files WHERE (parent=".$id.") ORDER BY ".$sortby)->fetchAll();
		
		if ($view == "icon") {
		
			foreach ($items as $item) {
				echo "\n<div class='item'>";
				echo makeicon($dbo, $item['id']);
				echo "\n<span class='material'>";
				$tags = null;
				$tags = @unserialize($dbo->query("SELECT UserTags FROM mdls WHERE (id=".$item['id'].")")->fetch()['UserTags']);
				if ($tags) {
					foreach ($tags as $tag) {
						echo "<div id='label' class='".$tag."'>&nbsp;</div>";
						}
					echo "<div id='spacer'>&nbsp;</div>";
					}
				echo $item['Filename'];
				if ($item['Type'] == "dir" || $item['Type'] == "bundle" ) {
					echo " (".$item['items']." Items)";
					}
				echo "\n</span>";
				echo "\n<span class='materialsub'>".human_date($item['MTime'],1)."</span>";
				echo "\n<span class='materialsub'>".human_filesize($item['Size'])."</span>";
				echo "\n</div>";
				
				}
				
			} else {
			
			?>
			
			<table>
			<thead>
			<tr>
			<th>&nbsp;</th>
			<th>Filename</th>
			<th>Size</th>
			<th>Kind</th>
			<th>Items</th>
			<th>Modified</th>
			<th>Created</th>
			<th>Added</th>
			<th>Dimensions</th>
			<th>Duration</th>
			<th>DateTime</th>
			<th>Metadata</th>
			</tr>
			</thead><tbody>
			
			<?
			
			foreach ($items as $item) {
			
				$mdls = $dbo->query("SELECT * FROM mdls WHERE (".$method."=".$item['id'].")")->fetchAll()[0];
				$meta = $dbo->query("SELECT * FROM metadata WHERE (".$method."=".$item['id'].")")->fetchAll()[0];
				
				$etool = null;
				$minfo = null;
				$sinfo = @unserialize($mdls['spotlight']);
				$etool = @unserialize($meta['exiftool']);
				$minfo = @unserialize($meta['mediainfo']);
				
				$build = array();
				$build[] = makeicon($dbo, $item['id']);
				
				$subbuild = array();
				if ($tags) {
					foreach ($tags as $tag) {
						$subbuild[] = "<div id='label' class='".$tag."'>&nbsp;</div>";
						}
					$subbuild[] = "<div id='spacer'>&nbsp;</div>";
					}
					
				$subbuild[] = $item['Filename'];
				$build[] = implode($subbuild);
				
				$build[] = human_filesize($item['Size']);
				
				$kind = null;
				if ($mdls['Kind']) {
					$kind = $mdls['Kind'];
					} elseif ($item['gfi_type']) {
					$kind = $item['gfi_type'];
					} elseif ($mdls['Kind'] == "Alias") {
					$kind = "Alias";
					} else {
					$kind = ucfirst($item['Type']);
					}
				$build[] = $kind;
				
				$build[] = $item['items'];
				
				$build[] = @human_date($item['MTime']);
				$build[] = @human_date($item['gfi_created']);
				$build[] = @human_date($mdls['DateAdded']);
				
				if ($mdls['PixelWidth']) {
					$build[] = $mdls['PixelWidth']." x ".$mdls['PixelHeight']." pixels";
					} elseif ($etool[0]['ImageWidth']) {
					$build[] = $etool[0]['ImageWidth']." x ".$etool[0]['ImageHeight']." pixels";
					} elseif ($sinfo['kMDItemPageWidth']) {
					$build[] = round($sinfo['kMDItemPageWidth'],2)." x ".round($sinfo['kMDItemPageHeight'], 2)." points";
					} else {
					$build[] = "";
					}
				
				$duration = null;
				if ($meta['duration']) {
					$duration = $meta['duration'];
					} elseif ($etool[0]['MediaDuration']) {
					$duration = $etool[0]['MediaDuration'];
					}
				
				$build[] = $duration;
				
				$dto = null;
				if ($etool[0]['DateTimeOriginal']) {
					$dto = @human_date(strtotime($etool[0]['DateTimeOriginal']));
					}
				$build[] = $dto;
				
				$subbuild = array();
				if ($minfo) {
					$subbuild[] = "<a tooltip='".str_replace("'", "&#39;",htmlentities(dumpme($minfo)))."' class='tooltip'>[M]</a>";
					}
				if ($etool) {
					$subbuild[] = "<a tooltip='".str_replace("'", "&#39;",htmlentities(dumpme($etool)))."' class='tooltip'>[E]</a>";
					}
				
				$build[] = implode(" ", $subbuild);
					
				echo "<tr>";
				foreach ($build as $piece) {
					echo "<td class='list'>".$piece."</td>";
					}
				echo "</tr>";
			
				}
				
			echo "</tbody></table>";
			
			}
		
		} else {
		
		// file view
		
		echo "<pre>";
		
		$fdeep = $dbo->query("SELECT * FROM files WHERE (id=".$id.")")->fetchAll()[0];
		$sdeep = $dbo->query("SELECT * FROM mdls WHERE (id=".$id.")")->fetchAll()[0];
		$mdeep = $dbo->query("SELECT * FROM metadata WHERE (id=".$id.")")->fetchAll()[0];
		
		echo "<h1>".$fdeep['Pathname']."</h1><hr>"; 
		
		echo "<textarea rows='1' cols='100'>file://".$fdeep['Pathname']."</textarea>";
		echo "<textarea rows='1' cols='100'>show ".escapeshellarg($fdeep['Pathname'])."</textarea>";
		echo "<textarea rows='1' cols='40'>".$fdeep['hash']."</textarea><br><br>";
		
		if (isset($fdeep['tinfo'])) {
			echo "<img src='/image.php?db=".$db."&id=".$id."' width='".$twidth."' height='".$theight."' class='thumb'><br><br>";
			} else {
			echo "<img src='/icons/null.png' width='128' height='128'><br><br>";
			}
		
		echo dumpme(array_unserialize($fdeep));
		echo "<h1>Spotlight</h1><hr>";
		echo dumpme(array_unserialize($sdeep));
		echo "<h1>Mediainfo</h1><hr>";
		echo dumpme(array_unserialize($mdeep));
		
		echo "</pre>";
		
		}
	
	}

echo str_repeat("<div class='flexfill'></div>", 100);

echo "</div>";

if ($type == "dir") {
	echo "<hr>";
	echo count($dbo->query("SELECT * FROM files WHERE (parent=".$id.")")->fetchAll())." Items, ";
	echo human_filesize($dbo->query("SELECT Size FROM files WHERE (id=".$id.")")->fetch()['Size']);
	}

echo " ~ ".round(microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"],2)." seconds";

$dbo = null;

?>

</body>
</html>