0.10.2-9 Layout

This commit is contained in:
2026-03-16 10:02:41 +00:00
parent 45b2272f1a
commit 38a82706ce
14 changed files with 159 additions and 43 deletions
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "ripster-backend",
"version": "0.10.2-8",
"version": "0.10.2-9",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ripster-backend",
"version": "0.10.2-8",
"version": "0.10.2-9",
"dependencies": {
"archiver": "^7.0.1",
"cors": "^2.8.5",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "ripster-backend",
"version": "0.10.2-8",
"version": "0.10.2-9",
"private": true,
"type": "commonjs",
"scripts": {
+40
View File
@@ -131,6 +131,45 @@ function normalizeAudnexChapter(entry, index) {
};
}
function normalizeNameList(items) {
if (!Array.isArray(items) || items.length === 0) {
return null;
}
const names = items
.map((item) => String(item?.name || '').trim())
.filter(Boolean);
return names.length > 0 ? names.join(', ') : null;
}
async function fetchBookByAsin(asin, region = 'de') {
const normalizedAsin = normalizeAsin(asin);
if (!normalizedAsin) {
return null;
}
const url = new URL(`${AUDNEX_BASE_URL}/books/${normalizedAsin}`);
url.searchParams.set('region', String(region || 'de').trim() || 'de');
logger.info('book:fetch:start', { asin: normalizedAsin, url: url.toString() });
const payload = await audnexFetch(url.toString());
if (!payload || typeof payload !== 'object') {
return null;
}
const narrator = normalizeNameList(payload.narrators);
const author = normalizeNameList(payload.authors);
const title = String(payload.title || '').trim() || null;
const series = String(payload.seriesName || payload.series || '').trim() || null;
const part = String(payload.seriesPart || payload.part || '').trim() || null;
const description = String(payload.summary || payload.description || '').trim() || null;
const year = payload.releaseDate
? String(payload.releaseDate).slice(0, 4)
: null;
logger.info('book:fetch:done', { asin: normalizedAsin, narrator, author, title });
return { narrator, author, title, series, part, description, year };
}
async function fetchChaptersByAsin(asin, region = 'de') {
const normalizedAsin = normalizeAsin(asin);
if (!normalizedAsin) {
@@ -152,5 +191,6 @@ async function fetchChaptersByAsin(asin, region = 'de') {
module.exports = {
extractAsinFromAaxFile,
fetchBookByAsin,
fetchChaptersByAsin
};
+30 -6
View File
@@ -11081,21 +11081,37 @@ class PipelineService extends EventEmitter {
let detectedAsin = null;
let audnexChapters = [];
let audnexBook = null;
try {
detectedAsin = await audnexService.extractAsinFromAaxFile(storagePaths.rawFilePath);
if (detectedAsin) {
await historyService.appendLog(job.id, 'SYSTEM', `ASIN erkannt: ${detectedAsin}`);
audnexChapters = await audnexService.fetchChaptersByAsin(detectedAsin, 'de');
if (audnexChapters.length > 0) {
await historyService.appendLog(job.id, 'SYSTEM', `Audnex-Kapitel geladen: ${audnexChapters.length}`);
const [chapters, book] = await Promise.allSettled([
audnexService.fetchChaptersByAsin(detectedAsin, 'de'),
audnexService.fetchBookByAsin(detectedAsin, 'de')
]);
if (chapters.status === 'fulfilled') {
audnexChapters = chapters.value;
if (audnexChapters.length > 0) {
await historyService.appendLog(job.id, 'SYSTEM', `Audnex-Kapitel geladen: ${audnexChapters.length}`);
} else {
await historyService.appendLog(job.id, 'SYSTEM', `Keine Audnex-Kapitel fuer ASIN ${detectedAsin} gefunden.`);
}
} else {
await historyService.appendLog(job.id, 'SYSTEM', `Keine Audnex-Kapitel fuer ASIN ${detectedAsin} gefunden.`);
logger.warn('audiobook:upload:audnex-chapters-failed', { jobId: job.id, asin: detectedAsin, error: errorToMeta(chapters.reason) });
await historyService.appendLog(job.id, 'SYSTEM', `Audnex-Kapitel konnten nicht geladen werden: ${chapters.reason?.message || 'unknown'}`).catch(() => {});
}
if (book.status === 'fulfilled' && book.value) {
audnexBook = book.value;
await historyService.appendLog(job.id, 'SYSTEM', `Audnex-Buchmetadaten geladen: ${audnexBook.narrator ? `Sprecher: ${audnexBook.narrator}` : 'kein Sprecher'}`);
} else if (book.status === 'rejected') {
logger.warn('audiobook:upload:audnex-book-failed', { jobId: job.id, asin: detectedAsin, error: errorToMeta(book.reason) });
}
} else {
await historyService.appendLog(job.id, 'SYSTEM', 'Keine ASIN in der AAX-Datei gefunden, verwende eingebettete Kapitel.');
}
} catch (audnexError) {
logger.warn('audiobook:upload:audnex-chapters-failed', {
logger.warn('audiobook:upload:audnex-failed', {
jobId: job.id,
stagedRawFilePath: storagePaths.rawFilePath,
asin: detectedAsin,
@@ -11104,7 +11120,7 @@ class PipelineService extends EventEmitter {
await historyService.appendLog(
job.id,
'SYSTEM',
`Audnex-Kapitel konnten nicht geladen werden: ${audnexError?.message || 'unknown'}`
`Audnex-Daten konnten nicht geladen werden: ${audnexError?.message || 'unknown'}`
).catch(() => {});
}
@@ -11140,6 +11156,14 @@ class PipelineService extends EventEmitter {
const resolvedMetadata = {
...metadata,
// Audnex book metadata takes precedence over embedded tags where available
...(audnexBook?.narrator ? { narrator: audnexBook.narrator } : {}),
...(audnexBook?.author ? { author: audnexBook.author, artist: audnexBook.author } : {}),
...(audnexBook?.title ? { title: audnexBook.title, album: audnexBook.title } : {}),
...(audnexBook?.description ? { description: audnexBook.description } : {}),
...(audnexBook?.series ? { series: audnexBook.series } : {}),
...(audnexBook?.part ? { part: audnexBook.part } : {}),
...(audnexBook?.year ? { year: audnexBook.year } : {}),
asin: detectedAsin || null,
chapterSource: audnexChapters.length > 0 ? 'audnex' : 'probe',
chapters: audnexChapters.length > 0