Add filesystem scan trigger and version badge features

Implements optional filesystem scan triggering for Plex and Audiobookshelf after file organization, with new settings in the admin UI, setup wizard, and API. Updates documentation to reflect scan trigger options and improved file organization/cleanup logic. Refactors dropdown menus to use smart positioning and portals for better UX. Adds a version API route and a VersionBadge component to display build info in the header. Updates Docker build to inject version metadata.
This commit is contained in:
kikootwo
2026-01-09 17:15:00 -05:00
parent 288421012d
commit 384601014a
25 changed files with 1346 additions and 243 deletions
@@ -7,6 +7,8 @@ import { OrganizeFilesPayload, getJobQueueService } from '../services/job-queue.
import { prisma } from '../db';
import { getFileOrganizer } from '../utils/file-organizer';
import { createJobLogger } from '../utils/job-logger';
import { getLibraryService } from '../services/library';
import { getConfigService } from '../services/config.service';
/**
* Process organize files job
@@ -99,6 +101,54 @@ export async function processOrganizeFiles(payload: OrganizeFilesPayload): Promi
errors: result.errors,
});
// Trigger filesystem scan if enabled (Plex or Audiobookshelf)
const configService = getConfigService();
const backendMode = await configService.getBackendMode();
const configKey = backendMode === 'audiobookshelf'
? 'audiobookshelf.trigger_scan_after_import'
: 'plex.trigger_scan_after_import';
const scanEnabled = await configService.get(configKey);
if (scanEnabled === 'true') {
try {
// Get library service (returns PlexLibraryService or AudiobookshelfLibraryService)
const libraryService = await getLibraryService();
// Get configured library ID (backend-specific config)
const libraryId = backendMode === 'audiobookshelf'
? await configService.get('audiobookshelf.library_id')
: await configService.get('plex_audiobook_library_id');
if (!libraryId) {
throw new Error('Library ID not configured');
}
// Trigger scan (implementation is backend-specific)
await libraryService.triggerLibraryScan(libraryId);
await logger?.info(
`Triggered ${backendMode} filesystem scan for library ${libraryId}`
);
} catch (error) {
// Log error but don't fail the job
await logger?.error(
`Failed to trigger filesystem scan: ${error instanceof Error ? error.message : 'Unknown error'}`,
{
error: error instanceof Error ? error.stack : undefined,
backend: backendMode
}
);
// Continue - scheduled scans will eventually detect the book
}
} else {
await logger?.info(
`${backendMode} filesystem scan trigger disabled (relying on filesystem watcher)`
);
}
return {
success: true,
message: 'Files organized successfully',