From 55a9c16e7b5e0ab8a80ba0b7176583e51632ad77 Mon Sep 17 00:00:00 2001 From: James Ketrenos Date: Wed, 27 Nov 2019 22:27:25 -0800 Subject: [PATCH] Added 'fixdate.js' as it was on the deployed server Signed-off-by: James Ketrenos --- fixdate.js | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 fixdate.js diff --git a/fixdate.js b/fixdate.js new file mode 100644 index 0000000..ff5a28b --- /dev/null +++ b/fixdate.js @@ -0,0 +1,134 @@ +"use strict"; + +const Promise = require("bluebird"), + fs = require("fs"), + config = require("config"), + moment = require("moment"), + crypto = require("crypto"); + +let photoDB = null; + +const picturesPath = config.get("picturesPath").replace(/\/$/, "") + "/"; + +const stat = function (_path) { + if (_path.indexOf(picturesPath.replace(/\/$/, "")) == 0) { + _path = _path.substring(picturesPath.length); + } + + let path = picturesPath + _path; + + return new Promise(function (resolve, reject) { + fs.stat(path, function (error, stats) { + if (error) { + return reject(error); + } + return resolve(stats); + }); + }); +} + +const rawExtension = /\.nef$/i, extensions = [ "jpg", "jpeg", "png", "gif", "nef" ]; + +function scanDir(parent, path) { + let re = new RegExp("\.((" + extensions.join(")|(") + "))$", "i"), + album = { + path: path.slice(picturesPath.length), /* path already ends in '/' */ + parent: parent, + }, albums = [ album ], assets = []; + + console.log("Scanning for date fixes: " + (path || "/")); + return new Promise(function(resolve, reject) { + fs.readdir(path, function(error, files) { + if (error) { + console.warn("Could not readdir: " + path); + return resolve([]); + } + + /* Remove 'thumbs' and 'raw' directories from being processed */ + files = files.filter(function(file) { + for (var i = 0; i < files.length; i++) { + /* If this file has an original NEF/ORF on the system, don't add the JPG to the DB */ + if (rawExtension.exec(files[i]) && file == files[i].replace(rawExtension, ".jpg")) { + return false; + } + + /* If there is a different CASE (eg. JPG vs jpg) don't add it, and remove the 'lower case' + * version from disk. */ + if (file != files[i] && file.toUpperCase() == files[i]) { + removeNewerFile(path, file, files[i]); + console.log("Duplicate file in " + path + ": ", file, files[i]); + return false; + } + } + + return file != "raw" && file != "thumbs" && file != ".git" && file != "corrupt"; + }); + + return resolve(files); + }); + }).then(function(files) { + return Promise.map(files, function(file) { + let filepath = path + file; + return stat(filepath).then(function(stats) { + if (stats.isDirectory()) { + return scanDir(album, filepath + "/").spread(function(_albums, _assets) { + albums = albums.concat(_albums); + assets = assets.concat(_assets); + }); + } + + /* Check file extensions */ + if (!re.exec(file)) { + return; + } + + return photoDB.sequelize.query("SELECT photos.id,photos.added FROM photos,albums " + + "WHERE albums.id=photos.albumId AND albums.path=:path AND photos.filename=:filename " + + "AND photos.added>:mtime", { + replacements: { + mtime: stats.mtime, + filename: file.replace(rawExtension, ".jpg"), + path: album.path + }, + type: photoDB.sequelize.QueryTypes.SELECT + }).then(function(results) { + if (results.length == 1) { + assets.push({ + id: results[0].id, + mtime: stats.mtime + }); + } + }); + }); + }); + }).then(function() { + return [ albums, assets ]; + }); +} + +require("./server/db/photos").then(function(db) { + photoDB = db; + return scanDir(null, picturesPath).spread(function(albums, assets) { + console.log(assets.length + " assets have incorrect dates."); + let toProcess = assets.length, lastMessage = moment(), started = moment(); + return photoDB.sequelize.transaction(function (t) { + return Promise.map(assets, function(asset) { + return photoDB.sequelize.query( + "UPDATE photos SET added=:mtime,taken=:mtime,modified=:mtime WHERE id=:id", { + replacements: asset, + transaction: t, + }).then(function(results) { + toProcess--; + if (moment().add(-1, 'seconds') > lastMessage) { + console.log("Items to be processed: " + toProcess); + lastMessage = moment(); + } + }); + }, { + concurrency: 5 + }); + }).then(function(result) { + console.log("Update transaction completed: " + started.toNow()); + }) + }); +});