forked from lix-project/lix-website
97 lines
2.9 KiB
JavaScript
97 lines
2.9 KiB
JavaScript
|
const debug = require("debug")("streamroller:fileNameParser");
|
||
|
const ZIP_EXT = ".gz";
|
||
|
const format = require("date-format");
|
||
|
const DEFAULT_FILENAME_SEP = ".";
|
||
|
|
||
|
module.exports = ({ file, keepFileExt, pattern, fileNameSep }) => {
|
||
|
let FILENAME_SEP = fileNameSep || DEFAULT_FILENAME_SEP;
|
||
|
// All these functions take two arguments: f, the filename, and p, the result placeholder
|
||
|
// They return the filename with any matching parts removed.
|
||
|
// The "zip" function, for instance, removes the ".gz" part of the filename (if present)
|
||
|
const zip = (f, p) => {
|
||
|
if (f.endsWith(ZIP_EXT)) {
|
||
|
debug("it is gzipped");
|
||
|
p.isCompressed = true;
|
||
|
return f.slice(0, -1 * ZIP_EXT.length);
|
||
|
}
|
||
|
return f;
|
||
|
};
|
||
|
|
||
|
const __NOT_MATCHING__ = "__NOT_MATCHING__";
|
||
|
|
||
|
const extAtEnd = f => {
|
||
|
if (f.startsWith(file.name) && f.endsWith(file.ext)) {
|
||
|
debug("it starts and ends with the right things");
|
||
|
return f.slice(file.name.length + 1, -1 * file.ext.length);
|
||
|
}
|
||
|
return __NOT_MATCHING__;
|
||
|
};
|
||
|
|
||
|
const extInMiddle = f => {
|
||
|
if (f.startsWith(file.base)) {
|
||
|
debug("it starts with the right things");
|
||
|
return f.slice(file.base.length + 1);
|
||
|
}
|
||
|
return __NOT_MATCHING__;
|
||
|
};
|
||
|
|
||
|
const dateAndIndex = (f, p) => {
|
||
|
const items = f.split(FILENAME_SEP);
|
||
|
let indexStr = items[items.length - 1];
|
||
|
debug("items: ", items, ", indexStr: ", indexStr);
|
||
|
let dateStr = f;
|
||
|
if (indexStr !== undefined && indexStr.match(/^\d+$/)) {
|
||
|
dateStr = f.slice(0, -1 * (indexStr.length + 1));
|
||
|
debug(`dateStr is ${dateStr}`);
|
||
|
if (pattern && !dateStr) {
|
||
|
dateStr = indexStr;
|
||
|
indexStr = "0";
|
||
|
}
|
||
|
} else {
|
||
|
indexStr = "0";
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
// Two arguments for new Date() are intentional. This will set other date
|
||
|
// components to minimal values in the current timezone instead of UTC,
|
||
|
// as new Date(0) will do.
|
||
|
const date = format.parse(pattern, dateStr, new Date(0, 0));
|
||
|
if (format.asString(pattern, date) !== dateStr) return f;
|
||
|
p.index = parseInt(indexStr, 10);
|
||
|
p.date = dateStr;
|
||
|
p.timestamp = date.getTime();
|
||
|
return "";
|
||
|
} catch (e) {
|
||
|
//not a valid date, don't panic.
|
||
|
debug(`Problem parsing ${dateStr} as ${pattern}, error was: `, e);
|
||
|
return f;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
const index = (f, p) => {
|
||
|
if (f.match(/^\d+$/)) {
|
||
|
debug("it has an index");
|
||
|
p.index = parseInt(f, 10);
|
||
|
return "";
|
||
|
}
|
||
|
return f;
|
||
|
};
|
||
|
|
||
|
let parts = [
|
||
|
zip,
|
||
|
keepFileExt ? extAtEnd : extInMiddle,
|
||
|
pattern ? dateAndIndex : index
|
||
|
];
|
||
|
|
||
|
return filename => {
|
||
|
let result = { filename, index: 0, isCompressed: false };
|
||
|
// pass the filename through each of the file part parsers
|
||
|
let whatsLeftOver = parts.reduce(
|
||
|
(remains, part) => part(remains, result),
|
||
|
filename
|
||
|
);
|
||
|
// if there's anything left after parsing, then it wasn't a valid filename
|
||
|
return whatsLeftOver ? null : result;
|
||
|
};
|
||
|
};
|