0.7.12
This commit is contained in:
7
MainMenu.nib/designable.nib
generated
7
MainMenu.nib/designable.nib
generated
@@ -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"/>
|
||||
|
||||
BIN
MainMenu.nib/keyedobjects.nib
generated
BIN
MainMenu.nib/keyedobjects.nib
generated
Binary file not shown.
@@ -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
|
||||
|
||||
|
||||
53
Yuba.php
53
Yuba.php
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
?>
|
||||
@@ -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
191
functions.pashua.php
Executable 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;
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -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";
|
||||
|
||||
@@ -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;}
|
||||
@@ -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));
|
||||
|
||||
?>
|
||||
@@ -1 +1 @@
|
||||
0.7.11.5
|
||||
0.7.12
|
||||
Reference in New Issue
Block a user