From f3af3a5131eb273ced8301603633230b11ef1d24 Mon Sep 17 00:00:00 2001 From: James Ketrenos Date: Sun, 23 Sep 2018 18:07:20 -0700 Subject: [PATCH] Continued re-implementing scanning to it can be used for periodic re-scan and update Signed-off-by: James Ketrenos --- frontend/bower.json | 3 +- server/app.js | 2 +- server/scanner.js | 76 +++++++++++++++++++++++++++++++++------------ 3 files changed, 60 insertions(+), 21 deletions(-) mode change 100644 => 100755 server/scanner.js diff --git a/frontend/bower.json b/frontend/bower.json index 9459fe3..d738ed5 100644 --- a/frontend/bower.json +++ b/frontend/bower.json @@ -42,6 +42,7 @@ "iron-icons": "^2", "iron-resizable-behavior": "^2", "iron-iconset": "^2", - "iron-overlay-behavior": "2" + "iron-overlay-behavior": "2", + "paper-input": "^2" } } diff --git a/server/app.js b/server/app.js index d7dade7..2233a73 100755 --- a/server/app.js +++ b/server/app.js @@ -18,7 +18,7 @@ const express = require("express"), require("./console-line.js"); /* Monkey-patch console.log with line numbers */ -const picturesPath = config.get("picturesPath"), +const picturesPath = config.get("picturesPath").replace(/\/$/, ""), serverConfig = config.get("server"); let basePath = config.get("basePath"); diff --git a/server/scanner.js b/server/scanner.js old mode 100644 new mode 100755 index 55824bc..7107d66 --- a/server/scanner.js +++ b/server/scanner.js @@ -9,7 +9,7 @@ let scanning = 0; let photoDB = null; -const picturesPath = config.get("picturesPath"); +const picturesPath = config.get("picturesPath").replace(/\/$/, ""); const processQueue = [], triedClean = []; @@ -465,13 +465,12 @@ function triggerWatcher() { function scanDir(parent, path) { let re = new RegExp("\.((" + extensions.join(")|(") + "))$", "i"), album = { - path: path.slice(picturesPath.length), + path: path.slice(picturesPath.length) || "/", name: path.replace(/.*\//, "").replace(/_/g, " "), - assets: [], parent: parent, allAssetCount: 0, allAlbumCount: 0 - }; + }, albums = [ album ], assets = []; return new Promise(function(resolve, reject) { fs.readdir(path, function(error, files) { @@ -508,9 +507,11 @@ function scanDir(parent, path) { return stat(filepath).then(function(stats) { if (stats.isDirectory()) { - return scanDir(album, filepath).then(function(child) { - album.allAssetCount += child.allAssetCount; - album.allAlbumCount += child.allAlbumCount + 1; + return scanDir(album, filepath).spread(function(_albums, _assets) { + album.allAssetCount += _assets.length; + album.allAlbumCount += _albums.length + 1; + albums = albums.concat(_albums); + assets = assets.concat(_assets); }).catch(function(error) { console.warn("Could not scanDir " + filepath + ": " + error); }); @@ -521,8 +522,7 @@ function scanDir(parent, path) { return; } - album.allAssetCount++; - album.assets.push({ + assets.push({ path: path.slice(picturesPath.length), filename: file.replace(rawExtension, ".jpg"), /* We will be converting from NEF/ORF => JPG */ stats: stats @@ -530,27 +530,65 @@ function scanDir(parent, path) { }); }); }).then(function() { - return album; + return [ albums, assets ]; }); } +function findOrCreateDBAlbum(album) { + let query = "SELECT id FROM albums WHERE path=:path AND "; + if (!album.parent) { + query += "parentId IS NULL"; + } else { + if (!album.parent.id) { + let error = "Albums in array in non ancestral order!"; + console.error(error); + throw error; + } + album.parentId = album.parent.id; + query += "parentId=:parentId"; + } + + return photoDB.sequelize.query(query, { + replacements: album, + type: photoDB.sequelize.QueryTypes.SELECT + }).then(function(results) { + if (results.length == 0) { + return photoDB.sequelize.query("INSERT INTO albums (path,parentId,name) VALUES(:path,:parent,:name)", { + replacements: replacements + }).then(function(results) { + return results[1].lastID; + }); + } else { + return results[0].id; + } + }).then(function(id) { + album.parentId = id; + return id; + }); +} module.exports = { scan: function (db) { photoDB = db; /* 1. Scan for all assets which will be managed by the system. readdir - - returns set of albums and photos. - * 2. Compute HASH of the file - * 3. Check for HASH in photohash -- skip? - * 4. Check for and create thumbs/FILE thumbs/scaled/FILE - * 5. If necessary, create JPG from RAW - * 6. Check in DB and update last-scanned date - * 7. Look up all DB entries with last-scanned date < NOW -- purge? + * 2. Check if entry in DB. Check mod-time in DB vs. stats from #1 + * 3. If not in DB, or mod-time changed, compute HASH of the file + * 4. Check for HASH in photohash -- skip? + * 5. Check for and create thumbs/FILE thumbs/scaled/FILE + * 6. If necessary, create JPG from RAW + * 7. Update last-scanned date in DB for entry + * 8. Look up all DB entries with last-scanned date < NOW -- purge from DB (they were + * removed on disk)? Also purge from the HASH table. */ let now = Date.now(); - return scanDir(null, picturesPath).then(function(albums) { - console.log("Found " + albums.allAssetCount + " assets in " + albums.allAlbumCount + " albums after " + + return scanDir(null, picturesPath).spread(function(albums, assets) { + console.log("Found " + assets.length + " assets in " + albums.length + " albums after " + ((Date.now() - now) / 1000) + "s"); + return Promise.map(albums, function(album) { + return db.sequelize + }, { + concurrency: 5 + }); /*triggerWatcher();*/ }); }