Files
Yuba/Yuba.php

1137 lines
32 KiB
PHP
Raw Normal View History

2017-05-03 00:39:48 -07:00
<?php
2017-06-20 02:05:52 -07:00
// Yuba
// //
//////////////////////////////////////////
2019-10-06 06:46:23 -07:00
$version = file_get_contents(__DIR__."/current_version.txt");
2017-06-20 02:05:52 -07:00
2019-04-27 00:48:25 -07:00
ini_set('memory_limit', '10240M');
2017-05-25 15:38:19 -07:00
date_default_timezone_set("America/Los_Angeles");
2018-08-08 23:12:47 -07:00
// Includes & Prefs
//////////////////////////////////////////
2019-10-09 04:25:19 -07:00
// Timestamp
$mytime = time();
$tmpdir = "/tmp/yuba/".$mytime;
if (!is_dir($tmpdir)) { mkdir($tmpdir,0777,true); }
$stamp = date("Y-m-d_H-i-s", $mytime);
if (!file_exists("/tmp/yuba/debug.log")) { touch("/tmp/yuba/debug.log"); }
// Prefs
2019-09-25 00:31:51 -07:00
$prefs_file = "/Users/".get_current_user()."/Library/Preferences/org.profiteroles.Yuba.php";
2019-05-23 04:48:00 -07:00
if (!file_exists($prefs_file)) {
if (!copy(__DIR__."/prefs.php",$prefs_file)) {
echo "Error creating preferences file";
die;
}
}
$p = unserialize(file_get_contents($prefs_file));
2019-05-22 04:02:22 -07:00
2018-08-08 23:12:47 -07:00
require("functions.php");
require("filetypes.php");
2019-06-14 02:15:01 -07:00
// Manual prefs
2019-10-09 04:07:46 -07:00
$wopt_steps = 8; // total number of steps
2018-09-13 01:50:00 -07:00
$wopt_currstep = 1;
2019-10-09 04:07:46 -07:00
if ($p['debug']) { $wopt_clear = 0; } else { $wopt_clear = 1; }
2019-10-15 18:32:21 -07:00
$wopt_debug_unique = 0;
2018-08-08 23:12:47 -07:00
2019-04-09 01:13:49 -07:00
$parser = new plistParser();
2019-05-22 04:02:22 -07:00
// Menu options
//////////////////////////////////////////
// Preferences
if (@$argv[1] == "Preferences...") {
2019-10-08 02:36:10 -07:00
exec($bin_php." ".escapeshellarg(__DIR__."/YubaPrefs.php")." 2>&1");
2019-05-22 04:02:22 -07:00
die;
}
2019-10-09 04:07:46 -07:00
// Console
if (@$argv[1] == "Console") {
exec("open -n ".__DIR__."/bin/Console.app --args /tmp/yuba/debug.log");
die;
}
2019-05-22 04:02:22 -07:00
// Version check
if (@$argv[1] == "Check for Updates...") {
2019-10-06 06:46:23 -07:00
$curr_version = file_get_contents("https://www.profiteroles.org/git/p/Yuba/raw/master/current_version.txt");
2019-05-22 04:02:22 -07:00
if ($curr_version > $version) {
if(askMulti("Yuba ".$curr_version." is available (you have ".$version.")", array("Cancel","Download")) == 1) {
2019-10-06 06:46:23 -07:00
exec("open https://www.profiteroles.org/git/p/Yuba/");
echo "QUITAPP\n";
2019-05-22 04:02:22 -07:00
}
} else {
alert($version." is the latest version","Up-to-date");
die;
}
}
2019-10-09 04:07:46 -07:00
dm("Launching Yuba\n".str_repeat("-",33)."\n".print_r($p,true));
// PHP Checks
//////////////////////////////////////////
$needed = array("iconv","fileinfo","json","PDO","pdo_sqlite","SimpleXML","sqlite3","xml");
foreach ($needed as $ext) {
if (!extension_loaded($ext)) {
alert("PHP is missing the ".$ext.". Exiting.","PHP Extension Missing");
echo "QUITAPP\n";
}
}
if ($p['contents'] && !extension_loaded("zip")) {
alert("PHP is missing the zip extension. Yuba will not collect file contents.","PHP Extension Missing");
revise_prefs(array("contents" => 0));
}
2017-06-20 02:05:52 -07:00
// Path & application variables
2017-05-20 20:03:50 -07:00
//////////////////////////////////////////
2017-06-20 02:05:52 -07:00
2019-10-08 01:54:04 -07:00
if (!isset($argv[1]) || $argv[1] == "") { echo "No input"; die; }
2017-06-20 02:05:52 -07:00
$zpath = realpath(@$argv[1]);
2019-05-22 04:02:22 -07:00
if ($p['bdest']) { $bdest = realpath($p['bdest']); } else { $bdest = "/Users/".get_current_user()."/Documents/Yuba/"; }
2019-10-15 18:32:21 -07:00
if (!is_dir($bdest)) { if (!mkdir($bdest,0777,true)) { echo "Error creating destination directory"; die; } }
2017-06-20 02:05:52 -07:00
// Check for bundle
if ($zpath == "/") { $blabel = "root"; } else { $blabel = preg_replace("/[^A-Za-z0-9\.]/", "_", basename($zpath)); }
2019-10-15 18:32:21 -07:00
if ($wopt_debug_unique) { $blabel .= "-".$mytime; }
2019-04-09 01:13:49 -07:00
if (is_writable($zpath)) { echo "Warning: source is writeable\n"; }
2017-06-20 02:05:52 -07:00
$bpath = chop($bdest,"/")."/".substr(crc32($zpath),0,3)."_".$blabel.".bundle";
if (!is_dir($bpath)) { mkdir($bpath); }
if (!is_dir($bpath."/thumbs")) { mkdir($bpath."/thumbs"); }
2019-06-10 16:32:09 -07:00
if (!is_dir($bpath."/icons")) { mkdir($bpath."/icons"); }
2019-06-10 22:04:25 -07:00
if (!is_dir($bpath."/contents")) { mkdir($bpath."/contents"); }
2017-06-20 02:05:52 -07:00
2018-09-01 21:30:02 -07:00
// Logfile
2018-09-16 15:22:15 -07:00
$messages_log_file = $bpath."/".$stamp."_messages.log";
2018-09-02 11:21:24 -07:00
$error_log_file = $bpath."/".$stamp."_error.log";
2018-09-01 21:30:02 -07:00
error_reporting(E_ALL);
ini_set("display_errors", TRUE);
ini_set("log_errors", TRUE);
2018-09-02 11:21:24 -07:00
ini_set("error_log", $error_log_file);
2018-09-01 21:30:02 -07:00
2019-10-06 06:46:23 -07:00
// Bundled QlGenerators
$generators = @glob(__DIR__."/../Library/Quicklook/*.qlgenerator");
if (!empty($generators)) {
foreach ($generators as $generator) {
$p['bundled_generators'][] = basename($generator);
}
}
2018-08-08 23:12:47 -07:00
// Banner
2017-06-20 02:05:52 -07:00
//////////////////////////////////////////
2019-05-22 04:02:22 -07:00
if (!is_dir($zpath) | !is_dir($bdest)) { echo "Filepath error"; die; }
2018-08-08 23:12:47 -07:00
$banner = "Yuba: ".$zpath." -> ".$bpath;
2018-09-16 15:22:15 -07:00
echo msg($banner."\n".str_repeat("-", strlen($banner)));
2017-05-22 23:37:36 -07:00
2019-10-06 06:46:23 -07:00
// System Info
2017-06-20 02:05:52 -07:00
//////////////////////////////////////////
2017-05-20 20:03:50 -07:00
2018-09-16 15:22:15 -07:00
echo msg("Gathering system info...");
2018-08-08 23:12:47 -07:00
2019-10-06 06:46:23 -07:00
// Disks
2019-04-09 01:13:49 -07:00
if (substr($zpath, 0, 9) != "/Volumes/") {
$zbase = "/";
} else {
$zparts = explode("/", $zpath);
$zbase = "/Volumes/".$zparts[2];
}
2017-05-20 20:03:50 -07:00
$host = gethostname();
2018-09-16 15:22:15 -07:00
$disks = shell_exec("diskutil list -plist 2>&1");
2019-04-09 01:13:49 -07:00
$diskutil = shell_exec("diskutil info -plist ".$zbase." 2>&1");
$diskutil_parsed = $parser->parseString(utf8_for_xml($diskutil));
2019-10-06 06:46:23 -07:00
foreach ($diskutil_parsed['SMARTDeviceSpecificKeysMayVaryNotGuaranteed'] as $key => $value) {
$diskutil_parsed[$key] = $value;
}
unset($diskutil_parsed['SMARTDeviceSpecificKeysMayVaryNotGuaranteed']);
2019-04-09 01:13:49 -07:00
$vdisks = shell_exec("hdiutil info -plist 2>&1");
$vdisks_parsed = $parser->parseString(utf8_for_xml($vdisks));
2018-09-01 21:30:02 -07:00
$df = shell_exec("df 2>&1");
2019-04-09 01:13:49 -07:00
$df_volume = $diskutil_parsed['MountPoint'];
$df_device = "/dev/".$diskutil_parsed['ParentWholeDisk'];
2019-04-27 00:48:25 -07:00
$mdutil = shell_exec("mdutil -sv ".$df_volume);
2018-09-01 21:30:02 -07:00
if (strpos($mdutil,"disabled")) {
2018-09-16 15:22:15 -07:00
echo msg("Warning: spotlight indexing is disabled");
2018-09-02 11:21:24 -07:00
$p['spotlight'] = false;
2018-09-01 21:30:02 -07:00
}
2017-05-22 23:37:36 -07:00
if ($zpath == "/") {
$type = "Startup disk";
2019-10-06 06:46:23 -07:00
} elseif (strtolower($zpath) == strtolower("/Volumes/".$diskutil_parsed["VolumeName"])) {
if ($diskutil_parsed["BusProtocol"] == "Disk Image") {
2017-05-22 23:37:36 -07:00
$type = "Disk image";
} else {
$type = "External disk";
}
} else {
$type = "Folder";
}
2019-04-09 01:13:49 -07:00
if ($type == "Disk image") {
$hdiutil = shell_exec("hdiutil imageinfo -plist ".$df_device." 2>&1");
foreach ($vdisks_parsed['images'] as $id => $disk) {
if ($disk['system-entities'][0]['dev-entry'] == $df_device) {
$image_file = $disk['image-path'];
}
}
} else {
$hdiutil = false;
$image_file = false;
}
2019-10-06 06:46:23 -07:00
// System Profile
2019-05-22 00:59:01 -07:00
if ($p['profile']) {
2019-04-09 01:13:49 -07:00
echo msg("system_profiler");
2018-08-08 23:12:47 -07:00
$profile = shell_exec("system_profiler SPHardwareDataType SPStorageDataType SPThunderboltDataType SPUSBDataType 2>&1");
2019-05-22 00:59:01 -07:00
} else {
$profile = "disabled";
2018-08-08 23:12:47 -07:00
}
2017-06-16 00:14:32 -07:00
$sysvers = shell_exec("sw_vers 2>&1");
2017-05-22 23:37:36 -07:00
2019-10-06 06:46:23 -07:00
// QuickLook
foreach (explode("\n",shell_exec($bin_qlmanage." -m plugins 2>&1")) as $ql_line) {
$ql_parts = @explode(" -> ",trim($ql_line));
if (@$ql_parts[1]) {
$qlmanage['plugins'][$ql_parts[0]] = $ql_parts[1];
}
}
$qlmanage['server'] = trim(shell_exec($bin_qlmanage." -m server 2>&1"));
$qlmanage['memory'] = trim(shell_exec($bin_qlmanage." -m memory 2>&1"));
$qlmanage['burst'] = trim(shell_exec($bin_qlmanage." -m burst 2>&1"));
$qlmanage['threads'] = trim(shell_exec($bin_qlmanage." -m threads 2>&1"));
$qlmanage['other'] = trim(shell_exec($bin_qlmanage." -m other 2>&1"));
2017-05-22 23:37:36 -07:00
// Database
2017-06-20 02:05:52 -07:00
//////////////////////////////////////////
2017-05-20 20:03:50 -07:00
2018-09-16 15:22:15 -07:00
echo msg("Building database...");
2018-08-08 23:12:47 -07:00
2017-06-22 01:09:03 -07:00
$dbo = new PDO("sqlite:".$bpath."/".$stamp.".sqlite3");
2017-05-20 20:03:50 -07:00
$dbo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
2018-09-16 15:22:15 -07:00
$dbo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
2017-05-20 20:03:50 -07:00
2019-10-09 04:07:46 -07:00
//$dbo->query("PRAGMA page_size = 4096");
//$dbo->query("PRAGMA cache_size = 10000");
//$dbo->query("PRAGMA locking_mode = EXCLUSIVE");
//$dbo->query("PRAGMA synchronous = NORMAL");
2017-06-18 03:17:42 -07:00
$dbo->query("PRAGMA journal_mode = WAL");
2017-06-16 00:14:32 -07:00
2018-09-02 11:21:24 -07:00
$dbo->exec("CREATE TABLE _skim (
2017-06-20 02:05:52 -07:00
version TEXT,
opts TEXT,
host TEXT,
uid INTEGER,
zpath TEXT,
bpath TEXT,
type TEXT,
passed_file INTEGER,
passed_dir INTEGER,
passed_link INTEGER,
passed_total INTEGER,
nodescended INTEGER,
ignored INTEGER,
dupes INTEGER,
qlmanage TEXT,
sysvers TEXT,
disks TEXT,
2019-04-09 01:13:49 -07:00
diskutil TEXT,
vdisks TEXT,
hdiutil TEXT,
image_file TEXT,
df TEXT,
df_device TEXT,
df_volume TEXT,
mdutil TEXT,
2017-06-20 02:05:52 -07:00
profile TEXT,
status TEXT
)");
$dbo->exec("CREATE TABLE family (
pid TEXT,
fid TEXT,
children TEXT
)");
2017-06-22 01:09:03 -07:00
2019-06-11 00:07:31 -07:00
$dbo->exec("CREATE TABLE dupes (
fid TEXT,
dupes TEXT
)");
2017-05-25 15:38:19 -07:00
$dbo->exec("CREATE TABLE files (
2017-06-20 02:05:52 -07:00
pid TEXT,
fid TEXT,
2017-06-22 01:09:03 -07:00
Pathname TEXT,
Path TEXT,
Filename TEXT,
Extension TEXT,
Type TEXT,
2018-09-05 00:26:26 -07:00
Size INTEGER,
2017-06-22 01:09:03 -07:00
Inode INTEGER,
Perms INTEGER,
Owner TEXT,
ATime INTEGER,
MTime INTEGER,
2018-09-02 11:21:24 -07:00
CTime INTEGER,
2017-06-22 01:09:03 -07:00
LinkTarget TEXT,
RealPath TEXT,
stat TEXT,
items INTEGER,
newest INTEGER,
2019-04-27 00:48:25 -07:00
fkind TEXT,
2017-06-22 01:09:03 -07:00
gfi_type TEXT,
gfi_attr TEXT,
gfi_created TEXT,
has_exif INTEGER,
has_mediainfo INTEGER,
has_hash INTEGER,
thumb_filename TEXT,
thumb_width INTEGER,
thumb_height INTEGER,
2019-05-23 04:48:00 -07:00
thumb_tool TEXT,
2019-06-10 22:04:25 -07:00
icon_filename TEXT,
2018-09-03 02:53:01 -07:00
contents_filename TEXT
2017-05-25 15:38:19 -07:00
)");
2017-05-22 23:37:36 -07:00
2019-10-06 06:46:23 -07:00
$stmt = $dbo->prepare("INSERT INTO _skim VALUES (:version, :opts, :host, :uid, :zpath, :bpath, :type, :passed_file, :passed_dir, :passed_link, :passed_total, :nodescended, :ignored, :dupes, :qlmanage, :sysvers, :disks, :diskutil, :vdisks, :hdiutil, :image_file, :df, :df_device, :df_volume, :mdutil, :profile, :status)");
2017-06-20 02:05:52 -07:00
$stmt->BindValue(":version",$version);
2018-08-08 23:12:47 -07:00
$stmt->BindValue(":opts",serialize($p));
2017-05-20 20:03:50 -07:00
$stmt->BindValue(":host",$host);
2017-06-20 02:05:52 -07:00
$stmt->BindValue(":uid",posix_getuid());
2017-05-22 23:37:36 -07:00
$stmt->BindValue(":zpath",$zpath);
2017-06-20 02:05:52 -07:00
$stmt->BindValue(":bpath",$bpath);
2017-05-22 23:37:36 -07:00
$stmt->BindValue(":type",$type);
2019-10-06 06:46:23 -07:00
$stmt->BindValue(":qlmanage",serialize($qlmanage));
2017-06-16 00:14:32 -07:00
$stmt->BindValue(":sysvers",$sysvers);
2019-04-09 01:13:49 -07:00
$stmt->BindValue(":disks",$disks);
2017-05-22 23:37:36 -07:00
$stmt->BindValue(":diskutil",$diskutil);
2019-04-09 01:13:49 -07:00
$stmt->BindValue(":vdisks",$vdisks);
2018-09-16 15:22:15 -07:00
$stmt->BindValue(":hdiutil",$hdiutil);
2019-04-09 01:13:49 -07:00
$stmt->BindValue(":image_file",$image_file);
2018-09-01 21:30:02 -07:00
$stmt->BindValue(":df",$df);
$stmt->BindValue(":df_device",$df_device);
$stmt->BindValue(":df_volume",$df_volume);
$stmt->BindValue(":mdutil",$mdutil);
2017-05-22 23:37:36 -07:00
$stmt->BindValue(":profile",$profile);
2017-05-25 15:38:19 -07:00
$stmt->BindValue(":status","aborted");
2017-05-20 20:03:50 -07:00
$stmt->execute();
2017-06-20 02:05:52 -07:00
// Iterator
//////////////////////////////////////////
2017-05-03 00:39:48 -07:00
2018-08-08 23:12:47 -07:00
$first_run = 1;
$passed_file = $passed_dir = $passed_link = $passed_total = $nodescended = $ignored = 0;
2017-05-25 15:38:19 -07:00
$files = new RecursiveIteratorIterator(
new RecursiveCallbackFilterIterator(
new RecursiveDirectoryIterator(
2017-06-22 01:09:03 -07:00
$zpath,
2017-05-25 15:38:19 -07:00
RecursiveDirectoryIterator::SKIP_DOTS
),
2018-08-08 23:12:47 -07:00
function ($current, $key, $iterator) use ($p) {
global $nodescended, $ignored, $passed_file, $passed_dir, $passed_link, $passed_total, $first_run;
2017-05-25 15:38:19 -07:00
$clean = true;
2017-06-22 01:09:03 -07:00
// identify ignore files
2018-08-08 23:12:47 -07:00
if (is_array($p['ignore'])) {
foreach ($p['ignore'] as $wildcard) {
2017-05-25 15:38:19 -07:00
if (fnmatch($wildcard, $current->getFilename())) {
$clean = false;
2018-08-08 23:12:47 -07:00
if ($first_run) { $ignored++; }
2017-05-25 15:38:19 -07:00
}
}
}
2017-06-22 01:09:03 -07:00
// identify nodescend dirs
2018-08-08 23:12:47 -07:00
if (is_array($p['nodescend'])) {
foreach ($p['nodescend'] as $wildcard) {
2017-05-25 15:38:19 -07:00
if (fnmatch($wildcard, $current->getPath())) {
$clean = false;
2018-08-08 23:12:47 -07:00
if ($first_run) { $nodescended++; }
2017-05-25 15:38:19 -07:00
}
}
}
2017-06-22 01:09:03 -07:00
//tally stats
2018-08-08 23:12:47 -07:00
if ($clean && $first_run) {
2017-06-20 02:05:52 -07:00
if ($current->getType() == "file") {
$passed_file++;
} elseif ($current->getType() == "dir") {
$passed_dir++;
} elseif ($current->getType() == "link") {
$passed_link++;
}
2018-08-08 23:12:47 -07:00
$passed_total++;
2017-06-20 02:05:52 -07:00
}
2017-05-25 15:38:19 -07:00
return $clean;
}
),
RecursiveIteratorIterator::SELF_FIRST,
RecursiveIteratorIterator::CATCH_GET_CHILD
);
2018-08-08 23:12:47 -07:00
// Tally
2017-06-20 02:05:52 -07:00
//////////////////////////////////////////
2017-05-25 15:38:19 -07:00
2018-09-16 15:22:15 -07:00
echo msg("Counting files...");
2018-09-03 02:53:01 -07:00
2018-08-08 23:12:47 -07:00
foreach ($files as $null) { }
$first_run = 0;
2017-05-25 15:38:19 -07:00
2018-09-02 11:21:24 -07:00
if (!$passed_total) {
2018-09-16 15:22:15 -07:00
echo msg("Nothing was found, exiting");
2018-09-02 11:21:24 -07:00
die;
}
2018-09-16 15:22:15 -07:00
echo msg("Total files: ".$passed_total."");
2017-06-16 00:14:32 -07:00
2017-06-22 01:09:03 -07:00
// Pool DB
//////////////////////////////////////////
$dbp = new PDO("sqlite:".$bpath."/pool.sqlite3");
2018-09-14 13:50:27 -07:00
2017-06-22 01:09:03 -07:00
$dbp->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
2018-09-14 13:50:27 -07:00
2017-06-22 01:09:03 -07:00
$dbp->exec("CREATE TABLE IF NOT EXISTS md5 (fid TEXT, hash TEXT)");
$dbp->exec("CREATE TABLE IF NOT EXISTS exiftool (fid TEXT, tags TEXT)");
$dbp->exec("CREATE TABLE IF NOT EXISTS mediainfo (fid TEXT, info TEXT)");
$dbp->exec("CREATE TABLE IF NOT EXISTS thumbs (fid TEXT, created INTEGER, relative_path TEXT, width INTEGER, height INTEGER, tool TEXT)");
2019-06-10 16:32:09 -07:00
$dbp->exec("CREATE TABLE IF NOT EXISTS icons (fid TEXT, hash TEXT, created INTEGER, relative_path TEXT, tool TEXT)");
2018-09-01 21:30:02 -07:00
$dbp->exec("CREATE TABLE IF NOT EXISTS contents (fid TEXT, created INTEGER, relative_path TEXT)");
2017-06-22 01:09:03 -07:00
2017-06-20 02:05:52 -07:00
// Prescan
//////////////////////////////////////////
2017-05-25 15:38:19 -07:00
2018-09-03 03:40:31 -07:00
$i = 0;
2017-06-20 02:05:52 -07:00
$family = array();
2018-09-03 03:40:31 -07:00
$fids = array();
$noread = array();
$fx = new SplFixedArray($passed_file);
2019-06-10 22:04:25 -07:00
$splcount = 0;
2018-08-08 23:12:47 -07:00
2018-09-13 01:50:00 -07:00
echo ProgressBar::start($passed_total,"Prescan (".stepString().")");
2018-08-08 23:12:47 -07:00
2017-05-25 15:38:19 -07:00
foreach ($files as $splFileInfo) {
$path = $splFileInfo->getPath();
2018-09-03 03:40:31 -07:00
$pathname = $splFileInfo->getPathname();
$shellpath = escapeshellarg($splFileInfo->getPathname());
$realpath = $splFileInfo->getRealPath();
2017-06-20 02:05:52 -07:00
$key = md5($pathname);
$pkey = md5($path);
if (array_key_exists($key, $family)) {
2018-09-16 15:22:15 -07:00
echo msg("Duplicate key on ".$pathname.""); die;
2017-05-20 20:03:50 -07:00
}
2017-06-16 00:14:32 -07:00
2017-06-20 02:05:52 -07:00
$family[$key] = array();
// Path-agnostic Unique File ID (to prevent redundant hashes and thumbs)
2017-05-25 15:38:19 -07:00
2017-06-20 02:05:52 -07:00
if ($splFileInfo->getType() != "dir" && $splFileInfo->getType() != "link") {
2017-05-25 15:38:19 -07:00
2017-06-20 02:05:52 -07:00
$fid = md5($splFileInfo->getSize().$splFileInfo->getMtime().$splFileInfo->getBasename());
$dx[$fid][] = $pathname;
2019-06-10 22:04:25 -07:00
$fx[$splcount] = array($fid, $pathname);
2017-06-20 02:05:52 -07:00
$family[$key]['fid'] = $fid;
2019-06-10 22:04:25 -07:00
$splcount++;
2017-06-20 02:05:52 -07:00
2017-05-03 00:39:48 -07:00
}
2018-09-14 13:50:27 -07:00
// Collect file stat()
if ($p['stat_mode']) {
$sty[$i] = statToArray(shell_exec("stat -s ".$shellpath." 2>&1"));
if ($p['stat_mode'] > 1 && $splFileInfo->getType() != "link") {
// capture stat values for postflight comparison
$stx[$i] = array($splFileInfo->getATime(), $splFileInfo->getMTime(), $splFileInfo->getCTime());
}
} else {
$sty[$i] = "bypass";
}
2018-09-03 03:40:31 -07:00
// Check file can be read
2017-05-25 15:38:19 -07:00
2018-09-03 03:40:31 -07:00
if ($realpath && !is_readable($realpath)) {
$noread[] = $realpath;
}
2017-06-20 02:05:52 -07:00
// Children
2017-06-18 03:17:42 -07:00
2018-09-03 03:40:31 -07:00
//$family[$pkey]['children'][] = $key;
$family[$pkey]['children'][] = $i+1;
2017-06-18 03:17:42 -07:00
2018-09-13 01:50:00 -07:00
echo ProgressBar::next(true);
2018-09-03 03:40:31 -07:00
$i++;
2017-05-25 15:38:19 -07:00
2017-06-20 02:05:52 -07:00
}
2017-05-25 15:38:19 -07:00
2019-06-12 23:26:54 -07:00
echo ProgressBar::finish($wopt_clear);
2017-05-25 15:38:19 -07:00
2018-09-03 03:40:31 -07:00
// Thow permissions error
if (count($noread)) {
2019-06-13 06:23:28 -07:00
echo msg("Current user (".posix_getuid().") does not have read access to the following files:\n").implode("\n",$noread)."\n";
2018-09-03 03:40:31 -07:00
if ($p['readability']) {
2018-09-16 15:22:15 -07:00
echo msg("Exiting...");
2018-09-03 03:40:31 -07:00
die;
}
}
2017-06-20 02:05:52 -07:00
// Write family to DB
2019-06-12 23:26:54 -07:00
$dupes = array_filter($dx, function($a) { return count($a) > 1; });
$dupecount = 0;
$dupetotal = 0;
if (count($dupes)) {
$dupecount = count($dupes,COUNT_RECURSIVE) - count($dupes);
$dupetotal = floor(($dupecount/$passed_total)*100);
foreach ($dupes as $fid => $array) {
$stmt = $dbo->prepare("INSERT INTO dupes VALUES (:fid, :array)");
$stmt->BindValue(":fid",$fid);
$stmt->BindValue(":array",serialize($array));
$stmt->execute();
}
}
2017-06-20 02:05:52 -07:00
$message = "Writing family to DB: ";
$message .= $passed_file." files, ";
$message .= $passed_dir." dirs, ";
$message .= $nodescended." bundles, ";
$message .= $passed_link." links, ";
$message .= $ignored." ignored, ";
2019-06-12 23:26:54 -07:00
$message .= $dupecount." dupes (".$dupetotal."%)";
2017-06-20 02:05:52 -07:00
2018-08-08 23:12:47 -07:00
echo ProgressBar::start(count($family),$message);
2017-06-20 02:05:52 -07:00
foreach ($family as $key => $item) {
$stmt = $dbo->prepare("INSERT INTO family VALUES (:pid, :fid, :children)");
$stmt->BindValue(":pid",$key);
if (@$item['fid']) {
$stmt->BindValue(":fid",$item['fid']);
2017-05-22 23:37:36 -07:00
}
2017-06-20 02:05:52 -07:00
if (@$item['children'] && is_array(@$item['children'])) {
$stmt->BindValue(":children",serialize($item['children']));
2017-05-03 00:39:48 -07:00
}
2017-05-25 15:38:19 -07:00
$stmt->execute();
2017-06-20 02:05:52 -07:00
2018-08-08 23:12:47 -07:00
echo ProgressBar::next();
2017-06-20 02:05:52 -07:00
}
2019-06-12 23:26:54 -07:00
echo ProgressBar::finish($wopt_clear);
2017-06-20 02:05:52 -07:00
2019-04-09 01:13:49 -07:00
// create an index for family db
$dbo->exec("CREATE INDEX family_index ON family (pid)");
2019-06-11 00:07:31 -07:00
$dbo->exec("CREATE INDEX dupes_index ON dupes (fid)");
2019-04-09 01:13:49 -07:00
2017-06-20 02:05:52 -07:00
unset($dx, $dxo, $dupes);
// stats
2018-09-02 11:21:24 -07:00
$stmt = "UPDATE _skim SET ";
2017-06-20 02:05:52 -07:00
$stmt .= "passed_file=".$passed_file.", ";
$stmt .= "passed_dir=".$passed_dir.", ";
$stmt .= "passed_link=".$passed_link.", ";
2018-08-08 23:12:47 -07:00
$stmt .= "passed_total=".$passed_total.", ";
2017-06-20 02:05:52 -07:00
$stmt .= "nodescended=".$nodescended.", ";
$stmt .= "ignored=".$ignored.", ";
$stmt .= "dupes=".(@$dupecount ? $dupecount : 0);
2017-06-20 02:05:52 -07:00
$dbo->exec($stmt);
2018-09-13 01:50:00 -07:00
$wopt_currstep++;
2019-06-09 23:53:11 -07:00
// Directory Previews
//////////////////////////////////////////
echo ProgressBar::start(count($fx),"Searching for directory previews (".stepString().")");
foreach ($fx as $array) {
$fid = $array[0];
$pathname = $array[1];
if (in_array(basename($pathname),$p['p_files'])) {
$dpreview[dirname($pathname)] = $fid;
}
2019-06-10 16:32:09 -07:00
echo ProgressBar::next();
}
2019-06-12 23:26:54 -07:00
echo ProgressBar::finish($wopt_clear);
2019-06-10 16:32:09 -07:00
2019-10-09 04:07:46 -07:00
// Helper
2017-06-20 02:05:52 -07:00
//////////////////////////////////////////
2019-10-09 04:07:46 -07:00
if ($p['thumbs'] || $p['icons'] || $p['meta'] || $p['hash'] || $p['contents']) {
2017-06-20 02:05:52 -07:00
2019-10-09 04:07:46 -07:00
echo ProgressBar::start($passed_file,"Creating batch (".stepString().")",1);
2019-06-14 02:15:01 -07:00
2019-10-09 04:07:46 -07:00
$batchfile = $tmpdir."/_batch.sh";
2019-06-14 02:15:01 -07:00
$helper = realpath("helper.php");
2017-05-25 15:38:19 -07:00
2019-06-14 02:15:01 -07:00
foreach ($fx as $count => $array) {
2017-06-20 02:05:52 -07:00
$fid = $array[0];
$pathname = $array[1];
2019-10-09 04:07:46 -07:00
$tcmd = $bin_php." ".escapeshellarg($helper)." ".$fid." ".escapeshellarg($pathname)." ".escapeshellarg($bpath)." ".$mytime."; printf '\\n".ProgressBar::next()."'";
2019-06-14 02:15:01 -07:00
msg($tcmd);
2019-10-09 04:07:46 -07:00
$line[] = $tcmd;
2019-06-14 02:15:01 -07:00
}
2019-10-09 04:07:46 -07:00
file_put_contents($batchfile,implode("\n", $line));
2019-06-14 02:15:01 -07:00
echo ProgressBar::finish($wopt_clear);
2017-05-25 15:38:19 -07:00
2019-10-09 04:07:46 -07:00
echo ProgressBar::start($passed_file,"Running batch (".stepString().")");
if ($p['parallel']) {
2019-06-14 02:15:01 -07:00
passthru($bin_parallel." < ".$batchfile);
} else {
passthru("bash ".$batchfile);
2017-06-18 03:17:42 -07:00
}
2019-06-12 23:26:54 -07:00
echo ProgressBar::finish($wopt_clear);
2019-06-14 02:15:01 -07:00
2017-06-20 02:05:52 -07:00
}
2018-09-16 15:22:15 -07:00
// Pool Indices
//////////////////////////////////////////
// We are done with the Pool DB, make sure there are indices
$dbp->exec("CREATE INDEX IF NOT EXISTS contents_index ON contents (fid)");
$dbp->exec("CREATE INDEX IF NOT EXISTS exiftool_index ON exiftool (fid)");
$dbp->exec("CREATE INDEX IF NOT EXISTS md5_index ON md5 (fid)");
$dbp->exec("CREATE INDEX IF NOT EXISTS mediainfo_index ON mediainfo (fid)");
$dbp->exec("CREATE INDEX IF NOT EXISTS thumbs_index ON thumbs (fid)");
2019-06-10 16:32:09 -07:00
$dbp->exec("CREATE INDEX IF NOT EXISTS icons_index ON icons (fid)");
2018-09-16 15:22:15 -07:00
2018-09-02 11:21:24 -07:00
// Spotlight
//////////////////////////////////////////
$mb['i'] = array( "PixelWidth",
"PixelHeight",
"Latitude",
"Longitude",
"DurationSeconds",
"UseCount",
"FSInvisible",
"NumberOfPages",
"PageHeight",
2019-04-27 00:48:25 -07:00
"PageWidth",
"TotalBitRate" );
2018-09-02 11:21:24 -07:00
$mb['t'] = array( "Title",
"ContentType",
"Creator",
"FSCreatorCode",
"Kind",
"FSTypeCode" );
$mb['a'] = array( "UserTags",
"WhereFroms",
"EncodingApplications" );
$mb['d'] = array( "DateAdded",
"LastUsedDate",
"ContentModificationDate",
"ContentCreationDate" );
$ibuild[] = ":pid, :spotlight";
$cbuild[] = "pid TEXT, spotlight TEXT";
foreach (array_merge($mb['i'],$mb['d']) as $item) {
$cbuild[] = $item." INTEGER";
$ibuild[] = ":".$item;
}
foreach (array_merge($mb['t'],$mb['a']) as $item) {
$cbuild[] = $item." TEXT";
$ibuild[] = ":".$item;
}
2019-10-15 18:32:21 -07:00
$dbo->exec("CREATE TABLE mdls (".implode(",",$cbuild).")");
2018-09-02 11:21:24 -07:00
if ($p['spotlight']) {
2018-09-13 01:50:00 -07:00
echo ProgressBar::start($passed_total,"Spotlight (".stepString().")");
2018-09-02 11:21:24 -07:00
foreach ($files as $splFileInfo) {
2018-09-13 01:50:00 -07:00
$path = $splFileInfo->getPathname();
2018-09-16 15:22:15 -07:00
msg($path);
2018-09-13 01:50:00 -07:00
$pid = md5($path);
$shellpath = escapeshellarg($path);
2018-09-02 11:21:24 -07:00
$mdls = shell_exec("mdls -plist - ".$shellpath." 2>&1");
2018-09-16 15:22:15 -07:00
if (substr_count(@$mdls,"\n") > 1) {
$spotlight = $parser->parseString(utf8_for_xml($mdls));
} else {
$spotlight = array();
}
2018-09-02 11:21:24 -07:00
$stmt = $dbo->prepare("INSERT INTO mdls VALUES (".implode(",",$ibuild).")");
foreach ($mb as $key => $list) {
foreach ($list as $item) {
if (@$spotlight["kMDItem".$item]) {
$stmt->BindValue(":pid",$pid);
$stmt->BindValue(":spotlight",$mdls);
switch($key) {
case "i":
case "t":
$stmt->BindValue(":".$item,$spotlight["kMDItem".$item]);
break;
case "a":
$stmt->BindValue(":".$item,serialize($spotlight["kMDItem".$item]));
break;
case "d":
$stmt->BindValue(":".$item,strtotime($spotlight["kMDItem".$item]));
break;
}
}
}
}
$stmt->execute();
2018-09-13 01:50:00 -07:00
echo ProgressBar::next(true);
2018-09-02 11:21:24 -07:00
}
2019-06-12 23:26:54 -07:00
echo ProgressBar::finish($wopt_clear);
2018-09-02 11:21:24 -07:00
}
2017-06-20 02:05:52 -07:00
// Files
//////////////////////////////////////////
2017-06-18 03:17:42 -07:00
2018-09-01 21:30:02 -07:00
$j = 0;
2018-09-13 01:50:00 -07:00
echo ProgressBar::start($passed_total, "Skimming");
2017-06-22 01:09:03 -07:00
foreach ($files as $splFileInfo) {
// DB
2019-06-10 22:04:25 -07:00
$stmt = $dbo->prepare("INSERT INTO files VALUES (:pid, :fid, :Pathname, :Path, :Filename, :Extension, :Type, :Size, :Inode, :Perms, :Owner, :ATime, :MTime, :CTime, :LinkTarget, :RealPath, :stat, :items, :newest, :fkind, :gfi_type, :gfi_attr, :gfi_created, :has_exif, :has_mediainfo, :has_hash, :thumb_filename, :thumb_width, :thumb_height, :thumb_tool, :icon_filename, :contents_filename)");
2017-06-22 01:09:03 -07:00
// Identify dir, file, link or bundle dir
$type = $splFileInfo->getType();
if ($type == "dir") {
2018-08-08 23:12:47 -07:00
foreach ($p['bundles'] as $bundle) {
2017-06-22 01:09:03 -07:00
$check = ".".$bundle;
if (substr($splFileInfo->getFilename(), -(strlen($check)), strlen($check)) == $check) { $type = "bundle"; }
}
}
$stmt->BindValue(":Type",$type);
// Path basics
$pathname = $splFileInfo->getPathname();
$path = $splFileInfo->getPath();
$filename = $splFileInfo->getFilename();
$extension = $splFileInfo->getExtension();
$shellpath = escapeshellarg($pathname);
$stmt->BindValue(":Pathname",$pathname);
$stmt->BindValue(":Path",$path);
$stmt->BindValue(":Filename",$filename);
$stmt->BindValue(":Extension",$extension);
2018-09-05 00:26:26 -07:00
//stat
2018-09-14 13:50:27 -07:00
$stmt->BindValue(":stat",serialize($sty[$j]));
2018-09-01 21:30:02 -07:00
2017-06-22 01:09:03 -07:00
if ($type == "link") {
$stmt->BindValue(":LinkTarget",$splFileInfo->getLinkTarget());
$stmt->BindValue(":RealPath",$splFileInfo->getRealPath());
} else {
$stmt->BindValue(":Inode",$splFileInfo->getInode());
$stmt->BindValue(":Perms",$splFileInfo->getPerms());
$stmt->BindValue(":Owner",$splFileInfo->getOwner().":".$splFileInfo->getGroup());
2018-09-14 13:50:27 -07:00
$stmt->BindValue(":ATime",$splFileInfo->getATime());
$stmt->BindValue(":MTime",$splFileInfo->getMTime());
$stmt->BindValue(":CTime",$splFileInfo->getCTime());
2017-06-22 01:09:03 -07:00
}
// ------------------------------------------------ //
// Generate PID and FID
$pid = md5($pathname);
$stmt->BindValue(":pid",$pid);
if ($type == "file") {
$fid = md5($splFileInfo->getSize().$splFileInfo->getMtime().$splFileInfo->getBasename());
$stmt->BindValue(":fid",$fid);
}
// Size
if ($type == "dir" || $type == "bundle") {
$size = trim(shell_exec("du -ks ".$shellpath." | cut -f1"))*1024;
} elseif ($type == "file") {
$size = $splFileInfo->getSize();
} else {
$size = null;
}
$stmt->BindValue(":Size",@$size);
// ------------------------------------------------ //
// Items
if ($type == "dir" || $type == "bundle" ) {
2018-09-16 15:22:15 -07:00
// below commented out because it was causing -1 on dirs beginning with a dot
//$items = chop(@shell_exec("find ".$shellpath." \( ! -regex '.*/\..*' \) | wc -l 2>&1"))-1;
// below should be rewritten to use $wopt_ignore files
$items = chop(@shell_exec("find ".$shellpath." \( ! -regex '.*/\.DS_Store' \) | wc -l 2>&1"))-1;
2017-06-22 01:09:03 -07:00
$stmt->BindValue(":items",@$items);
}
// ------------------------------------------------ //
2017-05-25 15:38:19 -07:00
2017-06-22 01:09:03 -07:00
// Newest
if ($type == "dir") {
$newest = @filemtime(chop(shell_exec("find ".$shellpath." -type f -not -path '*/\.*' -print0 | xargs -0 stat -f \"%m %N\" | sort -rn 2>&1 | head -1 | cut -f2- -d\" \"")));
$stmt->BindValue(":newest",@$newest);
}
// ------------------------------------------------ //
// GetFileInfo
$gfiparts = explode("\n", chop(shell_exec($bin_gfi." -P ".$shellpath." 2>&1")));
if (is_array($gfiparts)) {
foreach ($gfiparts as $line) {
list($label, $value) = explode(": ", $line);
$gfi[$label] = isset($value) ? trim($value,"\"") : null;
}
}
$writegfitype = @$gfi['type'].":".@$gfi['creator'];
if ($writegfitype == "\\0\\0\\0\\0:\\0\\0\\0\\0" || $writegfitype == ":") { $writegfitype = null; }
$stmt->BindValue(":gfi_type",$writegfitype);
$stmt->BindValue(":gfi_attr",@$gfi['attributes']);
2019-04-09 01:13:49 -07:00
$stmt->BindValue(":gfi_created",strtotime(@$gfi['created']));
2019-04-27 00:48:25 -07:00
// ------------------------------------------------ //
// Kind
unset($fkind);
if ($type == "file") {
$fkind = trim(shell_exec("export LC_ALL=C; file -b -p ".$shellpath." | cut -f1 -d,"));
2019-04-27 00:48:25 -07:00
$stmt->BindValue(":fkind",@$fkind);
}
2017-06-22 01:09:03 -07:00
// ------------------------------------------------ //
// Pool
if ($type == "file") {
unset($fetch_exif, $fetch_media, $fetch_hash, $fetch_thumb, $yes_exif, $yes_media, $yes_hash);
2018-09-14 13:50:27 -07:00
$yes_exif = $dbp->query("SELECT rowid FROM exiftool WHERE fid='".$fid."'")->fetch()[0];
2017-06-22 01:09:03 -07:00
$stmt->BindValue(":has_exif",$yes_exif);
2018-09-14 13:50:27 -07:00
$yes_media = $dbp->query("SELECT rowid FROM mediainfo WHERE fid='".$fid."'")->fetch()[0];
2017-06-22 01:09:03 -07:00
$stmt->BindValue(":has_mediainfo",$yes_media);
2018-09-14 13:50:27 -07:00
$yes_hash = $dbp->query("SELECT rowid FROM md5 WHERE fid='".$fid."'")->fetch()[0];
2017-06-22 01:09:03 -07:00
$stmt->BindValue(":has_hash",$yes_hash);
2018-09-14 13:50:27 -07:00
$yes_contents = $dbp->query("SELECT relative_path FROM contents WHERE fid='".$fid."'")->fetch()[0];
$stmt->BindValue(":contents_filename",$yes_contents);
2019-05-22 00:59:01 -07:00
2019-05-22 04:02:22 -07:00
if (!in_array($extension, $p['t_skip'])) {
2019-05-22 00:59:01 -07:00
$fetch_thumb = $dbp->query("SELECT * FROM thumbs WHERE fid='".$fid."'")->fetch();
}
2017-06-22 01:09:03 -07:00
if (@$fetch_thumb['relative_path']) {
$stmt->BindValue(":thumb_filename",$fetch_thumb['relative_path']);
$stmt->BindValue(":thumb_width",$fetch_thumb['width']);
$stmt->BindValue(":thumb_height",$fetch_thumb['height']);
2019-05-23 04:48:00 -07:00
$stmt->BindValue(":thumb_tool",$fetch_thumb['tool']);
2017-06-22 01:09:03 -07:00
} else {
$stmt->BindValue(":thumb_filename",null);
}
2019-06-10 22:04:25 -07:00
$fetch_icon = $dbp->query("SELECT * FROM icons WHERE fid='".$fid."'")->fetch();
if (@$fetch_icon['relative_path']) {
$stmt->BindValue(":icon_filename",$fetch_icon['relative_path']);
} else {
$stmt->BindValue(":icon_filename",null);
}
2019-06-09 23:53:11 -07:00
} elseif ($type == "dir") {
2019-10-15 20:09:49 -07:00
if (is_array(@$dpreview) && @$dpreview[$pathname]) {
2019-06-09 23:53:11 -07:00
$fetch_thumb = $dbp->query("SELECT * FROM thumbs WHERE fid='".$dpreview[$pathname]."'")->fetch();
if (@$fetch_thumb['relative_path']) {
$stmt->BindValue(":thumb_filename",$fetch_thumb['relative_path']);
$stmt->BindValue(":thumb_width",$fetch_thumb['width']);
$stmt->BindValue(":thumb_height",$fetch_thumb['height']);
$stmt->BindValue(":thumb_tool",$fetch_thumb['tool']);
} else {
$stmt->BindValue(":thumb_filename",null);
}
}
2017-06-22 01:09:03 -07:00
}
2019-06-09 23:53:11 -07:00
2017-06-22 01:09:03 -07:00
2018-09-02 11:21:24 -07:00
// ------------------------------------------------ //
2017-06-22 01:09:03 -07:00
// Write to DB
$stmt->execute();
// Double check stat for file against pre-run value
if ($p['stat_mode'] > 1 && $type != "link") {
2017-06-22 01:09:03 -07:00
2018-09-14 13:50:27 -07:00
$restat = statToArray(shell_exec("stat -s ".$shellpath." 2>&1"));
2017-06-22 01:09:03 -07:00
$message = array();
2018-09-14 13:50:27 -07:00
if ($sty[$j]['st_atime'] != $restat['st_atime']) {
if ($p['stat_mode'] == 3 && is_writable($pathname)) {
2018-09-14 13:50:27 -07:00
exec("touch -at `date -r ".$sty[$j]['st_atime']." +%Y%m%d%H%M.%S` ".$shellpath." 2>&1");
$message[] = "atime (fix)";
} else {
$message[] = "atime";
}
2017-06-22 01:09:03 -07:00
}
2018-09-14 13:50:27 -07:00
if ($sty[$j]['st_mtime'] != $restat['st_mtime']) {
$message[] = "mtime";
2017-06-22 01:09:03 -07:00
}
2018-09-14 13:50:27 -07:00
if ($sty[$j]['st_ctime'] != $restat['st_ctime']) {
$message[] = "ctime";
2017-06-22 01:09:03 -07:00
}
if (count($message)) { echo msg(" CHANGE = ".implode(", ", $message).""); }
2017-06-22 01:09:03 -07:00
}
2018-09-16 15:22:15 -07:00
echo ProgressBar::next($pathname);
2018-09-01 21:30:02 -07:00
$j++;
2017-06-22 01:09:03 -07:00
}
2019-06-12 23:26:54 -07:00
echo ProgressBar::finish($wopt_clear);
2017-05-25 15:38:19 -07:00
2018-09-14 13:50:27 -07:00
// Milk
//////////////////////////////////////////
2019-04-27 00:48:25 -07:00
$milk['t*DocTitle'] = ["e^Title","k^Title","m^Track_name"];
2018-09-16 15:22:15 -07:00
$milk['t*Format'] = ["m^Format","e^Compression","e^MIMEType"];
2019-04-27 00:48:25 -07:00
$milk['t*Dimensions'] = ["k^PixelWidth.k^PixelHeight","e^PixelWidth.e^PixelHeight","m^SkimDims","k^SkimPageDims"];
2018-09-16 15:22:15 -07:00
$milk['s*Seconds'] = ["k^DurationSeconds","e^Duration","m^Duration"];
$milk['d*DateTime'] = ["e^DateTimeOriginal","m^EncodedDate","e^CreateDate","e^MediaCreateDate","k^ContentCreationDate"];
$milk['t*Origin'] = ["e^CameraModelName","e^Producer","e^CreatorTool","e^WriterName","e^Software","e^Encoder","k^Creator"];
$milk['t*GPS'] = ["k^Latitude.k^Longitude","e^GPSPosition"];
2019-04-27 00:48:25 -07:00
$milk['t*Author'] = ["e^Author","e^Artist","e^Creator","e^By-line","k^Copyright"];
2018-09-16 15:22:15 -07:00
2019-04-27 00:48:25 -07:00
$milk['i*Tracks'] = ["m^SkimTrackCount","k^NumberOfPages"];
2018-09-16 15:22:15 -07:00
$milk['t*Writer'] = ["m^Writing_application.m^Writing_library"];
2019-04-27 00:48:25 -07:00
$milk['t*Bitrate'] = ["m^Overall_bit_rate","e^AvgBitrate","k^TotalBitRate"];
2018-09-16 15:22:15 -07:00
2019-04-27 00:48:25 -07:00
//$milk['i*Orientation'] = ["e^Orientation"];
//$milk['t*Profile'] = ["e^Profile"];
//$milk['i*BitDepth'] = ["e^BitDepth"];
//$milk['t*LensType'] = ["e^LensType"];
//$milk['t*FocalLength'] = ["e^FocalLength"];
//$milk['t*Aperture'] = ["e^Aperture"];
//$milk['t*LightSource'] = ["e^LightSource"];
//$milk['t*WhiteBalance'] = ["e^WhiteBalance"];
2018-09-16 15:22:15 -07:00
$delimiter = ",";
2019-04-27 00:48:25 -07:00
$display_delimiter = " x ";
2018-09-14 13:50:27 -07:00
// Build DB
2018-09-16 15:22:15 -07:00
$cbuild = $ibuild = array();
foreach (array_keys($milk) as $name) {
list($kind,$item) = explode("*",$name);
switch ($kind) {
case "t":
case "d":
case "s":
$cbuild[] = $item." TEXT";
break;
case "i":
$cbuild[] = $item." INTEGER";
break;
2018-09-14 13:50:27 -07:00
}
2018-09-16 15:22:15 -07:00
$ibuild[] = ":".$item;
2018-09-14 13:50:27 -07:00
}
$dbo->exec("CREATE TABLE milk (".implode(",",$cbuild).")");
2018-09-16 15:22:15 -07:00
$countrows = @reset($dbo->query("SELECT max(rowid) FROM files")->fetch());
echo msg("Milking ".$countrows." rows");
echo ProgressBar::start($countrows, "Milk");
$loop = $dbo->query("SELECT rowid, * FROM files");
while ($row_a = $loop->fetch()) {
$stmt = $dbo->prepare("INSERT INTO milk VALUES (".implode(",",$ibuild).")");
2019-06-13 23:18:02 -07:00
if ($dbo->query("SELECT name FROM sqlite_master WHERE name='mdls'")->fetch()) {
$row_b = @$dbo->query("SELECT * FROM mdls WHERE (rowid='".$row_a['rowid']."')")->fetch();
}
2018-09-16 15:22:15 -07:00
if (count(@$row_b) > 1) {
$m['k'] = $row_b;
2019-04-27 00:48:25 -07:00
//custom values
if ($m['k']['PageWidth'] && $m['k']['PageHeight']) {
$m['k']['SkimPageDims'] = round($m['k']['PageWidth']/72,2)."in".$display_delimiter.round($m['k']['PageHeight']/72,2)."in";
}
2018-09-16 15:22:15 -07:00
} else {
$m['k'] = null;
}
if (isset($row_a['has_exif'])) {
$row_c = $dbp->query("SELECT * FROM exiftool WHERE (rowid='".$row_a['has_exif']."')")->fetch();
$m['e'] = unserialize($row_c['tags']);
} else {
$m['e'] = null;
}
if (isset($row_a['has_mediainfo'])) {
$row_d = $dbp->query("SELECT * FROM mediainfo WHERE (rowid='".$row_a['has_mediainfo']."')")->fetch();
2019-05-22 00:59:01 -07:00
if (substr($row_d['info'],0,5) == "<?xml") {
$decoded = @json_decode(json_encode(simplexml_load_string($row_d['info'])),true);
$m_base = $decoded['File']['track'];
$m['m'] = $decoded['File']['track'][0];
} else {
$decoded = @json_decode($row_d['info'],true);
$m_base = $decoded['media']['track'];
$m['m'] = $decoded['media']['track'][0];
}
2018-09-16 15:22:15 -07:00
2019-05-22 00:59:01 -07:00
$m['m']['SkimTrackCount'] = @count($m_base);
2019-10-15 18:32:21 -07:00
if (is_array($m_base)) {
foreach (@$m_base as $track) {
if (!@$m['m']['SkimDims'] && @$track['Width'] && @$track['Height']) {
$m['m']['SkimDims'] = @sanitize($track['Width'],"i").$display_delimiter.@sanitize($track['Height'],"i");
}
2018-09-16 15:22:15 -07:00
}
}
// do seconds fix here
} else {
$m['m'] = null;
}
// M*I*L*K baby
foreach ($milk as $value => $weighted) {
list($type,$name) = explode("*",$value);
$found = 0;
foreach ($weighted as $dindex) {
// concatenante 2 values
if (!$found && strpos($dindex, ".")) {
$parts = explode(".",$dindex);
$out = array();
foreach ($parts as $part) {
list($kind,$item) = explode("^",$part);
if (@$m[$kind][$item]) {
$out[] = sanitize($m[$kind][$item],$type);
}
}
if (count($out)) {
$stmt->BindValue(":".$name,implode($delimiter,$out));
$found = 1;
}
} elseif (!$found) {
// find a single value
list($kind,$item) = explode("^",$dindex);
if (@$m[$kind][$item]) {
2019-06-10 16:32:09 -07:00
$stmt->BindValue(":".$name,@sanitize($m[$kind][$item],$type));
2018-09-16 15:22:15 -07:00
$found = 1;
}
}
}
}
echo ProgressBar::next(true);
$stmt->execute();
}
2018-09-14 13:50:27 -07:00
2019-06-12 23:26:54 -07:00
echo ProgressBar::finish($wopt_clear);
2018-09-14 13:50:27 -07:00
2017-06-20 02:05:52 -07:00
// Cleanup
//////////////////////////////////////////
2018-09-16 15:22:15 -07:00
echo msg("");
2017-06-20 02:05:52 -07:00
2018-09-02 11:21:24 -07:00
if (file_exists($error_log_file)) { echo file_get_contents($error_log_file); }
2017-06-20 02:05:52 -07:00
$seconds = floor($time = microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"]);
2018-09-02 11:21:24 -07:00
$dbo->exec("UPDATE _skim SET status='completed_in_".$seconds."'");
2018-09-05 00:26:26 -07:00
// rsync
2019-10-15 18:32:21 -07:00
if ($p['postflight'] == 3) {
$url = "http://localhost/rtc.php?db=data/".basename($bpath)."/".$stamp.".sqlite3";
exec("open ".$url);
} elseif ($p['postflight'] == 2 && $p['rsync_dest']) {
2018-09-16 15:22:15 -07:00
echo msg("rsync...");
2018-09-05 00:26:26 -07:00
$command = "rsync -avv -e ssh ".$bpath." ".$p['rsync_dest'];
$count = trim(shell_exec("find ".escapeshellarg($bpath)." | wc -l"));
2018-09-14 13:50:27 -07:00
echo ProgressBar::start($count,$p['rsync_dest']);
2018-09-05 00:26:26 -07:00
$pipe = popen($command, "r");
2018-09-14 13:50:27 -07:00
while(fgets($pipe, 2048)) { echo ProgressBar::next(true); }
2018-09-05 00:26:26 -07:00
pclose($pipe);
echo ProgressBar::finish();
2019-05-22 04:02:22 -07:00
} elseif ($p['postflight'] == 1) {
exec("open -R ".escapeshellarg($bpath));
2018-09-05 00:26:26 -07:00
}
2019-04-09 01:13:49 -07:00
$done = "Finished ".$zpath." in ".$seconds." seconds";
2019-06-10 16:32:09 -07:00
$done_m = "Memory usage: ".prettysize(memory_get_usage(true));
echo msg($done."\n".$done_m); notification($done);
2017-05-25 15:38:19 -07:00
2017-06-22 01:09:03 -07:00
unset($dbo, $dbp, $files, $family, $fx);
2017-05-03 00:39:48 -07:00
?>