This commit is contained in:
2019-05-22 04:02:22 -07:00
parent c062910a22
commit e84c693464
11 changed files with 313 additions and 26 deletions

View File

@@ -120,7 +120,7 @@ Gw
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<size key="minSize" width="553" height="200"/>
<size key="maxSize" width="553" height="10000000"/>
<size key="maxSize" width="555" height="10000000"/>
<color key="insertionPointColor" name="textColor" catalog="System" colorSpace="catalog"/>
<connections>
<outlet property="delegate" destination="207" id="489"/>
@@ -158,13 +158,12 @@ Gw
<menuItem isSeparatorItem="YES" id="233">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Preferences..." id="reA-2d-BZ0">
<modifierMask key="keyEquivalentModifierMask"/>
<menuItem title="Preferences..." keyEquivalent="," id="reA-2d-BZ0">
<connections>
<action selector="menuItemSelected:" target="207" id="x6l-Tq-pHp"/>
</connections>
</menuItem>
<menuItem title="Check for updates..." id="jWa-5b-mBK" userLabel="Check for updates...">
<menuItem title="Check for Updates..." id="jWa-5b-mBK" userLabel="Check for updates...">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="menuItemSelected:" target="207" id="VBb-a8-Cku"/>

Binary file not shown.

View File

@@ -4,7 +4,7 @@
**Yuba** generates a web-browsable SQLite database from an HFS+ filesystem. Its client application gathers forensic-quality data about a locally attached disk, properly interpreting bundles, reading Spotlight data, Finder flags, labels, and other contextual information. It can generate hashes, thumbnails, and gather 3rd party metadata with exiftool and mediainfo. Yuba's filesystem catalogues are comprehensive, lightweight, optimized for massive (1 million+) trees, and reflect incremental changes to contents and metadata. A server-side PHP script is provided, which allows familiar, Finder-style browsing of a catalogue.
* **⇩ [Download Yuba 0.7.11](http://www.profiteroles.org/downloads/Yuba_0.7.11.zip)**
* **⇩ [Download Yuba 0.7.12](http://www.profiteroles.org/downloads/Yuba_0.7.12.zip)**
## Features

View File

@@ -3,7 +3,7 @@
// Yuba
// //
//////////////////////////////////////////
$version = "0.7.11.5";
$version = file_get_contents(__DIR__."/version.txt");
ini_set('memory_limit', '10240M');
date_default_timezone_set("America/Los_Angeles");
@@ -11,7 +11,9 @@ date_default_timezone_set("America/Los_Angeles");
// Includes & Prefs
//////////////////////////////////////////
$p = unserialize(file_get_contents("prefs.php"));
$p = unserialize(file_get_contents(__DIR__."/prefs.php"));
$p['phpbin'] = "/usr/bin/php";
require("functions.php");
require("filetypes.php");
@@ -21,6 +23,33 @@ $wopt_currstep = 1;
$parser = new plistParser();
// Menu options
//////////////////////////////////////////
// Preferences
if (@$argv[1] == "Preferences...") {
exec($p['phpbin']." ".__DIR__."/YubaPrefs.php 2>&1");
die;
}
// Version check
if (@$argv[1] == "Check for Updates...") {
$curr_version = file_get_contents("http://git.profiteroles.org/profiteroles/Yuba/raw/branch/master/version.txt");
if ($curr_version > $version) {
if(askMulti("Yuba ".$curr_version." is available (you have ".$version.")", array("Cancel","Download")) == 1) {
exec("open http://git.profiteroles.org/profiteroles/Yuba");
die;
}
} else {
alert($version." is the latest version","Up-to-date");
die;
}
}
// Path & application variables
//////////////////////////////////////////
@@ -28,8 +57,8 @@ $stamp = date("Y-m-d_H-i-s", time());
if (!isset($argv[1])) { echo "No input"; die; }
$zpath = realpath(@$argv[1]);
if (@$argv[2]) { $bdest = realpath($argv[2]); } else { $bdest = realpath($p['bdest']); }
if (!is_dir($zpath) | !is_dir($bdest)) { echo "Filepath error"; die; }
if ($p['bdest']) { $bdest = realpath($p['bdest']); } else { $bdest = "/Users/".get_current_user()."/Documents/Yuba/"; }
if (!is_dir($bdest)) { if (!mkdir($bdest)) { echo "Error creating directory: ".$bdest; die; } }
// Check for bundle
if ($zpath == "/") { $blabel = "root"; } else { $blabel = preg_replace("/[^A-Za-z0-9\.]/", "_", basename($zpath)); }
@@ -48,7 +77,6 @@ $bin_ffmpeg = __DIR__."/bin/ffmpeg";
$bin_qlthumb = __DIR__."/bin/ql-thumbnail";
// Logfile
$messages_log_file = $bpath."/".$stamp."_messages.log";
$error_log_file = $bpath."/".$stamp."_error.log";
error_reporting(E_ALL);
@@ -59,6 +87,8 @@ ini_set("error_log", $error_log_file);
// Banner
//////////////////////////////////////////
if (!is_dir($zpath) | !is_dir($bdest)) { echo "Filepath error"; die; }
$banner = "Yuba: ".$zpath." -> ".$bpath;
echo msg($banner."\n".str_repeat("-", strlen($banner)));
@@ -509,9 +539,7 @@ if ($p['thumbs']) {
if (!is_dir($tpath)) { mkdir($tpath); }
$tfile = $tpath."/".$fid.".jpg";
// HACK for ql-thumbnail bug
$t_skip = array("emlx","flac");
if (count($t_skip) && in_array($ext, $t_skip)) {
if (count($p['t_skip']) && in_array($ext, $p['t_skip'])) {
echo ProgressBar::next("Skipping ".shortlabel($pathname));
continue;
}
@@ -589,7 +617,8 @@ if ($p['contents']) {
$cfile = $cpath."/".$fid.".zip";
if (in_array($ext, $p['c_files'])) {
if (!is_dir($cpath)) { mkdir($cpath); }
if (!file_exists($cfile) && filesize($pathname) < 25000) {
$max_size = $p['contents_limit'] * 1000;
if (!file_exists($cfile) && filesize($pathname) < $max_size) {
msg("Zipping ".$pathname);
@@ -972,7 +1001,7 @@ foreach ($files as $splFileInfo) {
$yes_contents = $dbp->query("SELECT relative_path FROM contents WHERE fid='".$fid."'")->fetch()[0];
$stmt->BindValue(":contents_filename",$yes_contents);
if (!in_array($extension, $t_skip)) {
if (!in_array($extension, $p['t_skip'])) {
$fetch_thumb = $dbp->query("SELECT * FROM thumbs WHERE fid='".$fid."'")->fetch();
}
if (@$fetch_thumb['relative_path']) {
@@ -1188,7 +1217,7 @@ $dbo->exec("UPDATE _skim SET status='completed_in_".$seconds."'");
// rsync
if ($p['rsync_dest']) {
if ($p['postflight'] == 2 && $p['rsync_dest']) {
echo msg("rsync...");
$command = "rsync -avv -e ssh ".$bpath." ".$p['rsync_dest'];
$count = trim(shell_exec("find ".escapeshellarg($bpath)." | wc -l"));
@@ -1197,6 +1226,8 @@ if ($p['rsync_dest']) {
while(fgets($pipe, 2048)) { echo ProgressBar::next(true); }
pclose($pipe);
echo ProgressBar::finish();
} elseif ($p['postflight'] == 1) {
exec("open -R ".escapeshellarg($bpath));
}
$done = "Finished ".$zpath." in ".$seconds." seconds";

View File

@@ -0,0 +1,53 @@
<?php
// YubaPrefs 0.1.0
//
// Includes
require (__DIR__."/functions.php");
require (__DIR__."/functions.pashua.php");
// Read Prefs
$p = unserialize(file_get_contents(__DIR__."/prefs.php"));
if(!$p['bdest']) {
$p['bdest'] = "/Users/".get_current_user()."/Documents/Yuba/";
if (!is_dir($p['bdest'])) { if (!mkdir($p['bdest'])) { echo "Error creating destination directory"; } }
}
// Load strings
$strings[] = array("Do nothing","Reveal result in Finder","Upload result with rsync");
$strings[] = array("Bypass","Generate","Rebuild (tk)");
$result = Pashua::showDialog(makeWindowString($p, $strings));
// User cancelled
if (@$result['cb']) {
echo "0";
die;
}
// Fix strings
$result['postflight'] = array_search($result['postflight'],$strings[0]);
$result['thumbs'] = array_search($result['thumbs'],$strings[1]);
// If the user didn't specify a destpath, set to default
if(!$p['bdest']) {
$p['bdest'] = "/Users/".get_current_user()."/Documents/Yuba/";
}
// Fix a Pashua bug
$result['destpath'] = str_replace("Desktop/Desktop","Desktop",$result['destpath']);
// Write Prefs
file_put_contents("prefs.php",serialize($result));
echo "1";
?>

View File

@@ -1,7 +1,7 @@
<?php
// Filetypes
// 0.7.11.5
// 0.7.12
//////////////////////////////////////////
$p['bundles'] = array( "app",
@@ -66,6 +66,9 @@ $p['t_files']['sips'] = array( "jpg",
"png",
"heic" );
// don't make thumbs for these files
$p['t_skip'] = array("emlx","flac");
$p['m_files'] = array( "mkv",
"ogg",
"avi",
@@ -167,5 +170,6 @@ foreach ($p['e_files'] as $ext) { $p['e_files'][] = strtoupper($ext); }
foreach ($p['m_files'] as $ext) { $p['m_files'][] = strtoupper($ext); }
foreach ($p['t_files']['ffmpeg'] as $ext) { $p['t_files']['ffmpeg'][] = strtoupper($ext); }
foreach ($p['t_files']['sips'] as $ext) { $p['t_files']['sips'][] = strtoupper($ext); }
foreach ($p['t_skip'] as $ext) { $p['t_skip'][] = strtoupper($ext); }
?>

191
functions.pashua.php Executable file
View File

@@ -0,0 +1,191 @@
<?php
// Pashua Stuff
/**
* Static class which wraps the two simple methods used for communicating with Pashua
*/
class Pashua
{
/**
* Invokes a Pashua dialog window with the given window configuration
*
* @param string $conf Configuration string to pass to Pashua
* @param string $customLocation Filesystem path to directory containing Pashua
*
* @throws \RuntimeException
* @return array Associative array of values returned by Pashua
*/
public static function showDialog($conf, $customLocation = null)
{
if (ini_get('safe_mode')) {
$msg = "To use Pashua you will have to disable safe mode or " .
"change " . __FUNCTION__ . "() to fit your environment.\n";
fwrite(STDERR, $msg);
exit(1);
}
// Write configuration string to temporary config file
$configfile = tempnam('/tmp', 'Pashua_');
if (false === $fp = @fopen($configfile, 'w')) {
throw new \RuntimeException("Error trying to open $configfile");
}
fwrite($fp, $conf);
fclose($fp);
$path = __DIR__."/Pashua.app/Contents/MacOS/Pashua";
// Call pashua binary with config file as argument and read result
$result = shell_exec(escapeshellarg($path) . ' ' . escapeshellarg($configfile));
@unlink($configfile);
// Parse result
$parsed = array();
foreach (explode("\n", $result) as $line) {
preg_match('/^(\w+)=(.*)$/', $line, $matches);
if (empty($matches) or empty($matches[1])) {
continue;
}
$parsed[$matches[1]] = $matches[2];
}
return $parsed;
}
}
function makeWindowString($p, $strings) {
$conf = "
# Set window title
*.title = Preferences
*.floating = 1
bdest.type = openbrowser
bdest.filetype = directory
bdest.label = Destination
bdest.default = ".$p['bdest']."
bdest.width = 400
postflight.type = popup
postflight.label = When finished
postflight.option = ".$strings[0][0]."
postflight.option = ".$strings[0][1]."
postflight.option = ".$strings[0][2]."
postflight.default = ".$strings[0][$p['postflight']]."
postflight.width = 400
rsync_dest.type = textfield
rsync_dest.label = rsync destination
rsync_dest.default = ".$p['rsync_dest']."
rsync_dest.placeholder = user@server.com:files/
rsync_dest.width = 400
hr1.type = image
hr1.path = ".__DIR__."/hr.png"."
hr1.width = 400
hr1.height = 2
readability.type = checkbox
readability.label = Abort if files can't be read
readability.default = ".$p['readability']."
fixatimes.type = checkbox
fixatimes.label = Fix atimes after access
fixatimes.default = ".$p['fixatimes']."
verify_stat.type = checkbox
verify_stat.label = Verify preflight and postflight stat values match
verify_stat.default = ".$p['verify_stat']."
hr2.type = image
hr2.path = ".__DIR__."/hr.png"."
hr2.width = 400
hr2.height = 2
spotlight.type = checkbox
spotlight.label = Spotlight
spotlight.default = ".$p['spotlight']."
meta.type = checkbox
meta.label = Collect external metadata
meta.default = ".$p['meta']."
meta.x = 200
meta.y = 227
thumbs.type = popup
thumbs.label = Thumbnails
thumbs.option = ".$strings[1][0]."
thumbs.option = ".$strings[1][1]."
thumbs.option = ".$strings[1][2]."
thumbs.default = ".$strings[1][$p['thumbs']]."
thumbs.width = 160
thumb_size.type = textfield
thumb_size.default = ".$p['thumb_size']."
thumb_size.label = Size
thumb_size.placeholder = pixels
thumb_size.width = 60
thumb_size.x = 200
thumb_size.y = 165
hash.type = checkbox
hash.label = Generate hashes
hash.default = ".$p['hash']."
hash_label.type = text
hash_label.default = Limit
hash_label.x = 200
hash_label.y = 128
hash_label.width = 40
hash_limit.type = textfield
hash_limit.default = ".$p['hash_limit']."
hash_limit.tooltip = Don't hash files larger than X GB
hash_limit.width = 60
hash_limit.x = 240
hash_limit.y = 125
hash_label_after.type = text
hash_label_after.default = GB
hash_label_after.x = 304
hash_label_after.y = 128
hash_label_after.width = 40
contents.type = checkbox
contents.label = Collect file contents
contents.default = ".$p['contents']."
contents_label.type = text
contents_label.default = Limit
contents_label.x = 200
contents_label.y = 88
contents_label.width = 40
contents_limit.type = textfield
contents_limit.tooltip = Don't save files larger than X kB
contents_limit.default = ".$p['contents_limit']."
contents_limit.width = 60
contents_limit.x = 240
contents_limit.y = 85
contents_label_after.type = text
contents_label_after.default = kB
contents_label_after.x = 304
contents_label_after.y = 88
contents_label_after.width = 40
profile.type = checkbox
profile.label = Generate system profile
profile.default = ".$p['profile']."
cb.type = cancelbutton
db.type = defaultbutton
db.label = Save
";
return $conf;
}
?>

View File

@@ -1,7 +1,7 @@
<?php
// Classes
// 0.7.10.3
// 0.7.12
//////////////////////////////////////////
class ProgressBar {
@@ -67,6 +67,16 @@ class ProgressBar {
// Functions
//////////////////////////////////////////
function alert($string, $title = "Warning") {
echo "\nALERT:".$title."|".$string."\n";
}
function askMulti($string, $buttons) {
$buttonstring = "buttons {\\\"".implode("\\\", \\\"",$buttons)."\\\"} default button ".count($buttons);
$result = exec("osascript -e \"display dialog \\\"".$string."\\\" ".$buttonstring."\" | cut -f2 -d':'");
return array_search($result,$buttons);
}
function msg($string) {
global $messages_log_file;
$logstring = "[".date('Y-m-d h:i:s')."] ".$string."\n";

View File

@@ -1 +1 @@
a:13:{s:5:"bdest";s:5:"/tmp/";s:10:"rsync_dest";s:0:"";s:11:"readability";i:0;s:9:"fixatimes";i:0;s:11:"verify_stat";i:0;s:4:"meta";i:1;s:6:"thumbs";i:1;s:10:"thumb_size";i:512;s:4:"hash";i:1;s:10:"hash_limit";i:1;s:8:"contents";i:1;s:9:"spotlight";i:1;s:7:"profile";i:1;}
a:15:{s:5:"bdest";s:0:"";s:10:"rsync_dest";s:0:"";s:10:"postflight";i:1;s:11:"readability";i:0;s:9:"fixatimes";i:0;s:11:"verify_stat";i:0;s:4:"meta";i:1;s:6:"thumbs";i:1;s:10:"thumb_size";i:512;s:4:"hash";i:1;s:10:"hash_limit";i:1;s:8:"contents";i:1;s:14:"contents_limit";i:50;s:9:"spotlight";i:1;s:7:"profile";i:1;}

View File

@@ -1,8 +1,9 @@
#!/usr/bin/php
<?
$p['bdest'] = "/tmp/";
$p['bdest'] = "";
$p['rsync_dest'] = "";
$p['postflight'] = 1;
$p['readability'] = 0;
$p['fixatimes'] = 0;
@@ -14,12 +15,10 @@ $p['thumb_size'] = 512;
$p['hash'] = 1;
$p['hash_limit'] = 1;
$p['contents'] = 1;
$p['contents_limit'] = 50;
$p['spotlight'] = 1;
$p['profile'] = 1;
file_put_contents("prefs.php",serialize($p));
//$p = unserialize(file_get_contents(__DIR__."/prefs.php"));
//print_r($p);
file_put_contents("../prefs.php",serialize($p));
?>

View File

@@ -1 +1 @@
0.7.11.5
0.7.12