2022-04-14 14:23:41 +02:00
|
|
|
const path = require('path');
|
|
|
|
const chokidar = require('chokidar');
|
2022-06-02 16:36:27 +02:00
|
|
|
const { open, writeFile } = require('fs/promises');
|
2022-04-14 14:23:41 +02:00
|
|
|
|
2022-06-03 17:04:44 +02:00
|
|
|
const Environment = require('../models/Environment.js');
|
|
|
|
|
2022-04-14 14:23:41 +02:00
|
|
|
class Watcher {
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
this.#initialize();
|
|
|
|
}
|
|
|
|
|
2022-06-02 16:36:27 +02:00
|
|
|
async #initialize() {
|
2022-04-14 14:23:41 +02:00
|
|
|
if (config?.library === undefined) {
|
|
|
|
throw new Error('library not defined');
|
|
|
|
}
|
|
|
|
if (config?.library?.sources === undefined || config?.library?.sources.length === 0) {
|
|
|
|
throw new Error('no library sources defined');
|
|
|
|
}
|
2022-06-02 16:36:27 +02:00
|
|
|
let initialScan = config?.library?.initialscan?.enabled;
|
|
|
|
if (initialScan === undefined) {
|
|
|
|
initialScan = true;
|
|
|
|
}
|
2022-04-14 14:23:41 +02:00
|
|
|
for (let index = 0; index < config.library.sources.length; index++) {
|
|
|
|
const directory = path.resolve(config.library.sources[index]);
|
2022-06-02 16:36:27 +02:00
|
|
|
let ignoreInitial = !initialScan;
|
|
|
|
if (ignoreInitial === false) {
|
2022-06-03 17:04:44 +02:00
|
|
|
let env = new Environment(constants.ENVIRONMENT_LASTSCAN);
|
|
|
|
await env.find('key');
|
|
|
|
if (env === undefined) {
|
|
|
|
env = new Environment(constants.ENVIRONMENT_LASTSCAN, new Date().getTime().toString());
|
|
|
|
env.save();
|
|
|
|
}
|
2022-06-02 16:36:27 +02:00
|
|
|
ignoreInitial = (new Date().getTime() - await this.#checkHiddenFile(directory)) < (config?.library?.initialscan?.maxage || 86400000);
|
|
|
|
}
|
2022-04-14 14:23:41 +02:00
|
|
|
logger.debug('watching directory \'' + directory + '\'...');
|
2022-06-02 16:36:27 +02:00
|
|
|
this.#handleEvents(chokidar.watch(directory, {
|
|
|
|
ignoreInitial: ignoreInitial
|
|
|
|
}));
|
2022-04-14 14:23:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#handleEvents(watcher) {
|
|
|
|
if (watcher === undefined) {
|
|
|
|
return;
|
|
|
|
}
|
2022-04-21 13:43:33 +02:00
|
|
|
watcher.on(constants.FS_EVENT_ADD, (file, stats) => {
|
|
|
|
queue.add(constants.FS_EVENT_ADD, file, stats);
|
2022-04-14 14:23:41 +02:00
|
|
|
});
|
2022-04-21 13:43:33 +02:00
|
|
|
watcher.on(constants.FS_EVENT_UNLINK, (file, stats) => {
|
|
|
|
queue.add(constants.FS_EVENT_UNLINK, file, stats);
|
2022-04-14 14:23:41 +02:00
|
|
|
});
|
2022-04-21 13:43:33 +02:00
|
|
|
watcher.on(constants.FS_EVENT_CHANGE, (file, stats) => {
|
|
|
|
queue.add(constants.FS_EVENT_CHANGE, file, stats);
|
2022-04-14 14:23:41 +02:00
|
|
|
});
|
|
|
|
}
|
2022-06-02 16:36:27 +02:00
|
|
|
|
|
|
|
async #checkHiddenFile(directory) {
|
|
|
|
if (directory === undefined) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const hiddenFile = path.join(directory, '.kannon');
|
|
|
|
let filehandle;
|
|
|
|
try {
|
|
|
|
filehandle = await open(hiddenFile);
|
2022-06-03 17:04:44 +02:00
|
|
|
return (await filehandle.readFile()).toString();
|
2022-06-02 16:36:27 +02:00
|
|
|
} catch (error) {
|
|
|
|
if (error.code === 'ENOENT') {
|
|
|
|
return await this.#createHiddenFile(hiddenFile);
|
|
|
|
}
|
|
|
|
logger.error('encountered an error checking the hidden file \'' + hiddenFile + '\' > ' + error);
|
|
|
|
} finally {
|
|
|
|
filehandle?.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async #createHiddenFile(file) {
|
|
|
|
if (file === undefined) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const timestamp = new Date().getTime().toString();
|
|
|
|
try {
|
|
|
|
await writeFile(file, timestamp);
|
|
|
|
return timestamp;
|
|
|
|
} catch (error) {
|
|
|
|
logger.error('encountered an error writing the hidden file \'' + file + '\' > ' + error);
|
|
|
|
}
|
|
|
|
}
|
2022-04-14 14:23:41 +02:00
|
|
|
}
|
|
|
|
|
2022-04-21 13:43:33 +02:00
|
|
|
module.exports = Watcher;
|