Add --quick option to fb scan ...

This commit is contained in:
Bryan Ashby 2018-02-16 23:00:15 -07:00
parent cd51cc1adb
commit 9ad38f84a7
2 changed files with 134 additions and 23 deletions

View File

@ -221,6 +221,19 @@ module.exports = class FileEntry {
return paths.join(storageDir, this.fileName); return paths.join(storageDir, this.fileName);
} }
static quickCheckExistsByPath(fullPath, cb) {
fileDb.get(
`SELECT COUNT() AS count
FROM file
WHERE file_name = ?
LIMIT 1;`,
[ paths.basename(fullPath) ],
(err, rows) => {
return err ? cb(err) : cb(null, rows.count > 0 ? true : false);
}
);
}
static persistUserRating(fileId, userId, rating, cb) { static persistUserRating(fileId, userId, rating, cb) {
return fileDb.run( return fileDb.run(
`REPLACE INTO file_user_rating (file_id, user_id, rating) `REPLACE INTO file_user_rating (file_id, user_id, rating)

View File

@ -24,7 +24,7 @@ exports.handleFileBaseCommand = handleFileBaseCommand;
Global options: Global options:
--yes: assume yes --yes: assume yes
--no-prompt: try to avoid user input --no-prompt: try to avoid user input
Prompt for import and description before scan Prompt for import and description before scan
* Only after finding duplicate-by-path * Only after finding duplicate-by-path
@ -59,7 +59,7 @@ function finalizeEntryAndPersist(isUpdate, fileEntry, descHandler, cb) {
const getDescFromFileName = require('../../core/file_base_area.js').getDescFromFileName; const getDescFromFileName = require('../../core/file_base_area.js').getDescFromFileName;
const descFromFile = getDescFromFileName(fileEntry.fileName); const descFromFile = getDescFromFileName(fileEntry.fileName);
if(false === argv.prompt) { if(false === argv.prompt) {
fileEntry.desc = descFromFile; fileEntry.desc = descFromFile;
return callback(null); return callback(null);
@ -116,7 +116,9 @@ function scanFileAreaForChanges(areaInfo, options, cb) {
fe.hashTags = new Set(options.tags); fe.hashTags = new Set(options.tags);
} }
} }
const FileEntry = require('../file_entry.js');
async.eachSeries(storageLocations, (storageLoc, nextLocation) => { async.eachSeries(storageLocations, (storageLoc, nextLocation) => {
async.waterfall( async.waterfall(
[ [
@ -157,6 +159,100 @@ function scanFileAreaForChanges(areaInfo, options, cb) {
process.stdout.write(`Scanning ${fullPath}... `); process.stdout.write(`Scanning ${fullPath}... `);
async.series(
[
function quickCheck(next) {
if(!options.quick) {
return next(null);
}
FileEntry.quickCheckExistsByPath(fullPath, (err, exists) => {
if(exists) {
console.info('Dupe');
return nextFile(null);
}
return next(null);
});
},
function fullScan() {
fileArea.scanFile(
fullPath,
{
areaTag : areaInfo.areaTag,
storageTag : storageLoc.storageTag
},
(err, fileEntry, dupeEntries) => {
if(err) {
console.info(`Error: ${err.message}`);
return nextFile(null); // try next anyway
}
//
// We'll update the entry if the following conditions are met:
// * We have a single duplicate, and:
// * --update was passed or the existing entry's desc,
// longDesc, or est_release_year meta are blank/empty
//
if(argv.update && 1 === dupeEntries.length) {
const FileEntry = require('../../core/file_entry.js');
const existingEntry = new FileEntry();
return existingEntry.load(dupeEntries[0].fileId, err => {
if(err) {
console.info('Dupe (cannot update)');
return nextFile(null);
}
//
// Update only if tags or desc changed
//
const optTags = Array.isArray(options.tags) ? new Set(options.tags) : existingEntry.hashTags;
const tagsEq = _.isEqual(optTags, existingEntry.hashTags);
if( tagsEq &&
fileEntry.desc === existingEntry.desc &&
fileEntry.descLong == existingEntry.descLong &&
fileEntry.meta.est_release_year == existingEntry.meta.est_release_year)
{
console.info('Dupe');
return nextFile(null);
}
console.info('Dupe (updating)');
// don't allow overwrite of values if new version is blank
existingEntry.desc = fileEntry.desc || existingEntry.desc;
existingEntry.descLong = fileEntry.descLong || existingEntry.descLong;
if(fileEntry.meta.est_release_year) {
existingEntry.meta.est_release_year = fileEntry.meta.est_release_year;
}
updateTags(existingEntry);
finalizeEntryAndPersist(true, existingEntry, descHandler, err => {
return nextFile(err);
});
});
} else if(dupeEntries.length > 0) {
console.info('Dupe');
return nextFile(null);
}
console.info('Done!');
updateTags(fileEntry);
finalizeEntryAndPersist(false, fileEntry, descHandler, err => {
return nextFile(err);
});
}
);
}
]
);
/*
fileArea.scanFile( fileArea.scanFile(
fullPath, fullPath,
{ {
@ -165,7 +261,7 @@ function scanFileAreaForChanges(areaInfo, options, cb) {
}, },
(err, fileEntry, dupeEntries) => { (err, fileEntry, dupeEntries) => {
if(err) { if(err) {
console.info(`Error: ${err.message}`); console.info(`Error: ${err.message}`);
return nextFile(null); // try next anyway return nextFile(null); // try next anyway
} }
@ -191,8 +287,8 @@ function scanFileAreaForChanges(areaInfo, options, cb) {
const optTags = Array.isArray(options.tags) ? new Set(options.tags) : existingEntry.hashTags; const optTags = Array.isArray(options.tags) ? new Set(options.tags) : existingEntry.hashTags;
const tagsEq = _.isEqual(optTags, existingEntry.hashTags); const tagsEq = _.isEqual(optTags, existingEntry.hashTags);
if( tagsEq && if( tagsEq &&
fileEntry.desc === existingEntry.desc && fileEntry.desc === existingEntry.desc &&
fileEntry.descLong == existingEntry.descLong && fileEntry.descLong == existingEntry.descLong &&
fileEntry.meta.est_release_year == existingEntry.meta.est_release_year) fileEntry.meta.est_release_year == existingEntry.meta.est_release_year)
{ {
@ -220,15 +316,16 @@ function scanFileAreaForChanges(areaInfo, options, cb) {
console.info('Dupe'); console.info('Dupe');
return nextFile(null); return nextFile(null);
} }
console.info('Done!'); console.info('Done!');
updateTags(fileEntry); updateTags(fileEntry);
finalizeEntryAndPersist(false, fileEntry, descHandler, err => { finalizeEntryAndPersist(false, fileEntry, descHandler, err => {
return nextFile(err); return nextFile(err);
}); });
} }
); );
*/
}); });
}, err => { }, err => {
return callback(err); return callback(err);
@ -239,12 +336,12 @@ function scanFileAreaForChanges(areaInfo, options, cb) {
// :TODO: Look @ db entries for area that were *not* processed above // :TODO: Look @ db entries for area that were *not* processed above
return callback(null); return callback(null);
} }
], ],
err => { err => {
return nextLocation(err); return nextLocation(err);
} }
); );
}, },
err => { err => {
return cb(err); return cb(err);
}); });
@ -259,7 +356,7 @@ function dumpAreaInfo(areaInfo, areaAndStorageInfo, cb) {
console.info(`storageTag: ${si.storageTag} => ${si.dir}`); console.info(`storageTag: ${si.storageTag} => ${si.dir}`);
}); });
console.info(''); console.info('');
return cb(null); return cb(null);
} }
@ -325,7 +422,7 @@ function dumpFileInfo(shaOrFileId, cb) {
console.info(`path: ${fullPath}`); console.info(`path: ${fullPath}`);
console.info(`hashTags: ${Array.from(fileEntry.hashTags).join(', ')}`); console.info(`hashTags: ${Array.from(fileEntry.hashTags).join(', ')}`);
console.info(`uploaded: ${moment(fileEntry.uploadTimestamp).format()}`); console.info(`uploaded: ${moment(fileEntry.uploadTimestamp).format()}`);
_.each(fileEntry.meta, (metaValue, metaName) => { _.each(fileEntry.meta, (metaValue, metaName) => {
console.info(`${metaName}: ${metaValue}`); console.info(`${metaName}: ${metaValue}`);
}); });
@ -354,7 +451,7 @@ function displayFileAreaInfo() {
[ [
function init(callback) { function init(callback) {
return initConfigAndDatabases(callback); return initConfigAndDatabases(callback);
}, },
function dumpInfo(callback) { function dumpInfo(callback) {
const Config = require('../../core/config.js').config; const Config = require('../../core/config.js').config;
let suppliedAreas = argv._.slice(2); let suppliedAreas = argv._.slice(2);
@ -396,8 +493,9 @@ function scanFileAreas() {
options.tags = tags.split(','); options.tags = tags.split(',');
} }
options.descFile = argv['desc-file']; // --desc-file or --desc-file PATH options.descFile = argv['desc-file']; // --desc-file or --desc-file PATH
options.quick = argv.quick;
options.areaAndStorageInfo = getAreaAndStorage(argv._.slice(2)); options.areaAndStorageInfo = getAreaAndStorage(argv._.slice(2));
async.series( async.series(
@ -405,10 +503,10 @@ function scanFileAreas() {
function init(callback) { function init(callback) {
return initConfigAndDatabases(callback); return initConfigAndDatabases(callback);
}, },
function initGlobalDescHandler(callback) { function initGlobalDescHandler(callback) {
// //
// If options.descFile is a String, it represents a FILE|PATH. We'll init // If options.descFile is a String, it represents a FILE|PATH. We'll init
// the description handler now. Else, we'll attempt to look for a description // the description handler now. Else, we'll attempt to look for a description
// file in each storage location. // file in each storage location.
// //
if(!_.isString(options.descFile)) { if(!_.isString(options.descFile)) {
@ -546,14 +644,14 @@ function moveFiles() {
}); });
}, },
function moveEntries(srcEntries, callback) { function moveEntries(srcEntries, callback) {
if(!dst.storageTag) { if(!dst.storageTag) {
dst.storageTag = dst.areaInfo.storageTags[0]; dst.storageTag = dst.areaInfo.storageTags[0];
} }
const destDir = FileEntry.getAreaStorageDirectoryByTag(dst.storageTag); const destDir = FileEntry.getAreaStorageDirectoryByTag(dst.storageTag);
async.eachSeries(srcEntries, (entry, nextEntry) => { async.eachSeries(srcEntries, (entry, nextEntry) => {
const srcPath = entry.filePath; const srcPath = entry.filePath;
const dstPath = paths.join(destDir, entry.fileName); const dstPath = paths.join(destDir, entry.fileName);
@ -566,7 +664,7 @@ function moveFiles() {
console.info('Done'); console.info('Done');
} }
return nextEntry(null); // always try next return nextEntry(null); // always try next
}); });
}, },
err => { err => {
return callback(err); return callback(err);
@ -652,7 +750,7 @@ function handleFileBaseCommand() {
function errUsage() { function errUsage() {
return printUsageAndSetExitCode( return printUsageAndSetExitCode(
getHelpFor('FileBase') + getHelpFor('FileOpsInfo'), getHelpFor('FileBase') + getHelpFor('FileOpsInfo'),
ExitCodes.ERROR ExitCodes.ERROR
); );
} }