🔧 Refactoring core-service to autowatch and import comics

This commit is contained in:
2022-01-26 00:40:30 -08:00
parent 44940b51aa
commit 019493a6f3
7 changed files with 108 additions and 96 deletions

View File

@@ -12,6 +12,7 @@ export const DbMixin = (collection, model) => {
pass: process.env.MONGO_INITDB_ROOT_PASSWORD, pass: process.env.MONGO_INITDB_ROOT_PASSWORD,
keepAlive: true, keepAlive: true,
useUnifiedTopology: true, useUnifiedTopology: true,
family: 4,
}), }),
model, model,
collection, collection,

View File

@@ -43,7 +43,7 @@
"@types/string-similarity": "^4.0.0", "@types/string-similarity": "^4.0.0",
"7zip-bin": "^5.1.1", "7zip-bin": "^5.1.1",
"7zip-min": "^1.4.0", "7zip-min": "^1.4.0",
"chokidar": "^3.5.2", "chokidar": "^3.5.3",
"dotenv": "^10.0.0", "dotenv": "^10.0.0",
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
"imghash": "^0.0.9", "imghash": "^0.0.9",

View File

@@ -90,7 +90,6 @@ export default class ApiService extends Service {
methods: {}, methods: {},
started(): any { started(): any {
// Add a connect listener // Add a connect listener
io.on("connection", (client) => { io.on("connection", (client) => {
console.log("Client connected via websocket!"); console.log("Client connected via websocket!");
@@ -112,19 +111,23 @@ export default class ApiService extends Service {
client.on("disconnect", () => { client.on("disconnect", () => {
console.log("Client disconnected"); console.log("Client disconnected");
}); });
});
// Filewatcher // Filewatcher
const fileWatcher = chokidar.watch(path.resolve("./comics"), { const fileWatcher = chokidar.watch(
path.resolve("./comics"),
{
ignored: /(^|[\/\\])\../, // ignore dotfiles ignored: /(^|[\/\\])\../, // ignore dotfiles
persistent: true, persistent: true,
usePolling: true,
ignoreInitial: true, ignoreInitial: true,
atomic: true, atomic: true,
depth: 1,
awaitWriteFinish: { awaitWriteFinish: {
stabilityThreshold: 2000, stabilityThreshold: 2000,
pollInterval: 100, pollInterval: 100,
}, },
}); }
);
const fileCopyDelaySeconds = 10; const fileCopyDelaySeconds = 10;
const checkFileCopyComplete = (path, previousPath) => { const checkFileCopyComplete = (path, previousPath) => {
fs.stat(path, async (err, stat) => { fs.stat(path, async (err, stat) => {
@@ -135,20 +138,18 @@ export default class ApiService extends Service {
stat.mtime.getTime() === stat.mtime.getTime() ===
previousPath.mtime.getTime() previousPath.mtime.getTime()
) { ) {
console.log("File detected, starting import..."); console.log(
"File detected, starting import..."
);
// this walking business needs to go, SACURATAYYY, SACURATAYYY!! This dude needs to go. // this walking business needs to go, SACURATAYYY, SACURATAYYY!! This dude needs to go.
const walkedFolders: IFolderData = const walkedFolder: IFolderData =
await broker.call("import.walkFolders", { await broker.call("import.walkFolders", {
basePathToWalk: path, basePathToWalk: path,
}); });
const extractionOptions: IExtractionOptions = { console.log(walkedFolder);
extractTarget: "cover",
targetExtractionFolder: "./userdata/covers",
extractionMode: "single",
};
await this.broker.call( await this.broker.call(
"import.processAndImportToDB", "import.processAndImportToDB",
{ walkedFolders, extractionOptions } { walkedFolder }
); );
} else { } else {
setTimeout( setTimeout(
@@ -177,7 +178,8 @@ export default class ApiService extends Service {
err.message err.message
); );
console.log( console.log(
"Error file not processed. PATH: " + path "Error file not processed. PATH: " +
path
); );
throw err; throw err;
} }
@@ -187,6 +189,10 @@ export default class ApiService extends Service {
path, path,
stat stat
); );
client.emit("action", {
type: "LS_COMIC_ADDED",
result: path,
});
}); });
}) })
.on("change", (path, stats) => .on("change", (path, stats) =>
@@ -200,6 +206,7 @@ export default class ApiService extends Service {
.on("addDir", (path) => .on("addDir", (path) =>
console.log(`Directory ${path} has been added`) console.log(`Directory ${path} has been added`)
); );
});
}, },
}); });
} }

View File

