This commit is contained in:
2019-04-27 00:48:25 -07:00
parent 9884d19108
commit 756ea17f99
5 changed files with 263 additions and 67 deletions

27
web/handle_zip.php Normal file
View File

@@ -0,0 +1,27 @@
<?
$types['txt'] = "text/plain";
$types['log'] = "text/plain";
$types['csv'] = "text/plain";
$types['webloc'] = "application/xml";
$types['svg'] = "image/svg+xml";
//$types['rtf'] = "application/rtf";
$types['rtfd'] = "application/rtf";
$types['doc'] = "application/msword";
$types['docx'] = "application/msword";
require "togggle.php";
$zip = new ZipArchive;
$zip->open($_GET['file']);
$stat = $zip->statIndex(0);
if (!$mime = $types[pathinfo($stat['name'],PATHINFO_EXTENSION)]) {
$mime = "text/plain";
}
header("Content-Type: ".$mime);
header("Content-Length: ".$stat['size']);
echo $zip->getFromIndex(0);
?>

View File

@@ -4,14 +4,14 @@
// Yuba RTC Browser
/////////////////////////////////////////////////////////////////
$browser_version = "0.7.9.2";
$browser_version = "0.7.10.3";
require "togggle.php";
require "lib/debug.php";
$db_dir = "skim";
$icon_size = 64;
$pad = 28;
$db_dir = "data/skim";
$icon_size = 96;
$pad = 40;
?>
@@ -25,10 +25,16 @@ html { font-family: Helvetica; word-wrap: break-word; }
div#exectime { position: absolute; right: 8px; top: 8px; }
div.container { display: flex; flex-flow: row wrap; justify-content: center; }
div.item { width: <?=$icon_size+$pad;?>px; height: <?=$icon_size+$pad;?>px; padding: <?=$pad;?>px; }
div.item { width: <?=$icon_size+$pad;?>px; height: <?=$icon_size+$pad;?>px; padding-bottom: <?=$pad;?> }
div.item { font-size: 11px; }
div.flexfill { width: <?=$icon_size+($pad*3);?>px; height: 1px; }
div.flexfill { width: <?=$icon_size+$pad;?>px; height: 1px; }
div.aborted { text-decoration: line-through; }
.slider, .slow_slider { position: absolute !important; top: 50px; right: 10px; width: 200px; }
.controls { position: absolute !important; top: 85px; right: 10px; width: 30px; }
form { margin-block-end: 0em !important; }
.arrow { font-size: 8px; opacity: .7; }
img.tiny { vertical-align: middle; width: 18px; height: 18px; margin: 0px 4px 0px 0px; }
.red { background-color: #ea6c60; }
.green { background-color: #9cde70; }
@@ -66,9 +72,85 @@ a.hidden img { opacity: .3; }
iframe { width: 425px; height: 550px; padding: 6px; border: 1px solid black; }
div.dblist { display: none; }
</style>
<script src="lib/lazysizes.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lazysizes/4.1.5/lazysizes.min.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css">
<script type="text/javascript">
function wrapImg(xfactor) {
var maxWidth = 0;
var maxHeight = 0;
$('div.item').each(function() {
$(this).width((<?=$icon_size?>*xfactor)+<?=$pad;?>);
$(this).height((<?=$icon_size?>*xfactor)+<?=$pad;?>);
img = $(this).find('img');
swidth = $(img).data('width')*xfactor;
sheight = $(img).data('height')*xfactor;
$(img).width(swidth);
$(img).height(sheight);
fileinfo = $(this).find('div.title');
if (xfactor > 2) {
$(this).css("font-size", 16);
} else if (xfactor < .7) {
$(this).css("font-size", 9);
} else {
$(this).css("font-size", 12);
}
})
$('div.flexfill').width((<?=$icon_size?>*xfactor)+<?=$pad;?>);
}
$(function(){
$("h2").click(function(){
$(this).next('.dblist').toggle();
});
$(".toggler").click(function(){
$('.dblist').toggle();
});
$(".info").click(function(){
$('.sidebar').toggle();
});
$(".slider").slider({
step: .01,
min: .5,
max: 3,
value: 1,
slide: function(event, ui) {
wrapImg(ui.value);
},
});
$(".slow_slider").slider({
step: .25,
min: .5,
max: 3,
value: 1,
stop: function(event, ui) {
wrapImg(ui.value);
},
});
$("select").on("change", function () {
var db = $(this).val();
var href = new URL(window.location.href);
href.searchParams.set('db', db);
window.location = href;
});
});
</script>
</head>
@@ -151,7 +233,7 @@ class plistParser extends XMLReader {
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);
//default: throw new Exception(sprintf("Not a valid plist. %s is not a valid type", $this->name), 4);
}
}
private function parse_dict() {
@@ -191,9 +273,12 @@ function breadcrumbs($zpath, $pathname) {
}
function shortlabel($filename, $max = 40) {
$suffix = "(...).".pathinfo($filename)['extension'];
if (strlen($filename) > $max) {
$return = substr($filename, 0, ($max-strlen($suffix))).$suffix;
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 = substr($filename, -floor($max*.33));
$return = $prefix."...".$suffix;
} else {
$return = $filename;
}
@@ -219,9 +304,6 @@ $search = $_POST['query'];
$parser = new plistParser();
if ($db_file) {
echo "<a href='?db='>db list</a>";
echo "<hr>";
if (!is_readable($db_file)) { echo "can't read db file"; die; }
@@ -237,9 +319,10 @@ if ($db_file) {
// 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'];
$view = $dbo->query("SELECT * FROM _skim")->fetch();
// handle special strings
$view['opts'] = unserialize($view['opts']);
$view['qlmanage'] = "hidden"; //array($view['qlmanage']);
@@ -264,6 +347,7 @@ if ($db_file) {
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'])) {
@@ -271,6 +355,22 @@ if ($db_file) {
}
$dirmdls = $dbo->query("SELECT rowid, * FROM mdls WHERE (rowid='".$view['rowid']."')")->fetch();
}
// Header
echo "<a href='?db='><img class='tiny' src='icons/home.png'>Home</a> <span class='arrow'>&#9658; </span>";
$dbs = glob(pathinfo($_GET['db'],PATHINFO_DIRNAME)."/????-??-??_??-??-??.sqlite3");
rsort($dbs);
echo "<select>";
foreach ($dbs as $db) {
echo "<option value='".$db."'";;
if ($_GET['db'] == $db) {
echo " selected";
}
echo ">".basename($db)."</option>";
}
echo "</select>";
echo "<hr>";
// Breadcrumbs
@@ -279,9 +379,14 @@ if ($db_file) {
foreach ($crumb as $myparts) {
if ($myparts[0] === null) {
$xc .= $myparts[1];
if ($view['Type'] == "dir") {
$myicon = "icons/directory.png";
} else {
$myicon = "icons/null.png";
}
$xc .= "<img class='tiny' src='".$myicon."'>".$myparts[1];
} else {
$xc .= "<a href='?db=".$db_file."&pid=".$myparts[0]."'>".$myparts[1]."</a> > ";
$xc .= "<a href='?db=".$db_file."&pid=".$myparts[0]."'><img class='tiny' src='icons/directory.png'>".$myparts[1]."</a> <span class='arrow'>&#9658;</span> ";
}
}
if (!$search) { echo $xc; echo "<hr>"; }
@@ -450,29 +555,42 @@ if ($db_file) {
} elseif (!$search) {
if (count($children) > 3000) {
echo "<div class='slow_slider'></div>";
} else {
echo "<div class='slider'></div>";
}
echo "<div class='controls'><a href='#' class='info'>info</a></div>";
echo "<table><tr><td valign='top'>";
echo "<div class='container'>";
foreach ($children as $item) {
$spotlight_status = $dbo->query("SELECT mdutil FROM _skim")->fetch()['mdutil'];
$sql = "SELECT mdls.*, files.*, milk.* FROM files ";
$sql .= "LEFT JOIN mdls ON (files.rowid = mdls.rowid) ";
$sql .= "LEFT JOIN milk ON (files.rowid = milk.rowid) ";
$sql .= "WHERE files.rowid IN (".implode(",",$children).") ";
$sql .= "ORDER BY files.Filename COLLATE NOCASE";
$rows = $dbo->query($sql)->fetchAll();
foreach ($rows as $item) {
//print_r($item);
$myname = $item['Filename'];
echo "<div class='item'>";
/////////////////////////
$row_a = $dbo->query("SELECT rowid, * FROM files WHERE (rowid='".$item."')")->fetch();
$row_b = $dbo->query("SELECT rowid, * FROM mdls WHERE (rowid='".$item."')")->fetch();
//$row_c = $dbo->query("SELECT * FROM milk WHERE (rowid='".$item."')")->fetch();
/////////////////////////
if ($row_b['FSInvisible']) {
if ($item['FSInvisible'] | substr($item['Filename'],0,1) == ".") {
$visibility = "hidden";
} else {
$visibility = "unhidden";
}
if ($row_a['thumb_filename']) {
$aspect = $row_a['thumb_width']/$row_a['thumb_height'];
if ($item['thumb_filename']) {
$aspect = $item['thumb_width']/$item['thumb_height'];
if ($aspect > 1) {
$width = $icon_size;
$height = $icon_size/$aspect;
@@ -480,35 +598,35 @@ if ($db_file) {
$width = $icon_size*$aspect;
$height = $icon_size;
}
$realfile = dirname($db_file).$row_a['thumb_filename'];
$icon = "<img id='thumb' class='lazyload' data-src='".$realfile."' width='".$width."' height='".$height."'>";
} elseif ($row_a['Type'] == "dir") {
$icon = "<img src='/icons/directory.png' width='".$icon_size."' height='".$icon_size."'>";
$realfile = dirname($db_file).$item['thumb_filename'];
$icon = "<img id='thumb' class='lazyload' data-src='".$realfile."' width='".$width."' height='".$height."' data-width='".$width."' data-height='".$height."'>";
} elseif ($item['Type'] == "dir") {
$icon = "<img src='/icons/directory.png' width='".$icon_size."' height='".$icon_size."' data-width='".$icon_size."' data-height='".$icon_size."'>";
} else {
$icon = "<img src='".findicon($row_a['Filename'])."' width='".$icon_size."' height='".$icon_size."'>";
$icon = "<img src='".findicon($item['Filename'])."' width='".$icon_size."' height='".$icon_size."' data-width='".$icon_size."' data-height='".$icon_size."'>";
}
echo "\n<a class='".$visibility."' href='?db=".$db_file."&pid=".$row_a['pid']."'>".$icon."</a>";
echo "\n<a class='".$visibility."' href='?db=".$db_file."&pid=".$item['pid']."'>".$icon."</a>";
echo "<div class='title'>";
if ($row_b['UserTags']) {
foreach (unserialize($row_b['UserTags']) as $tag) {
if ($item['UserTags']) {
foreach (unserialize($item['UserTags']) as $tag) {
echo "<span class='tag ".$tag."'></span>";
}
echo "&nbsp;";
}
echo htmlentities(shortlabel($row_a['Filename']));
echo htmlentities(shortlabel($item['Filename']));
echo "</div>";
if ($row_a['Size']) {
echo "<div class='size'>".human_filesize($row_a['Size'])."</div>";
if ($item['Size']) {
echo "<div class='size'>".human_filesize($item['Size'])."</div>";
}
if ($row_a['Type'] == "dir" && $row_a['items']) {
echo "<div class='size'>".number_format($row_a['items'])." items</div>";
if ($item['Type'] == "dir" && $item['items']) {
echo "<div class='size'>".number_format($item['items'])." items</div>";
}
echo "</div>";
@@ -518,7 +636,7 @@ if ($db_file) {
echo str_repeat("<div class='flexfill'></div>", 100);
echo "</div>";
echo "</td><td valign='top'>";
echo "</td><td valign='top' class='sidebar'>";
debug($view,$view['Pathname']);
@@ -555,13 +673,23 @@ if ($db_file) {
// DB List
echo "<a href='#' class='toggler'>toggle all</a>";
$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 "<div id='bundle'>";
$dbs = array_reverse(glob($bundle."/*.sqlite3"));
array_shift($dbs);
@@ -570,7 +698,10 @@ if ($db_file) {
$type = $dbo->query("SELECT type FROM _skim")->fetch()['type'];
echo "<img id='item' src='".$icons[$type]."'>";
}
echo "<h2>".pathinfo($bundle)['filename']."</h2>";
$dbo = new PDO("sqlite:".$dbs[0]);
$info = $dbo->query("SELECT * FROM _skim")->fetch();
echo "<h2><a href='#'>".pathinfo($bundle)['filename']." (".$info['passed_total'].")</a></h2>";
echo "<div class='dblist'>";
foreach ($dbs as $db_file) {
$dbo = new PDO("sqlite:".$db_file);
$info = $dbo->query("SELECT * FROM _skim")->fetch();
@@ -590,6 +721,7 @@ if ($db_file) {
echo "</div>";
}
echo "</div>";
echo "</div>";
}
}