Add fb 'info' support to oputil

This commit is contained in:
Bryan Ashby 2017-02-18 19:00:09 -07:00
parent 058ff3f367
commit 6717cd5179
5 changed files with 180 additions and 7 deletions

View File

@ -23,6 +23,7 @@ const iconv = require('iconv-lite');
exports.isInternalArea = isInternalArea;
exports.getAvailableFileAreas = getAvailableFileAreas;
exports.getSortedAvailableFileAreas = getSortedAvailableFileAreas;
exports.getAreaStorageDirectoryByTag = getAreaStorageDirectoryByTag;
exports.getAreaDefaultStorageDirectory = getAreaDefaultStorageDirectory;
exports.getAreaStorageLocations = getAreaStorageLocations;
exports.getDefaultFileAreaTag = getDefaultFileAreaTag;

View File

@ -289,8 +289,37 @@ module.exports = class FileEntry {
}
}
// :TODO: Use static get accessor:
static getWellKnownMetaValues() { return Object.keys(FILE_WELL_KNOWN_META); }
static findFileBySha(sha, cb) {
// full or partial SHA-256
fileDb.all(
`SELECT file_id
FROM file
WHERE file_sha256 LIKE "${sha}%"
LIMIT 2;`, // limit 2 such that we can find if there are dupes
(err, fileIdRows) => {
if(err) {
return cb(err);
}
if(!fileIdRows || 0 === fileIdRows.length) {
return cb(Errors.DoesNotExist('No matches'));
}
if(fileIdRows.length > 1) {
return cb(Errors.Invalid('SHA is ambiguous'));
}
const fileEntry = new FileEntry();
return fileEntry.load(fileIdRows[0].file_id, err => {
return cb(err, fileEntry);
});
}
);
}
static findFiles(filter, cb) {
filter = filter || {};

View File

@ -64,7 +64,7 @@ function initConfigAndDatabases(cb) {
function getAreaAndStorage(tags) {
return tags.map(tag => {
const parts = tag.split('@');
const parts = tag.toString().split('@');
const entry = {
areaTag : parts[0],
};

View File

@ -8,11 +8,13 @@ const argv = require('./oputil_common.js').argv;
const initConfigAndDatabases = require('./oputil_common.js').initConfigAndDatabases;
const getHelpFor = require('./oputil_help.js').getHelpFor;
const getAreaAndStorage = require('./oputil_common.js').getAreaAndStorage;
const Errors = require('../../core/enig_error.js').Errors;
const async = require('async');
const fs = require('fs');
const paths = require('path');
const _ = require('lodash');
const moment = require('moment');
exports.handleFileBaseCommand = handleFileBaseCommand;
@ -119,6 +121,140 @@ function scanFileAreaForChanges(areaInfo, options, cb) {
});
}
function dumpAreaInfo(areaInfo, areaAndStorageInfo, cb) {
console.info(`areaTag: ${areaInfo.areaTag}`);
console.info(`name: ${areaInfo.name}`);
console.info(`desc: ${areaInfo.desc}`);
areaInfo.storage.forEach(si => {
console.info(`storageTag: ${si.storageTag} => ${si.dir}`);
});
console.info('');
return cb(null);
}
function dumpFileInfo(shaOrFileId, cb) {
const FileEntry = require('../../core/file_entry.js');
async.waterfall(
[
function getBySha(callback) {
FileEntry.findFileBySha(shaOrFileId, (err, fileEntry) => {
return callback(null, fileEntry);
});
},
function getByFileId(fileEntry, callback) {
if(fileEntry) {
return callback(null, fileEntry); // already got it by sha
}
const fileId = parseInt(shaOrFileId);
if(isNaN(fileId)) {
return callback(Errors.DoesNotExist('Not found'));
}
fileEntry = new FileEntry();
fileEntry.load(shaOrFileId, err => {
return callback(err, fileEntry);
});
},
function dumpInfo(fileEntry, callback) {
const fullPath = paths.join(fileArea.getAreaStorageDirectoryByTag(fileEntry.storageTag), fileEntry.fileName);
console.info(`file_id: ${fileEntry.fileId}`);
console.info(`sha_256: ${fileEntry.fileSha256}`);
console.info(`area_tag: ${fileEntry.areaTag}`);
console.info(`path: ${fullPath}`);
console.info(`hashTags: ${Array.from(fileEntry.hashTags).join(', ')}`);
console.info(`uploaded: ${moment(fileEntry.uploadTimestamp).format()}`);
_.each(fileEntry.meta, (metaValue, metaName) => {
console.info(`${metaName}: ${metaValue}`);
});
if(argv['show-desc']) {
console.info(`${fileEntry.desc}`);
}
console.info('');
return callback(null);
}
],
err => {
return cb(err);
}
);
/*
FileEntry.findFileBySha(sha, (err, fileEntry) => {
if(err) {
return cb(err);
}
const fullPath = paths.join(fileArea.getAreaStorageDirectoryByTag(fileEntry.storageTag), fileEntry.fileName);
console.info(`file_id: ${fileEntry.fileId}`);
console.info(`sha_256: ${fileEntry.fileSha256}`);
console.info(`area_tag: ${fileEntry.areaTag}`);
console.info(`path: ${fullPath}`);
console.info(`hashTags: ${Array.from(fileEntry.hashTags).join(', ')}`);
console.info(`uploaded: ${moment(fileEntry.uploadTimestamp).format()}`);
_.each(fileEntry.meta, (metaValue, metaName) => {
console.info(`${metaName}: ${metaValue}`);
});
if(argv['show-desc']) {
console.info(`${fileEntry.desc}`);
}
});
*/
}
function displayFileAreaInfo() {
// AREA_TAG[@STORAGE_TAG]
// SHA256|PARTIAL
// if sha: dump file info
// if area/stoarge dump area(s) +
async.series(
[
function init(callback) {
return initConfigAndDatabases(callback);
},
function dumpInfo(callback) {
const Config = require('../../core/config.js').config;
let suppliedAreas = argv._.slice(2);
if(!suppliedAreas || 0 === suppliedAreas.length) {
suppliedAreas = _.map(Config.fileBase.areas, (areaInfo, areaTag) => areaTag);
}
const areaAndStorageInfo = getAreaAndStorage(suppliedAreas);
fileArea = require('../../core/file_base_area.js');
async.eachSeries(areaAndStorageInfo, (areaAndStorage, nextArea) => {
const areaInfo = fileArea.getFileAreaByTag(areaAndStorage.areaTag);
if(areaInfo) {
return dumpAreaInfo(areaInfo, areaAndStorageInfo, nextArea);
} else {
return dumpFileInfo(areaAndStorage.areaTag, nextArea);
}
},
err => {
return callback(err);
});
}
],
err => {
if(err) {
process.exitCode = ExitCodes.ERROR;
console.error(err.message);
}
}
);
}
function scanFileAreas() {
const options = {};
@ -170,6 +306,7 @@ function handleFileBaseCommand() {
const action = argv._[1];
switch(action) {
case 'info' : return displayFileAreaInfo();
case 'scan' : return scanFileAreas();
}
}

View File

@ -38,16 +38,22 @@ valid args:
--new : generate a new/initial configuration
`,
FileBase :
`usage: oputil.js fb <action> [<args>] [<action_specific>]
`usage: oputil.js fb <action> [<args>] <AREA_TAG|SHA|FILE_ID[@STORAGE_TAG] ...> [<args>]
where <action> is one of:
scan <args> AREA_TAG : (re)scan area specified by AREA_TAG for new files
multiple area tags can be specified in form of AREA_TAG1 AREA_TAG2 ...
scan AREA_TAG|SHA|FILE_ID : scan specified areas
AREA_TAG may be suffixed with @STORAGE_TAG; for example: retro@bbs
info AREA_TAG|FILE_ID|SHA : display information about areas and/or files
SHA may be a full or partial SHA-256
valid scan <args>:
--tags TAG1,TAG2,... : specify tag(s) to assign to discovered entries
--tags TAG1,TAG2,... : specify tag(s) to assign to discovered entries
valid info <args>:
--show-desc : display short description, if any
ARE_TAG can optionally contain @STORAGE_TAG; for example: retro_pc@bbs
`
};