@@ -27,6 +27,7 @@ import klaw from "klaw";
import path from "path"; import path from "path";
import { COMICS_DIRECTORY, USERDATA_DIRECTORY } from "../constants/directories"; import { COMICS_DIRECTORY, USERDATA_DIRECTORY } from "../constants/directories";
console.log(process.env.MONGO_URI);
export default class ImportService extends Service { export default class ImportService extends Service {
public constructor(public broker: ServiceBroker) { public constructor(public broker: ServiceBroker) {
super(broker); super(broker);
@@ -128,8 +129,7 @@ export default class ImportService extends Service {
params: {}, params: {},
async handler( async handler(
ctx: Context<{ ctx: Context<{
extractionOptions: any; walkedFolder: {
walkedFolders: {
name: string; name: string;
path: string; path: string;
extension: string; extension: string;
@@ -141,10 +141,9 @@ export default class ImportService extends Service {
}> }>
) { ) {
try { try {
const { extractionOptions, walkedFolders } = const { walkedFolder } = ctx.params;
ctx.params;
let comicExists = await Comic.exists({ let comicExists = await Comic.exists({
"rawFileDetails.name": `${walkedFolders.name}`, "rawFileDetails.name": `${walkedFolder.name}`,
}); });
// rough flow of import process // rough flow of import process
// 1. Walk folder // 1. Walk folder
@@ -157,7 +156,7 @@ export default class ImportService extends Service {
| IExtractedComicBookCoverFile | IExtractedComicBookCoverFile
| IExtractComicBookCoverErrorResponse | IExtractComicBookCoverErrorResponse
| IExtractedComicBookCoverFile[] = await extractCoverFromFile2( | IExtractedComicBookCoverFile[] = await extractCoverFromFile2(
extractionOptions walkedFolder[0]
); );
// 2. Add to mongo // 2. Add to mongo
@@ -185,7 +184,7 @@ export default class ImportService extends Service {
}; };
} else { } else {
console.info( console.info(
`Comic: \"${walkedFolders.name}\" already exists in the database` `Comic: \"${walkedFolder.name}\" already exists in the database`
); );
} }
} catch (error) { } catch (error) {
@@ -459,7 +458,9 @@ export default class ImportService extends Service {
}); });
resp.on("end", () => { resp.on("end", () => {
console.log(`${apiDetailURL} returned data.`) console.log(
`${apiDetailURL} returned data.`
);
const volumeInformation = const volumeInformation =
JSON.parse(data); JSON.parse(data);
resolve(volumeInformation.results); resolve(volumeInformation.results);

View File

@@ -14,6 +14,7 @@ import { extractCoverFromFile2 } from "../utils/uncompression.utils";
import { io } from "./api.service"; import { io } from "./api.service";
const REDIS_URI = process.env.REDIS_URI || `redis://0.0.0.0:6379`; const REDIS_URI = process.env.REDIS_URI || `redis://0.0.0.0:6379`;
console.log(`REDIS -> ${REDIS_URI}`);
export default class LibraryQueueService extends Service { export default class LibraryQueueService extends Service {
public constructor(public broker: ServiceBroker) { public constructor(public broker: ServiceBroker) {
super(broker); super(broker);

View File

@@ -17,7 +17,7 @@ export const walkFolder = async (folder: string, formats: string[]): Promise<IFo
const result: IFolderData[] = []; const result: IFolderData[] = [];
let walkResult: IFolderData = { let walkResult: IFolderData = {
name: "", name: "",
path: "", filePath: "",
extension: "", extension: "",
containedIn: "", containedIn: "",
isFile: false, isFile: false,
@@ -34,7 +34,7 @@ export const walkFolder = async (folder: string, formats: string[]): Promise<IFo
if ([...formats].includes(path.extname(dirent.name))) { if ([...formats].includes(path.extname(dirent.name))) {
walkResult = { walkResult = {
name: path.basename(dirent.name, path.extname(dirent.name)), name: path.basename(dirent.name, path.extname(dirent.name)),
path: path.dirname(pathname), filePath: path.resolve(pathname),
extension: path.extname(dirent.name), extension: path.extname(dirent.name),
fileSize: fs.statSync(path.resolve(pathname)).size, fileSize: fs.statSync(path.resolve(pathname)).size,
containedIn: path.dirname(pathname), containedIn: path.dirname(pathname),

View File

@@ -55,7 +55,9 @@ export const extractCoverFromFile2 = async (
fileObject: any fileObject: any
): Promise<any> => { ): Promise<any> => {
try { try {
const { filePath, size} = fileObject; console.log("ASDASD!@#!#!@#!@#");
console.log(fileObject);
const { filePath, fileSize} = fileObject;
const calibre = new Calibre(); const calibre = new Calibre();
console.info(`Initiating extraction process for path ${filePath}`); console.info(`Initiating extraction process for path ${filePath}`);
@@ -111,7 +113,7 @@ export const extractCoverFromFile2 = async (
return { return {
name: fileNameWithoutExtension, name: fileNameWithoutExtension,
path: filePath, path: filePath,
fileSize: size, fileSize,
extension: path.extname(filePath), extension: path.extname(filePath),
cover: { cover: {
filePath: path.relative(process.cwd(),renditionPath), filePath: path.relative(process.cwd(),renditionPath),