mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 00:11:37 -06:00
feat(scanner): regex metadata extraction (#1669)
feat(metadata): extract metadata from file paths with regex rules (#1669) Let libraries define ordered regex rules that read title, authors, series, series number and dates from each book's path relative to its library folder. Run rules in a bounded worker pool, honour source precedence and field locks, and apply them on scans, uploads and watcher moves. Also retry unprobed M4B tag writes with the mp4 muxer. Closes #1351 Co-authored-by: neon <18559658+neonsolstice@users.noreply.github.com>
This commit is contained in:
@@ -87,6 +87,7 @@ export * from "./cron";
|
||||
export * from "./tts";
|
||||
export * from "./watch-download";
|
||||
export * from "./podcast";
|
||||
export * from "./regex-metadata";
|
||||
export * from "./delivery";
|
||||
export * from "./djvu";
|
||||
export * from "./email";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { RegexMetadataConfig } from "./regex-metadata";
|
||||
import type { LibraryLastScan } from "./scanner";
|
||||
|
||||
export type OrganizationMode = "book_per_file" | "book_per_folder";
|
||||
@@ -59,6 +60,7 @@ export interface Library {
|
||||
watchLocalFolders?: boolean;
|
||||
autoScanCronExpression?: string | null;
|
||||
metadataPrecedence: string[];
|
||||
regexMetadata?: RegexMetadataConfig | null;
|
||||
formatPriority: string[];
|
||||
allowedFormats: string[];
|
||||
organizationMode: OrganizationMode;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
export const REGEX_METADATA_LIMITS = {
|
||||
rules: 20,
|
||||
patternLength: 2048,
|
||||
pathLength: 4096,
|
||||
} as const;
|
||||
|
||||
export const REGEX_METADATA_GROUPS = ["title", "author", "authors", "series", "seriesIndex", "publishedYear", "publishedDate"] as const;
|
||||
|
||||
export interface RegexMetadataRule {
|
||||
pattern: string;
|
||||
flags: string;
|
||||
}
|
||||
|
||||
export interface RegexMetadataConfig {
|
||||
rules: RegexMetadataRule[];
|
||||
}
|
||||
|
||||
export interface RegexMetadataFields {
|
||||
title?: string;
|
||||
authors?: string[];
|
||||
seriesName?: string;
|
||||
seriesIndex?: string;
|
||||
publishedYear?: number;
|
||||
publishedDate?: string;
|
||||
}
|
||||
|
||||
export type RegexMetadataDiagnosticCode =
|
||||
"invalid_pattern" | "missing_group" | "conflicting_authors" | "invalid_value" | "timeout" | "busy" | "worker_failed";
|
||||
|
||||
export interface RegexMetadataDiagnostic {
|
||||
code: RegexMetadataDiagnosticCode;
|
||||
ruleIndex?: number;
|
||||
field?: string;
|
||||
}
|
||||
|
||||
export interface RegexMetadataPreview {
|
||||
inputPath: string;
|
||||
matched: boolean;
|
||||
ruleIndex: number | null;
|
||||
groups: Record<string, string>;
|
||||
metadata: RegexMetadataFields;
|
||||
diagnostics: RegexMetadataDiagnostic[];
|
||||
}
|
||||
|
||||
export interface RegexMetadataValidation {
|
||||
valid: boolean;
|
||||
diagnostics: RegexMetadataDiagnostic[];
|
||||
}
|
||||
Reference in New Issue
Block a user