Started implementing maintainer action buttons
Signed-off-by: James Ketrenos <james_git@ketrenos.com>
This commit is contained in:
parent
97c2d1dd66
commit
77332428e6
@ -2,6 +2,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<link rel="import" href="../bower_components/polymer/polymer.html">
|
<link rel="import" href="../bower_components/polymer/polymer.html">
|
||||||
|
<link rel="import" href="../bower_components/paper-icon-button/paper-icon-button.html">
|
||||||
<link rel="import" href="../bower_components/iron-icon/iron-icon.html">
|
<link rel="import" href="../bower_components/iron-icon/iron-icon.html">
|
||||||
<link rel="import" href="../bower_components/iron-icons/iron-icons.html">
|
<link rel="import" href="../bower_components/iron-icons/iron-icons.html">
|
||||||
<link rel="import" href="../bower_components/iron-pages/iron-pages.html">
|
<link rel="import" href="../bower_components/iron-pages/iron-pages.html">
|
||||||
@ -28,7 +29,7 @@
|
|||||||
@apply --photo-thumbnail;
|
@apply --photo-thumbnail;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host > div {
|
#info {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
@ -37,15 +38,29 @@
|
|||||||
left: 0px;
|
left: 0px;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
font-size: 0.6em;
|
font-size: 0.6em;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(:hover) > div {
|
#actions {
|
||||||
|
padding: 0.5em;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
opacity: 0;
|
||||||
|
font-size: 0.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host(:hover) #info,
|
||||||
|
:host(:hover) #actions {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="layout vertical start">
|
<div id="actions" hidden$="[[!actions.length]]" class="horziontal layout center end">
|
||||||
|
<template is="dom-repeat" items="[[actions]]">
|
||||||
|
<paper-icon-button on-tap="_fireAction" icon="[[item]]"></paper-icon-button>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="info" class="layout vertical start">
|
||||||
<div>[[item.name]] ([[item.id]])</div>
|
<div>[[item.name]] ([[item.id]])</div>
|
||||||
<div>[[item.taken]]</div>
|
<div>[[item.taken]]</div>
|
||||||
<div on-tap="_pathTap">[[item.path]]</div>
|
<div on-tap="_pathTap">[[item.path]]</div>
|
||||||
@ -82,6 +97,12 @@
|
|||||||
"thumbChanged(thumbpath, visible)"
|
"thumbChanged(thumbpath, visible)"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
_fireAction: function(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
event.preventDefault();
|
||||||
|
this.fire("action", event.model.item);
|
||||||
|
},
|
||||||
|
|
||||||
thumbChanged: function(thumbpath, visible) {
|
thumbChanged: function(thumbpath, visible) {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
this.style.backgroundImage = "url(" +
|
this.style.backgroundImage = "url(" +
|
||||||
|
@ -221,6 +221,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
photo-thumbnail {
|
photo-thumbnail {
|
||||||
|
transition: opacity 0.25s ease-in-out;
|
||||||
--photo-thumbnail: {
|
--photo-thumbnail: {
|
||||||
border: 3px solid white;
|
border: 3px solid white;
|
||||||
};
|
};
|
||||||
@ -1212,6 +1213,14 @@
|
|||||||
|
|
||||||
var thumbnail = document.createElement("photo-thumbnail");
|
var thumbnail = document.createElement("photo-thumbnail");
|
||||||
thumbnail.item = photo;
|
thumbnail.item = photo;
|
||||||
|
if (this.user.maintainer) {
|
||||||
|
let actions = [ "delete" ];
|
||||||
|
if (this.mode == "duplicates") {
|
||||||
|
actions.unshift("text-format");
|
||||||
|
}
|
||||||
|
thumbnail.actions = actions;
|
||||||
|
thumbnail.addEventListener("action", this._imageAction.bind(this));
|
||||||
|
}
|
||||||
thumbnail.addEventListener("load-image", this._imageTap.bind(this));
|
thumbnail.addEventListener("load-image", this._imageTap.bind(this));
|
||||||
thumbnail.addEventListener("load-album", this.loadAlbum.bind(this));
|
thumbnail.addEventListener("load-album", this.loadAlbum.bind(this));
|
||||||
|
|
||||||
@ -1226,6 +1235,31 @@
|
|||||||
this.processing = false;
|
this.processing = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_imageAction: function(event) {
|
||||||
|
console.log(event.detail);
|
||||||
|
switch (event.detail) {
|
||||||
|
case "delete": /* Delete image */
|
||||||
|
var thumbnail = event.currentTarget;
|
||||||
|
thumbnail.style.opacity = 0;
|
||||||
|
thumbnail.style.pointerEvents = "none";
|
||||||
|
|
||||||
|
this.async(function(thumbnail) {
|
||||||
|
thumbnail.parentElement.removeChild(thumbnail);
|
||||||
|
for (var i = 0; i < this.thumbnails.length; i++) {
|
||||||
|
if (this.thumbnails[i] == thumbnail) {
|
||||||
|
console.log("Found thumbnail");
|
||||||
|
this.thumbnails.splice(i, 1);
|
||||||
|
this.notifyPath("thumbnails.length");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.bind(this, thumbnail), 250);
|
||||||
|
break;
|
||||||
|
case "text-format": /* Rename this image */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
pathTapped: function(event) {
|
pathTapped: function(event) {
|
||||||
this.path = event.currentTarget.path;
|
this.path = event.currentTarget.path;
|
||||||
Polymer.dom(this.$.thumbnails).innerHTML = "";
|
Polymer.dom(this.$.thumbnails).innerHTML = "";
|
||||||
|
@ -27,10 +27,10 @@ function removeNewerFile(path, fileA, fileB) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (statsA.mtime > statsB.mtime) {
|
if (statsA.mtime > statsB.mtime) {
|
||||||
console.log("Removing file by moving to 'corrupt':" + fileA);
|
setStatus("Removing file by moving to 'corrupt':" + fileA);
|
||||||
moveCorrupt(path, fileA);
|
moveCorrupt(path, fileA);
|
||||||
} else {
|
} else {
|
||||||
console.log("Removing file by moving to 'corrupt':" + fileB);
|
setStatus("Removing file by moving to 'corrupt':" + fileB);
|
||||||
moveCorrupt(path, fileB);
|
moveCorrupt(path, fileB);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -101,14 +101,14 @@ const exists = function(path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function convertRawToJpg(path, file) {
|
function convertRawToJpg(path, file) {
|
||||||
console.log("Converting " + path + file);
|
setStatus("Converting " + path + file);
|
||||||
|
|
||||||
path = picturesPath + path;
|
path = picturesPath + path;
|
||||||
|
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
return exists(path + file.replace(rawExtension, ".jpg")).then(function(exist) {
|
return exists(path + file.replace(rawExtension, ".jpg")).then(function(exist) {
|
||||||
if (exist) {
|
if (exist) {
|
||||||
console.log("Skipping already converted file: " + file);
|
setStatus("Skipping already converted file: " + file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,25 +133,25 @@ function convertRawToJpg(path, file) {
|
|||||||
ufraw.on('exit', function(stderr, code, signal) {
|
ufraw.on('exit', function(stderr, code, signal) {
|
||||||
if (signal || code != 0) {
|
if (signal || code != 0) {
|
||||||
let error = "UFRAW for " + path + file + " returned an error: " + code + "\n" + signal + "\n" + stderr.join("\n") + "\n";
|
let error = "UFRAW for " + path + file + " returned an error: " + code + "\n" + signal + "\n" + stderr.join("\n") + "\n";
|
||||||
console.error(error);
|
setStatus(error, "error");
|
||||||
return moveCorrupt(path, file).then(function() {
|
return moveCorrupt(path, file).then(function() {
|
||||||
console.warn("ufraw failed");
|
setStatus("ufraw failed", "warn");
|
||||||
return reject(error);
|
return reject(error);
|
||||||
}).catch(function(error) {
|
}).catch(function(error) {
|
||||||
console.warn("moveCorrupt failed");
|
setStatus("moveCorrupt failed", "warn");
|
||||||
return reject(error);
|
return reject(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return mkdir(path + "raw").then(function() {
|
return mkdir(path + "raw").then(function() {
|
||||||
fs.rename(path + file, path + "raw/" + file, function(err) {
|
fs.rename(path + file, path + "raw/" + file, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error("Unable to move RAW file: " + path + file);
|
setStatus("Unable to move RAW file: " + path + file, "error");
|
||||||
return reject(err);
|
return reject(err);
|
||||||
}
|
}
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
}).catch(function(error) {
|
}).catch(function(error) {
|
||||||
console.warn("mkdir failed");
|
setStatus("mkdir failed", "warn");
|
||||||
return reject(error);
|
return reject(error);
|
||||||
});
|
});
|
||||||
}.bind(this, ufraw));
|
}.bind(this, ufraw));
|
||||||
@ -165,13 +165,13 @@ function moveCorrupt(path, file) {
|
|||||||
path = picturesPath + path;
|
path = picturesPath + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.warn("Moving corrupt file '" + file + "' to " + path + "corrupt");
|
setStatus("Moving corrupt file '" + file + "' to " + path + "corrupt", "warn");
|
||||||
|
|
||||||
return mkdir(path + "corrupt").then(function() {
|
return mkdir(path + "corrupt").then(function() {
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
fs.rename(path + file, path + "corrupt/" + file, function(err) {
|
fs.rename(path + file, path + "corrupt/" + file, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error("Unable to move corrupt file: " + path + file);
|
setStatus("Unable to move corrupt file: " + path + file, "error");
|
||||||
return reject(err);
|
return reject(err);
|
||||||
}
|
}
|
||||||
return resolve();
|
return resolve();
|
||||||
@ -202,7 +202,7 @@ function processBlock(items) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let toProcess = processing.length, lastMessage = moment();
|
let toProcess = processing.length, lastMessage = moment();
|
||||||
console.log("Items to be processed: " + toProcess);
|
setStatus("Items to be processed: " + toProcess);
|
||||||
return Promise.mapSeries(processing, function(asset) {
|
return Promise.mapSeries(processing, function(asset) {
|
||||||
return computeHash(picturesPath + asset.album.path + asset.filename).then(function(hash) {
|
return computeHash(picturesPath + asset.album.path + asset.filename).then(function(hash) {
|
||||||
asset.hash = hash;
|
asset.hash = hash;
|
||||||
@ -222,7 +222,7 @@ function processBlock(items) {
|
|||||||
} else if (results[0].hash != asset.hash) {
|
} else if (results[0].hash != asset.hash) {
|
||||||
query = "UPDATE photohashes SET hash=:hash WHERE photoId=:id";
|
query = "UPDATE photohashes SET hash=:hash WHERE photoId=:id";
|
||||||
} else if (results[0].photoId != asset.id) {
|
} else if (results[0].photoId != asset.id) {
|
||||||
console.log("Duplicate asset: " +
|
setStatus("Duplicate asset: " +
|
||||||
"'" + asset.album.path + asset.filename + "' is a copy of " +
|
"'" + asset.album.path + asset.filename + "' is a copy of " +
|
||||||
"'" + results[0].path + results[0].filename + "'");
|
"'" + results[0].path + results[0].filename + "'");
|
||||||
duplicates.push(asset);
|
duplicates.push(asset);
|
||||||
@ -293,7 +293,7 @@ function processBlock(items) {
|
|||||||
asset.modified = moment(metadata.exif.exif.DateTimeOriginal).format();
|
asset.modified = moment(metadata.exif.exif.DateTimeOriginal).format();
|
||||||
|
|
||||||
if (asset.taken == "Invalid date" || asset.taken.replace(/T.*/, "") == "1899-11-30") {
|
if (asset.taken == "Invalid date" || asset.taken.replace(/T.*/, "") == "1899-11-30") {
|
||||||
console.log("Invalid EXIF date information for " + asset.album.path + asset.filename);
|
setStatus("Invalid EXIF date information for " + asset.album.path + asset.filename);
|
||||||
asset.taken = asset.modified = moment(created).format();
|
asset.taken = asset.modified = moment(created).format();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -332,7 +332,7 @@ function processBlock(items) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return image.resize(256, 256).toFile(dst).catch(function(error) {
|
return image.resize(256, 256).toFile(dst).catch(function(error) {
|
||||||
console.error("Error resizing image: " + dst, error);
|
setStatus("Error resizing image: " + dst + "\n" + error, "error");
|
||||||
throw error;
|
throw error;
|
||||||
});
|
});
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
@ -343,7 +343,7 @@ function processBlock(items) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return image.resize(Math.min(1024, metadata.width)).toFile(dst).catch(function(error) {
|
return image.resize(Math.min(1024, metadata.width)).toFile(dst).catch(function(error) {
|
||||||
console.error("Error resizing image: " + dst, error);
|
setStatus("Error resizing image: " + dst + "\n" + error, "error");
|
||||||
throw error;
|
throw error;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -355,7 +355,7 @@ function processBlock(items) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).catch(function(error) {
|
}).catch(function(error) {
|
||||||
console.error("Error reading image " + src + ": ", error);
|
setStatus("Error reading image " + src + ":\n" + error, "error");
|
||||||
return moveCorrupt(path, file).then(function() {
|
return moveCorrupt(path, file).then(function() {
|
||||||
|
|
||||||
/* If the original file was not a NEF/ORF, we are done... */
|
/* If the original file was not a NEF/ORF, we are done... */
|
||||||
@ -369,31 +369,31 @@ function processBlock(items) {
|
|||||||
/* Move the NEF/ORF to /corrupt as well so it isn't re-checked again and again... */
|
/* Move the NEF/ORF to /corrupt as well so it isn't re-checked again and again... */
|
||||||
// return moveCorrupt(path, asset.filename);
|
// return moveCorrupt(path, asset.filename);
|
||||||
|
|
||||||
console.error("Already attempted to convert NEF/ORF to JPG: " + path + file);
|
setStatus("Already attempted to convert NEF/ORF to JPG: " + path + file, "error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.warn("Adding " + path + file + " back onto processing queue.");
|
setStatus("Adding " + path + file + " back onto processing queue.", "error");
|
||||||
triedClean.push(path + file);
|
triedClean.push(path + file);
|
||||||
processBlock([ path, file, created, albumId ]);
|
processBlock([ path, file, created, albumId ]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).catch(function() {
|
}).catch(function() {
|
||||||
console.warn("Continuing file processing.");
|
setStatus("Continuing file processing.", "warn");
|
||||||
});
|
});
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
toProcess--;
|
toProcess--;
|
||||||
if (moment().add(-5, 'seconds') > lastMessage) {
|
if (moment().add(-5, 'seconds') > lastMessage) {
|
||||||
console.log("Items to be processed: " + toProcess);
|
setStatus("Items to be processed: " + toProcess);
|
||||||
lastMessage = moment();
|
lastMessage = moment();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}).catch(function(error) {
|
}).catch(function(error) {
|
||||||
console.log("Error processing file. Continuing.");
|
setStatus("Error processing file. Continuing.");
|
||||||
throw error;
|
throw error;
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
console.log("Completed processing queue. Marking " + duplicates.length + " duplicates.");
|
setStatus("Completed processing queue. Marking " + duplicates.length + " duplicates.");
|
||||||
let dups = [];
|
let dups = [];
|
||||||
duplicates.forEach(function(asset) {
|
duplicates.forEach(function(asset) {
|
||||||
/* If not already marked as a duplicate, mark it. */
|
/* If not already marked as a duplicate, mark it. */
|
||||||
@ -412,7 +412,7 @@ function processBlock(items) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
console.log("Looking for removed assets");
|
setStatus("Looking for removed assets");
|
||||||
return photoDB.sequelize.query("SELECT photos.scanned,photos.id,photos.filename,albums.path FROM photos " +
|
return photoDB.sequelize.query("SELECT photos.scanned,photos.id,photos.filename,albums.path FROM photos " +
|
||||||
"LEFT JOIN albums ON (albums.id=photos.albumId) " +
|
"LEFT JOIN albums ON (albums.id=photos.albumId) " +
|
||||||
"WHERE photos.deleted=0 AND DATETIME(photos.scanned)<DATETIME(:lastScan)", {
|
"WHERE photos.deleted=0 AND DATETIME(photos.scanned)<DATETIME(:lastScan)", {
|
||||||
@ -422,11 +422,11 @@ function processBlock(items) {
|
|||||||
type: photoDB.sequelize.QueryTypes.SELECT
|
type: photoDB.sequelize.QueryTypes.SELECT
|
||||||
}).then(function(results) {
|
}).then(function(results) {
|
||||||
let deleted = [];
|
let deleted = [];
|
||||||
console.log("Checking " + results.length + " assets to see if they are on disk.");
|
setStatus("Checking " + results.length + " assets to see if they are on disk.");
|
||||||
return Promise.map(results, function(asset) {
|
return Promise.map(results, function(asset) {
|
||||||
return exists(asset.path + asset.filename).then(function(exist) {
|
return exists(asset.path + asset.filename).then(function(exist) {
|
||||||
if (!exist) {
|
if (!exist) {
|
||||||
console.log(asset.path + asset.filename + " no longer exists on disk. Marking as deleted.");
|
setStatus(asset.path + asset.filename + " no longer exists on disk. Marking as deleted.");
|
||||||
deleted.push(asset.id);
|
deleted.push(asset.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -442,7 +442,7 @@ function processBlock(items) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
console.log(deleted.length + " assets deleted.");
|
setStatus(deleted.length + " assets deleted.");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -464,7 +464,7 @@ function scanDir(parent, path) {
|
|||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
fs.readdir(path, function(error, files) {
|
fs.readdir(path, function(error, files) {
|
||||||
if (error) {
|
if (error) {
|
||||||
console.warn("Could not readdir: " + path);
|
setStatus("Could not readdir: " + path, "warn");
|
||||||
return resolve([]);
|
return resolve([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -480,7 +480,7 @@ function scanDir(parent, path) {
|
|||||||
* version from disk. */
|
* version from disk. */
|
||||||
if (file != files[i] && file.toUpperCase() == files[i]) {
|
if (file != files[i] && file.toUpperCase() == files[i]) {
|
||||||
removeNewerFile(path, file, files[i]);
|
removeNewerFile(path, file, files[i]);
|
||||||
console.log("Duplicate file in " + path + ": ", file, files[i]);
|
setStatus("Duplicate file in " + path + ": ", file, files[i]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -502,7 +502,7 @@ function scanDir(parent, path) {
|
|||||||
albums = albums.concat(_albums);
|
albums = albums.concat(_albums);
|
||||||
assets = assets.concat(_assets);
|
assets = assets.concat(_assets);
|
||||||
}).catch(function(error) {
|
}).catch(function(error) {
|
||||||
console.warn("Could not scanDir " + filepath + ": " + error);
|
setStatus("Could not scanDir " + filepath + ": " + error, "error");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,7 +544,7 @@ function findOrCreateDBAlbum(transaction, album) {
|
|||||||
} else {
|
} else {
|
||||||
if (!album.parent.id) {
|
if (!album.parent.id) {
|
||||||
let error = "Albums in array in non ancestral order!";
|
let error = "Albums in array in non ancestral order!";
|
||||||
console.error(error);
|
setStatus(error, "error");
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
album.parentId = album.parent.id;
|
album.parentId = album.parent.id;
|
||||||
@ -557,7 +557,7 @@ function findOrCreateDBAlbum(transaction, album) {
|
|||||||
}).then(function(results) {
|
}).then(function(results) {
|
||||||
if (results.length == 0) {
|
if (results.length == 0) {
|
||||||
if (!album.parent) {
|
if (!album.parent) {
|
||||||
console.warn("Creating top level album: " + picturesPath);
|
setStatus("Creating top level album: " + picturesPath, "warn" );
|
||||||
}
|
}
|
||||||
return photoDB.sequelize.query("INSERT INTO albums (path,parentId,name) VALUES(:path,:parentId,:name)", {
|
return photoDB.sequelize.query("INSERT INTO albums (path,parentId,name) VALUES(:path,:parentId,:name)", {
|
||||||
replacements: album,
|
replacements: album,
|
||||||
@ -577,7 +577,7 @@ function findOrCreateDBAlbum(transaction, album) {
|
|||||||
function findOrUpdateDBAsset(transaction, asset) {
|
function findOrUpdateDBAsset(transaction, asset) {
|
||||||
if (!asset.album || !asset.album.id) {
|
if (!asset.album || !asset.album.id) {
|
||||||
let error = "Asset being processed without an album";
|
let error = "Asset being processed without an album";
|
||||||
console.error(error);
|
setStatus(error, "warn");
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -607,7 +607,7 @@ function findOrUpdateDBAsset(transaction, asset) {
|
|||||||
/* If the size on disk changed, update the size entry in the DB. This shouldn't happen in
|
/* If the size on disk changed, update the size entry in the DB. This shouldn't happen in
|
||||||
* production unless someone modifies the file, then re-stamps the modified time */
|
* production unless someone modifies the file, then re-stamps the modified time */
|
||||||
if (asset.size != results[0].size) {
|
if (asset.size != results[0].size) {
|
||||||
console.log("File was modified with time-restamp (HASH regeneration will be queued): " + asset.filename);
|
setStatus("File was modified with time-restamp (HASH regeneration will be queued): " + asset.filename);
|
||||||
delete asset.scanned;
|
delete asset.scanned;
|
||||||
delete asset.modified;
|
delete asset.modified;
|
||||||
}
|
}
|
||||||
@ -638,7 +638,30 @@ function computeHash(filepath) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let scanning = false;
|
let scanningStatus = [];
|
||||||
|
|
||||||
|
function setStatus(status, level) {
|
||||||
|
if (status == "idle") {
|
||||||
|
scanningStatus = [];
|
||||||
|
}
|
||||||
|
level = level || "info";
|
||||||
|
scanningStatus.push({
|
||||||
|
level: level,
|
||||||
|
time: moment().format(),
|
||||||
|
log: status
|
||||||
|
});
|
||||||
|
switch (level) {
|
||||||
|
case "error":
|
||||||
|
console.error(status);
|
||||||
|
break;
|
||||||
|
case "warn":
|
||||||
|
console.warn(status);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function doScan() {
|
function doScan() {
|
||||||
/* 1. Scan for all assets which will be managed by the system. readdir
|
/* 1. Scan for all assets which will be managed by the system. readdir
|
||||||
* 2. Check if entry in DB. Check mod-time in DB vs. stats from #1
|
* 2. Check if entry in DB. Check mod-time in DB vs. stats from #1
|
||||||
@ -659,12 +682,12 @@ function doScan() {
|
|||||||
let now = Date.now();
|
let now = Date.now();
|
||||||
let needsProcessing = [];
|
let needsProcessing = [];
|
||||||
|
|
||||||
if (scanning) {
|
if (scanningStatus.length != 0) {
|
||||||
return Promise.resolve("scanning");
|
return Promise.resolve(scanningStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
return scanDir(null, picturesPath).spread(function(albums, assets) {
|
return scanDir(null, picturesPath).spread(function(albums, assets) {
|
||||||
console.log("Found " + assets.length + " assets in " + albums.length + " albums after " +
|
setStatus("Found " + assets.length + " assets in " + albums.length + " albums after " +
|
||||||
((Date.now() - now) / 1000) + "s");
|
((Date.now() - now) / 1000) + "s");
|
||||||
/* One at a time, in series, as the album[] array has parents first, then descendants.
|
/* One at a time, in series, as the album[] array has parents first, then descendants.
|
||||||
* Operating in parallel could result in a child being searched for prior to the parent */
|
* Operating in parallel could result in a child being searched for prior to the parent */
|
||||||
@ -676,17 +699,17 @@ function doScan() {
|
|||||||
return findOrCreateDBAlbum(transaction, album).then(function() {
|
return findOrCreateDBAlbum(transaction, album).then(function() {
|
||||||
toProcess--;
|
toProcess--;
|
||||||
if (moment().add(-5, 'seconds') > lastMessage) {
|
if (moment().add(-5, 'seconds') > lastMessage) {
|
||||||
console.log("Albums to be created in DB: " + toProcess);
|
setStatus("Albums to be created in DB: " + toProcess);
|
||||||
lastMessage = moment();
|
lastMessage = moment();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
console.log("Processed " + albums.length + " album DB entries in " +
|
setStatus("Processed " + albums.length + " album DB entries in " +
|
||||||
((Date.now() - now) / 1000) + "s");
|
((Date.now() - now) / 1000) + "s");
|
||||||
now = Date.now();
|
now = Date.now();
|
||||||
|
|
||||||
console.log(assets.length + " assets remaining to be verified/updated. ETA N/A");
|
setStatus(assets.length + " assets remaining to be verified/updated. ETA N/A");
|
||||||
|
|
||||||
let processed = 0, start = Date.now(), last = 0, updateScanned = [], newEntries = 0;
|
let processed = 0, start = Date.now(), last = 0, updateScanned = [], newEntries = 0;
|
||||||
return photoDB.sequelize.transaction(function(transaction) {
|
return photoDB.sequelize.transaction(function(transaction) {
|
||||||
@ -721,7 +744,7 @@ function doScan() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let remaining = assets.length - processed, eta = Math.ceil((elapsed / 1000) * remaining / (processed - last));
|
let remaining = assets.length - processed, eta = Math.ceil((elapsed / 1000) * remaining / (processed - last));
|
||||||
console.log(remaining + " assets remaining be verified/updated " +
|
setStatus(remaining + " assets remaining be verified/updated " +
|
||||||
"(" + newEntries + " new entries, " + (processed - newEntries) + " up-to-date so far). ETA " + eta + "s");
|
"(" + newEntries + " new entries, " + (processed - newEntries) + " up-to-date so far). ETA " + eta + "s");
|
||||||
last = processed;
|
last = processed;
|
||||||
start = Date.now();
|
start = Date.now();
|
||||||
@ -736,23 +759,23 @@ function doScan() {
|
|||||||
ids: updateScanned
|
ids: updateScanned
|
||||||
}
|
}
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
console.log("Updated scan date of " + updateScanned.length + " assets");
|
setStatus("Updated scan date of " + updateScanned.length + " assets");
|
||||||
updateScanned = [];
|
updateScanned = [];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
console.log(newEntries + " assets are new. " + (needsProcessing.length - newEntries) + " assets have been modified.");
|
setStatus(newEntries + " assets are new. " + (needsProcessing.length - newEntries) + " assets have been modified.\n" +
|
||||||
console.log(needsProcessing.length + " assets need HASH computed. " + (assets.length - needsProcessing.length) + " need no update.");;
|
needsProcessing.length + " assets need HASH computed. " + (assets.length - needsProcessing.length) + " need no update.");;
|
||||||
processBlock(needsProcessing);
|
processBlock(needsProcessing);
|
||||||
needsProcessing = [];
|
needsProcessing = [];
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
console.log("Scanned " + assets.length + " asset DB entries in " +
|
setStatus("Scanned " + assets.length + " asset DB entries in " +
|
||||||
((Date.now() - now) / 1000) + "s");
|
((Date.now() - now) / 1000) + "s");
|
||||||
assets = [];
|
assets = [];
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
console.log("Total time to initialize DB and all scans: " + ((Date.now() - initialized) / 1000) + "s");
|
setStatus("Total time to initialize DB and all scans: " + ((Date.now() - initialized) / 1000) + "s");
|
||||||
return photoDB.sequelize.query("SELECT max(scanned) AS scanned FROM photos", {
|
return photoDB.sequelize.query("SELECT max(scanned) AS scanned FROM photos", {
|
||||||
type: photoDB.sequelize.QueryTypes.SELECT
|
type: photoDB.sequelize.QueryTypes.SELECT
|
||||||
}).then(function(results) {
|
}).then(function(results) {
|
||||||
@ -761,11 +784,14 @@ function doScan() {
|
|||||||
} else {
|
} else {
|
||||||
lastScan = new Date(results[0].scanned);
|
lastScan = new Date(results[0].scanned);
|
||||||
}
|
}
|
||||||
console.log("Updating any asset newer than " + moment(lastScan).format());
|
setStatus("Updating any asset newer than " + moment(lastScan).format());
|
||||||
});
|
});
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
scanning = false;
|
setStatus("idle");
|
||||||
return "scan complete";
|
return "scan complete";
|
||||||
|
}).catch(function(error) {
|
||||||
|
setStatus(error);
|
||||||
|
throw error;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -773,8 +799,6 @@ module.exports = {
|
|||||||
init: function(db) {
|
init: function(db) {
|
||||||
photoDB = db;
|
photoDB = db;
|
||||||
},
|
},
|
||||||
scan: function () {
|
scan: doScan
|
||||||
return doScan();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user