From d990e5b9094e13408651204589bd8886e1a90a5b Mon Sep 17 00:00:00 2001 From: mikiher Date: Sun, 12 Nov 2023 13:30:23 +0000 Subject: [PATCH 1/6] Add NFO metadata source --- .../components/modals/libraries/EditModal.vue | 2 +- .../libraries/LibraryScannerSettings.vue | 5 + server/objects/settings/LibrarySettings.js | 4 +- server/scanner/BookScanner.js | 11 ++- server/scanner/LibraryItemScanData.js | 5 + server/scanner/NfoFileScanner.js | 48 ++++++++++ server/utils/parsers/parseNfoMetadata.js | 94 +++++++++++++++++++ 7 files changed, 165 insertions(+), 4 deletions(-) create mode 100644 server/scanner/NfoFileScanner.js create mode 100644 server/utils/parsers/parseNfoMetadata.js diff --git a/client/components/modals/libraries/EditModal.vue b/client/components/modals/libraries/EditModal.vue index 5bcdabedeb..2a68dd639d 100644 --- a/client/components/modals/libraries/EditModal.vue +++ b/client/components/modals/libraries/EditModal.vue @@ -127,7 +127,7 @@ export default { skipMatchingMediaWithIsbn: false, autoScanCronExpression: null, hideSingleBookSeries: false, - metadataPrecedence: ['folderStructure', 'audioMetatags', 'txtFiles', 'opfFile', 'absMetadata'] + metadataPrecedence: ['folderStructure', 'audioMetatags', 'nfoFile', 'txtFiles', 'opfFile', 'absMetadata'] } } }, diff --git a/client/components/modals/libraries/LibraryScannerSettings.vue b/client/components/modals/libraries/LibraryScannerSettings.vue index 215f79b55f..253d4e6b02 100644 --- a/client/components/modals/libraries/LibraryScannerSettings.vue +++ b/client/components/modals/libraries/LibraryScannerSettings.vue @@ -64,6 +64,11 @@ export default { name: 'Audio file meta tags', include: true }, + nfoFile: { + id: 'nfoFile', + name: 'NFO file', + include: true + }, txtFiles: { id: 'txtFiles', name: 'desc.txt & reader.txt files', diff --git a/server/objects/settings/LibrarySettings.js b/server/objects/settings/LibrarySettings.js index b734b6bf40..10ee19e02a 100644 --- a/server/objects/settings/LibrarySettings.js +++ b/server/objects/settings/LibrarySettings.js @@ -9,7 +9,7 @@ class LibrarySettings { this.autoScanCronExpression = null this.audiobooksOnly = false this.hideSingleBookSeries = false // Do not show series that only have 1 book - this.metadataPrecedence = ['folderStructure', 'audioMetatags', 'txtFiles', 'opfFile', 'absMetadata'] + this.metadataPrecedence = ['folderStructure', 'audioMetatags', 'nfoFile', 'txtFiles', 'opfFile', 'absMetadata'] if (settings) { this.construct(settings) @@ -28,7 +28,7 @@ class LibrarySettings { this.metadataPrecedence = [...settings.metadataPrecedence] } else { // Added in v2.4.5 - this.metadataPrecedence = ['folderStructure', 'audioMetatags', 'txtFiles', 'opfFile', 'absMetadata'] + this.metadataPrecedence = ['folderStructure', 'audioMetatags', 'nfoFile', 'txtFiles', 'opfFile', 'absMetadata'] } } diff --git a/server/scanner/BookScanner.js b/server/scanner/BookScanner.js index 282155f268..48e8529add 100644 --- a/server/scanner/BookScanner.js +++ b/server/scanner/BookScanner.js @@ -18,6 +18,7 @@ const BookFinder = require('../finders/BookFinder') const LibraryScan = require("./LibraryScan") const OpfFileScanner = require('./OpfFileScanner') +const NfoFileScanner = require('./NfoFileScanner') const AbsMetadataFileScanner = require('./AbsMetadataFileScanner') /** @@ -593,7 +594,7 @@ class BookScanner { } const bookMetadataSourceHandler = new BookScanner.BookMetadataSourceHandler(bookMetadata, audioFiles, libraryItemData, libraryScan, existingLibraryItemId) - const metadataPrecedence = librarySettings.metadataPrecedence || ['folderStructure', 'audioMetatags', 'txtFiles', 'opfFile', 'absMetadata'] + const metadataPrecedence = librarySettings.metadataPrecedence || ['folderStructure', 'audioMetatags', 'nfoFile', 'txtFiles', 'opfFile', 'absMetadata'] libraryScan.addLog(LogLevel.DEBUG, `"${bookMetadata.title}" Getting metadata with precedence [${metadataPrecedence.join(', ')}]`) for (const metadataSource of metadataPrecedence) { if (bookMetadataSourceHandler[metadataSource]) { @@ -649,6 +650,14 @@ class BookScanner { AudioFileScanner.setBookMetadataFromAudioMetaTags(bookTitle, this.audioFiles, this.bookMetadata, this.libraryScan) } + /** + * Metadata from .nfo file + */ + async nfoFile() { + if (!this.libraryItemData.metadataNfoLibraryFile) return + await NfoFileScanner.scanBookNfoFile(this.libraryItemData.metadataNfoLibraryFile, this.bookMetadata) + } + /** * Description from desc.txt and narrator from reader.txt */ diff --git a/server/scanner/LibraryItemScanData.js b/server/scanner/LibraryItemScanData.js index 576280c834..b604e4d7ed 100644 --- a/server/scanner/LibraryItemScanData.js +++ b/server/scanner/LibraryItemScanData.js @@ -132,6 +132,11 @@ class LibraryItemScanData { return this.libraryFiles.find(lf => lf.metadata.ext.toLowerCase() === '.opf') } + /** @type {LibraryItem.LibraryFileObject} */ + get metadataNfoLibraryFile() { + return this.libraryFiles.find(lf => lf.metadata.ext.toLowerCase() === '.nfo') + } + /** * * @param {LibraryItem} existingLibraryItem diff --git a/server/scanner/NfoFileScanner.js b/server/scanner/NfoFileScanner.js new file mode 100644 index 0000000000..e450b5c307 --- /dev/null +++ b/server/scanner/NfoFileScanner.js @@ -0,0 +1,48 @@ +const { parseNfoMetadata } = require('../utils/parsers/parseNfoMetadata') +const { readTextFile } = require('../utils/fileUtils') + +class NfoFileScanner { + constructor() { } + + /** + * Parse metadata from .nfo file found in library scan and update bookMetadata + * + * @param {import('../models/LibraryItem').LibraryFileObject} nfoLibraryFileObj + * @param {Object} bookMetadata + */ + async scanBookNfoFile(nfoLibraryFileObj, bookMetadata) { + const nfoText = await readTextFile(nfoLibraryFileObj.metadata.path) + const nfoMetadata = nfoText ? await parseNfoMetadata(nfoText) : null + if (nfoMetadata) { + for (const key in nfoMetadata) { + if (key === 'tags') { // Add tags only if tags are empty + if (nfoMetadata.tags.length) { + bookMetadata.tags = nfoMetadata.tags + } + } else if (key === 'genres') { // Add genres only if genres are empty + if (nfoMetadata.genres.length) { + bookMetadata.genres = nfoMetadata.genres + } + } else if (key === 'authors') { + if (nfoMetadata.authors?.length) { + bookMetadata.authors = nfoMetadata.authors + } + } else if (key === 'narrators') { + if (nfoMetadata.narrators?.length) { + bookMetadata.narrators = nfoMetadata.narrators + } + } else if (key === 'series') { + if (nfoMetadata.series) { + bookMetadata.series = [{ + name: nfoMetadata.series, + sequence: nfoMetadata.sequence || null + }] + } + } else if (nfoMetadata[key] && key !== 'sequence') { + bookMetadata[key] = nfoMetadata[key] + } + } + } + } +} +module.exports = new NfoFileScanner() \ No newline at end of file diff --git a/server/utils/parsers/parseNfoMetadata.js b/server/utils/parsers/parseNfoMetadata.js new file mode 100644 index 0000000000..a7fbbceb4a --- /dev/null +++ b/server/utils/parsers/parseNfoMetadata.js @@ -0,0 +1,94 @@ +function parseNfoMetadata(nfoText) { + if (!nfoText) return null + const lines = nfoText.split(/\r?\n/) + const metadata = {} + let insideBookDescription = false + lines.forEach(line => { + if (line.search(/^\s*book description\s*$/i) !== -1) { + insideBookDescription = true + return + } + if (insideBookDescription) { + if (line.search(/^\s*=+\s*$/i) !== -1) return + metadata.description = metadata.description || '' + metadata.description += line + '\n' + return + } + const match = line.match(/^(.*?):(.*)$/) + if (match) { + const key = match[1].toLowerCase().trim() + const value = match[2].trim() + if (!value) return + switch (key) { + case 'title': + { + const titleMatch = value.match(/^(.*?):(.*)$/) + if (titleMatch) { + metadata.title = titleMatch[1].trim() + metadata.subtitle = titleMatch[2].trim() + } else { + metadata.title = value + } + } + break + case 'author': + metadata.authors = value.split(/\s*,\s*/) + break + case 'narrator': + case 'read by': + metadata.narrators = value.split(/\s*,\s*/) + break + case 'series name': + metadata.series = value + break + case 'genre': + metadata.genres = value.split(/\s*,\s*/) + break + case 'tags': + metadata.tags = value.split(/\s*,\s*/) + break + case 'copyright': + case 'audible.com release': + case 'audiobook copyright': + case 'book copyright': + case 'recording copyright': + case 'release date': + case 'date': + { + const year = extractYear(value) + if (year) { + metadata.publishedYear = year + } + } + break; + case 'position in series': + metadata.sequence = value + break + case 'unabridged': + metadata.abridged = value.toLowerCase() === 'yes' ? false : true + break + case 'abridged': + metadata.abridged = value.toLowerCase() === 'no' ? false : true + break + case 'publisher': + metadata.publisher = value + break + case 'asin': + metadata.asin = value + break + case 'isbn': + case 'isbn-10': + case 'isbn-13': + metadata.isbn = value + break + } + } + }) + return metadata +} +module.exports = { parseNfoMetadata } + +function extractYear(str) { + const match = str.match(/\d{4}/g) + return match ? match[match.length-1] : null +} \ No newline at end of file From 781d4f570f2617f28fa53a4fb0a05d77bc2fd494 Mon Sep 17 00:00:00 2001 From: mikiher Date: Tue, 21 Nov 2023 09:11:06 +0200 Subject: [PATCH 2/6] Add test for parseNfoMetadata --- .../utils/parsers/parseNfoMetadata.test.js | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 test/server/utils/parsers/parseNfoMetadata.test.js diff --git a/test/server/utils/parsers/parseNfoMetadata.test.js b/test/server/utils/parsers/parseNfoMetadata.test.js new file mode 100644 index 0000000000..91141335b7 --- /dev/null +++ b/test/server/utils/parsers/parseNfoMetadata.test.js @@ -0,0 +1,123 @@ +const chai = require('chai') +const expect = chai.expect +const { parseNfoMetadata } = require('../../../../server/utils/parsers/parseNfoMetadata') + +describe('parseNfoMetadata', () => { + it('returns null if nfoText is empty', () => { + const result = parseNfoMetadata('') + expect(result).to.be.null + }) + + it('parses title', () => { + const nfoText = 'Title: The Great Gatsby' + const result = parseNfoMetadata(nfoText) + expect(result.title).to.equal('The Great Gatsby') + }) + + it('parses title with subtitle', () => { + const nfoText = 'Title: The Great Gatsby: A Novel' + const result = parseNfoMetadata(nfoText) + expect(result.title).to.equal('The Great Gatsby') + expect(result.subtitle).to.equal('A Novel') + }) + + it('parses authors', () => { + const nfoText = 'Author: F. Scott Fitzgerald' + const result = parseNfoMetadata(nfoText) + expect(result.authors).to.deep.equal(['F. Scott Fitzgerald']) + }) + + it('parses multiple authors', () => { + const nfoText = 'Author: John Steinbeck, Ernest Hemingway' + const result = parseNfoMetadata(nfoText) + expect(result.authors).to.deep.equal(['John Steinbeck', 'Ernest Hemingway']) + }) + + it('parses narrators', () => { + const nfoText = 'Read by: Jake Gyllenhaal' + const result = parseNfoMetadata(nfoText) + expect(result.narrators).to.deep.equal(['Jake Gyllenhaal']) + }) + + it('parses multiple narrators', () => { + const nfoText = 'Read by: Jake Gyllenhaal, Kate Winslet' + const result = parseNfoMetadata(nfoText) + expect(result.narrators).to.deep.equal(['Jake Gyllenhaal', 'Kate Winslet']) + }) + + it('parses series name', () => { + const nfoText = 'Series Name: Harry Potter' + const result = parseNfoMetadata(nfoText) + expect(result.series).to.equal('Harry Potter') + }) + + it('parses genre', () => { + const nfoText = 'Genre: Fiction' + const result = parseNfoMetadata(nfoText) + expect(result.genres).to.deep.equal(['Fiction']) + }) + + it('parses multiple genres', () => { + const nfoText = 'Genre: Fiction, Historical' + const result = parseNfoMetadata(nfoText) + expect(result.genres).to.deep.equal(['Fiction', 'Historical']) + }) + + it('parses tags', () => { + const nfoText = 'Tags: mystery, thriller' + const result = parseNfoMetadata(nfoText) + expect(result.tags).to.deep.equal(['mystery', 'thriller']) + }) + + it('parses year from various date fields', () => { + const nfoText = 'Release Date: 2021-05-01\nBook Copyright: 2021\nRecording Copyright: 2021' + const result = parseNfoMetadata(nfoText) + expect(result.publishedYear).to.equal('2021') + }) + + it('parses position in series', () => { + const nfoText = 'Position in Series: 2' + const result = parseNfoMetadata(nfoText) + expect(result.sequence).to.equal('2') + }) + + it('parses abridged flag', () => { + const nfoText = 'Abridged: No' + const result = parseNfoMetadata(nfoText) + expect(result.abridged).to.be.false + + const nfoText2 = 'Unabridged: Yes' + const result2 = parseNfoMetadata(nfoText2) + expect(result2.abridged).to.be.false + }) + + it('parses publisher', () => { + const nfoText = 'Publisher: Penguin Random House' + const result = parseNfoMetadata(nfoText) + expect(result.publisher).to.equal('Penguin Random House') + }) + + it('parses ASIN', () => { + const nfoText = 'ASIN: B08X5JZJLH' + const result = parseNfoMetadata(nfoText) + expect(result.asin).to.equal('B08X5JZJLH') + }) + + it('parses description', () => { + const nfoText = 'Book Description\n=========\nThis is a book.\n It\'s good' + const result = parseNfoMetadata(nfoText) + expect(result.description).to.equal('This is a book.\n It\'s good\n') + }) + + it('no value', () => { + const nfoText = 'Title:' + const result = parseNfoMetadata(nfoText) + expect(result.title).to.be.undefined + }) + + it('no year value', () => { + const nfoText = "Date:0" + const result = parseNfoMetadata(nfoText) + expect(result.publishedYear).to.be.undefined + }) +}) \ No newline at end of file From 5e69b54eb0ee39f118221a077802b093ea190b30 Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 26 Nov 2023 13:45:43 -0600 Subject: [PATCH 3/6] Reverse order of metadata precedence in UI, add translations --- .../libraries/LibraryScannerSettings.vue | 27 +++++++++++++++---- client/strings/cs.json | 7 +++-- client/strings/da.json | 5 +++- client/strings/de.json | 5 +++- client/strings/en-us.json | 4 ++- client/strings/es.json | 5 +++- client/strings/fr.json | 5 +++- client/strings/gu.json | 5 +++- client/strings/hi.json | 5 +++- client/strings/hr.json | 5 +++- client/strings/it.json | 7 +++-- client/strings/lt.json | 5 +++- client/strings/nl.json | 5 +++- client/strings/no.json | 5 +++- client/strings/pl.json | 5 +++- client/strings/ru.json | 5 +++- client/strings/sv.json | 5 +++- client/strings/zh-cn.json | 5 +++- 18 files changed, 91 insertions(+), 24 deletions(-) diff --git a/client/components/modals/libraries/LibraryScannerSettings.vue b/client/components/modals/libraries/LibraryScannerSettings.vue index 253d4e6b02..8ec73dd03c 100644 --- a/client/components/modals/libraries/LibraryScannerSettings.vue +++ b/client/components/modals/libraries/LibraryScannerSettings.vue @@ -19,9 +19,11 @@
  • reorder
    - {{ source.include ? index + 1 : '' }} + {{ source.include ? getSourceIndex(source.id) : '' }} +
    +
    + {{ source.name }} {{ index === firstActiveSourceIndex ? $strings.LabelHighestPriority : $strings.LabelLowestPriority }}
    -
    {{ source.name }}
    @@ -97,20 +99,34 @@ export default { }, isBookLibrary() { return this.mediaType === 'book' + }, + firstActiveSourceIndex() { + return this.metadataSourceMapped.findIndex((source) => source.include) + }, + lastActiveSourceIndex() { + return this.metadataSourceMapped.findLastIndex((source) => source.include) } }, methods: { + getSourceIndex(source) { + const activeSources = (this.librarySettings.metadataPrecedence || []).map((s) => s).reverse() + return activeSources.findIndex((s) => s === source) + 1 + }, resetToDefault() { this.metadataSourceMapped = [] for (const key in this.metadataSourceData) { this.metadataSourceMapped.push({ ...this.metadataSourceData[key] }) } + this.metadataSourceMapped.reverse() + this.$emit('update', this.getLibraryData()) }, getLibraryData() { + const metadataSourceIds = this.metadataSourceMapped.map((source) => (source.include ? source.id : null)).filter((s) => s) + metadataSourceIds.reverse() return { settings: { - metadataPrecedence: this.metadataSourceMapped.map((source) => (source.include ? source.id : null)).filter((s) => s) + metadataPrecedence: metadataSourceIds } } }, @@ -125,15 +141,16 @@ export default { }, init() { const metadataPrecedence = this.librarySettings.metadataPrecedence || [] - this.metadataSourceMapped = metadataPrecedence.map((source) => this.metadataSourceData[source]).filter((s) => s) for (const sourceKey in this.metadataSourceData) { if (!metadataPrecedence.includes(sourceKey)) { const unusedSourceData = { ...this.metadataSourceData[sourceKey], include: false } - this.metadataSourceMapped.push(unusedSourceData) + this.metadataSourceMapped.unshift(unusedSourceData) } } + + this.metadataSourceMapped.reverse() } }, mounted() { diff --git a/client/strings/cs.json b/client/strings/cs.json index 07f3d4f7db..71d06dca89 100644 --- a/client/strings/cs.json +++ b/client/strings/cs.json @@ -92,6 +92,7 @@ "HeaderAppriseNotificationSettings": "Nastavení oznámení Apprise", "HeaderAudiobookTools": "Nástroje pro správu souborů audioknih", "HeaderAudioTracks": "Zvukové stopy", + "HeaderAuthentication": "Authentication", "HeaderBackups": "Zálohy", "HeaderChangePassword": "Změnit heslo", "HeaderChapters": "Kapitoly", @@ -275,6 +276,7 @@ "LabelHardDeleteFile": "Trvale smazat soubor", "LabelHasEbook": "Obsahuje elektronickou knihu", "LabelHasSupplementaryEbook": "Obsahuje doplňkovou elektronickou knihu", + "LabelHighestPriority": "Highest priority", "LabelHost": "Hostitel", "LabelHour": "Hodina", "LabelIcon": "Ikona", @@ -316,9 +318,10 @@ "LabelLogLevelInfo": "Informace", "LabelLogLevelWarn": "Varovat", "LabelLookForNewEpisodesAfterDate": "Hledat nové epizody po tomto datu", + "LabelLowestPriority": "Lowest Priority", "LabelMediaPlayer": "Přehrávač médií", "LabelMediaType": "Typ média", - "LabelMetadataOrderOfPrecedenceDescription": "1 je nejnižší priorita, 5 je nejvyšší priorita", + "LabelMetadataOrderOfPrecedenceDescription": "Higher priority metadata sources will override lower priority metadata sources", "LabelMetadataProvider": "Poskytovatel metadat", "LabelMetaTag": "Metaznačka", "LabelMetaTags": "Metaznačky", @@ -726,4 +729,4 @@ "ToastSocketFailedToConnect": "Socket se nepodařilo připojit", "ToastUserDeleteFailed": "Nepodařilo se smazat uživatele", "ToastUserDeleteSuccess": "Uživatel smazán" -} +} \ No newline at end of file diff --git a/client/strings/da.json b/client/strings/da.json index 768bb724f4..3fafae9f57 100644 --- a/client/strings/da.json +++ b/client/strings/da.json @@ -92,6 +92,7 @@ "HeaderAppriseNotificationSettings": "Apprise Notifikationsindstillinger", "HeaderAudiobookTools": "Audiobog Filhåndteringsværktøjer", "HeaderAudioTracks": "Lydspor", + "HeaderAuthentication": "Authentication", "HeaderBackups": "Sikkerhedskopier", "HeaderChangePassword": "Skift Adgangskode", "HeaderChapters": "Kapitler", @@ -275,6 +276,7 @@ "LabelHardDeleteFile": "Permanent slet fil", "LabelHasEbook": "Har e-bog", "LabelHasSupplementaryEbook": "Har supplerende e-bog", + "LabelHighestPriority": "Highest priority", "LabelHost": "Vært", "LabelHour": "Time", "LabelIcon": "Ikon", @@ -316,9 +318,10 @@ "LabelLogLevelInfo": "Information", "LabelLogLevelWarn": "Advarsel", "LabelLookForNewEpisodesAfterDate": "Søg efter nye episoder efter denne dato", + "LabelLowestPriority": "Lowest Priority", "LabelMediaPlayer": "Medieafspiller", "LabelMediaType": "Medietype", - "LabelMetadataOrderOfPrecedenceDescription": "1 is lowest priority, 5 is highest priority", + "LabelMetadataOrderOfPrecedenceDescription": "Higher priority metadata sources will override lower priority metadata sources", "LabelMetadataProvider": "Metadataudbyder", "LabelMetaTag": "Meta-tag", "LabelMetaTags": "Meta-tags", diff --git a/client/strings/de.json b/client/strings/de.json index f7cf8b68e9..f957ca99aa 100644 --- a/client/strings/de.json +++ b/client/strings/de.json @@ -92,6 +92,7 @@ "HeaderAppriseNotificationSettings": "Apprise Benachrichtigungseinstellungen", "HeaderAudiobookTools": "Hörbuch-Dateiverwaltungstools", "HeaderAudioTracks": "Audiodateien", + "HeaderAuthentication": "Authentication", "HeaderBackups": "Sicherungen", "HeaderChangePassword": "Passwort ändern", "HeaderChapters": "Kapitel", @@ -275,6 +276,7 @@ "LabelHardDeleteFile": "Datei dauerhaft löschen", "LabelHasEbook": "mit E-Book", "LabelHasSupplementaryEbook": "mit zusätlichem E-Book", + "LabelHighestPriority": "Highest priority", "LabelHost": "Host", "LabelHour": "Stunde", "LabelIcon": "Symbol", @@ -316,9 +318,10 @@ "LabelLogLevelInfo": "Informationen", "LabelLogLevelWarn": "Warnungen", "LabelLookForNewEpisodesAfterDate": "Suchen nach neuen Episoden nach diesem Datum", + "LabelLowestPriority": "Lowest Priority", "LabelMediaPlayer": "Mediaplayer", "LabelMediaType": "Medientyp", - "LabelMetadataOrderOfPrecedenceDescription": "1 is lowest priority, 5 is highest priority", + "LabelMetadataOrderOfPrecedenceDescription": "Higher priority metadata sources will override lower priority metadata sources", "LabelMetadataProvider": "Metadatenanbieter", "LabelMetaTag": "Meta Schlagwort", "LabelMetaTags": "Meta Tags", diff --git a/client/strings/en-us.json b/client/strings/en-us.json index 6f06ca77ea..8d9a22c8c9 100644 --- a/client/strings/en-us.json +++ b/client/strings/en-us.json @@ -276,6 +276,7 @@ "LabelHardDeleteFile": "Hard delete file", "LabelHasEbook": "Has ebook", "LabelHasSupplementaryEbook": "Has supplementary ebook", + "LabelHighestPriority": "Highest priority", "LabelHost": "Host", "LabelHour": "Hour", "LabelIcon": "Icon", @@ -317,9 +318,10 @@ "LabelLogLevelInfo": "Info", "LabelLogLevelWarn": "Warn", "LabelLookForNewEpisodesAfterDate": "Look for new episodes after this date", + "LabelLowestPriority": "Lowest Priority", "LabelMediaPlayer": "Media Player", "LabelMediaType": "Media Type", - "LabelMetadataOrderOfPrecedenceDescription": "1 is lowest priority, 5 is highest priority", + "LabelMetadataOrderOfPrecedenceDescription": "Higher priority metadata sources will override lower priority metadata sources", "LabelMetadataProvider": "Metadata Provider", "LabelMetaTag": "Meta Tag", "LabelMetaTags": "Meta Tags", diff --git a/client/strings/es.json b/client/strings/es.json index 0ac0a96018..d4752c1a4b 100644 --- a/client/strings/es.json +++ b/client/strings/es.json @@ -92,6 +92,7 @@ "HeaderAppriseNotificationSettings": "Ajustes de Notificaciones de Apprise", "HeaderAudiobookTools": "Herramientas de Gestión de Archivos de Audiolibro", "HeaderAudioTracks": "Pistas de Audio", + "HeaderAuthentication": "Authentication", "HeaderBackups": "Respaldos", "HeaderChangePassword": "Cambiar Contraseña", "HeaderChapters": "Capítulos", @@ -275,6 +276,7 @@ "LabelHardDeleteFile": "Eliminar Definitivamente", "LabelHasEbook": "Tiene Ebook", "LabelHasSupplementaryEbook": "Tiene Ebook Suplementario", + "LabelHighestPriority": "Highest priority", "LabelHost": "Host", "LabelHour": "Hora", "LabelIcon": "Icono", @@ -316,9 +318,10 @@ "LabelLogLevelInfo": "Información", "LabelLogLevelWarn": "Advertencia", "LabelLookForNewEpisodesAfterDate": "Buscar Nuevos Episodios a partir de esta Fecha", + "LabelLowestPriority": "Lowest Priority", "LabelMediaPlayer": "Reproductor de Medios", "LabelMediaType": "Tipo de Multimedia", - "LabelMetadataOrderOfPrecedenceDescription": "1 is lowest priority, 5 is highest priority", + "LabelMetadataOrderOfPrecedenceDescription": "Higher priority metadata sources will override lower priority metadata sources", "LabelMetadataProvider": "Proveedor de Metadata", "LabelMetaTag": "Meta Tag", "LabelMetaTags": "Meta Tags", diff --git a/client/strings/fr.json b/client/strings/fr.json index 5ad80723f4..56f214a299 100644 --- a/client/strings/fr.json +++ b/client/strings/fr.json @@ -92,6 +92,7 @@ "HeaderAppriseNotificationSettings": "Configuration des Notifications Apprise", "HeaderAudiobookTools": "Outils de Gestion de Fichier Audiobook", "HeaderAudioTracks": "Pistes audio", + "HeaderAuthentication": "Authentication", "HeaderBackups": "Sauvegardes", "HeaderChangePassword": "Modifier le mot de passe", "HeaderChapters": "Chapitres", @@ -275,6 +276,7 @@ "LabelHardDeleteFile": "Suppression du fichier", "LabelHasEbook": "Dispose d’un livre numérique", "LabelHasSupplementaryEbook": "Dispose d’un livre numérique supplémentaire", + "LabelHighestPriority": "Highest priority", "LabelHost": "Hôte", "LabelHour": "Heure", "LabelIcon": "Icone", @@ -316,9 +318,10 @@ "LabelLogLevelInfo": "Info", "LabelLogLevelWarn": "Warn", "LabelLookForNewEpisodesAfterDate": "Chercher de nouveaux épisode après cette date", + "LabelLowestPriority": "Lowest Priority", "LabelMediaPlayer": "Lecteur multimédia", "LabelMediaType": "Type de média", - "LabelMetadataOrderOfPrecedenceDescription": "1 is lowest priority, 5 is highest priority", + "LabelMetadataOrderOfPrecedenceDescription": "Higher priority metadata sources will override lower priority metadata sources", "LabelMetadataProvider": "Fournisseur de métadonnées", "LabelMetaTag": "Etiquette de métadonnée", "LabelMetaTags": "Etiquettes de métadonnée", diff --git a/client/strings/gu.json b/client/strings/gu.json index d71c9f1767..6e11a221b6 100644 --- a/client/strings/gu.json +++ b/client/strings/gu.json @@ -92,6 +92,7 @@ "HeaderAppriseNotificationSettings": "Apprise સૂચના સેટિંગ્સ", "HeaderAudiobookTools": "Audiobook File Management Tools", "HeaderAudioTracks": "Audio Tracks", + "HeaderAuthentication": "Authentication", "HeaderBackups": "Backups", "HeaderChangePassword": "Change Password", "HeaderChapters": "Chapters", @@ -275,6 +276,7 @@ "LabelHardDeleteFile": "Hard delete file", "LabelHasEbook": "Has ebook", "LabelHasSupplementaryEbook": "Has supplementary ebook", + "LabelHighestPriority": "Highest priority", "LabelHost": "Host", "LabelHour": "Hour", "LabelIcon": "Icon", @@ -316,9 +318,10 @@ "LabelLogLevelInfo": "Info", "LabelLogLevelWarn": "Warn", "LabelLookForNewEpisodesAfterDate": "Look for new episodes after this date", + "LabelLowestPriority": "Lowest Priority", "LabelMediaPlayer": "Media Player", "LabelMediaType": "Media Type", - "LabelMetadataOrderOfPrecedenceDescription": "1 is lowest priority, 5 is highest priority", + "LabelMetadataOrderOfPrecedenceDescription": "Higher priority metadata sources will override lower priority metadata sources", "LabelMetadataProvider": "Metadata Provider", "LabelMetaTag": "Meta Tag", "LabelMetaTags": "Meta Tags", diff --git a/client/strings/hi.json b/client/strings/hi.json index 51b2e7629f..6e228c8992 100644 --- a/client/strings/hi.json +++ b/client/strings/hi.json @@ -92,6 +92,7 @@ "HeaderAppriseNotificationSettings": "Apprise अधिसूचना सेटिंग्स", "HeaderAudiobookTools": "Audiobook File Management Tools", "HeaderAudioTracks": "Audio Tracks", + "HeaderAuthentication": "Authentication", "HeaderBackups": "Backups", "HeaderChangePassword": "Change Password", "HeaderChapters": "Chapters", @@ -275,6 +276,7 @@ "LabelHardDeleteFile": "Hard delete file", "LabelHasEbook": "Has ebook", "LabelHasSupplementaryEbook": "Has supplementary ebook", + "LabelHighestPriority": "Highest priority", "LabelHost": "Host", "LabelHour": "Hour", "LabelIcon": "Icon", @@ -316,9 +318,10 @@ "LabelLogLevelInfo": "Info", "LabelLogLevelWarn": "Warn", "LabelLookForNewEpisodesAfterDate": "Look for new episodes after this date", + "LabelLowestPriority": "Lowest Priority", "LabelMediaPlayer": "Media Player", "LabelMediaType": "Media Type", - "LabelMetadataOrderOfPrecedenceDescription": "1 is lowest priority, 5 is highest priority", + "LabelMetadataOrderOfPrecedenceDescription": "Higher priority metadata sources will override lower priority metadata sources", "LabelMetadataProvider": "Metadata Provider", "LabelMetaTag": "Meta Tag", "LabelMetaTags": "Meta Tags", diff --git a/client/strings/hr.json b/client/strings/hr.json index e04343a09c..6c24b1bd32 100644 --- a/client/strings/hr.json +++ b/client/strings/hr.json @@ -92,6 +92,7 @@ "HeaderAppriseNotificationSettings": "Apprise Notification Settings", "HeaderAudiobookTools": "Audiobook File Management alati", "HeaderAudioTracks": "Audio Tracks", + "HeaderAuthentication": "Authentication", "HeaderBackups": "Backups", "HeaderChangePassword": "Promijeni lozinku", "HeaderChapters": "Poglavlja", @@ -275,6 +276,7 @@ "LabelHardDeleteFile": "Obriši datoteku zauvijek", "LabelHasEbook": "Has ebook", "LabelHasSupplementaryEbook": "Has supplementary ebook", + "LabelHighestPriority": "Highest priority", "LabelHost": "Host", "LabelHour": "Sat", "LabelIcon": "Ikona", @@ -316,9 +318,10 @@ "LabelLogLevelInfo": "Info", "LabelLogLevelWarn": "Warn", "LabelLookForNewEpisodesAfterDate": "Traži nove epizode nakon ovog datuma", + "LabelLowestPriority": "Lowest Priority", "LabelMediaPlayer": "Media Player", "LabelMediaType": "Media Type", - "LabelMetadataOrderOfPrecedenceDescription": "1 is lowest priority, 5 is highest priority", + "LabelMetadataOrderOfPrecedenceDescription": "Higher priority metadata sources will override lower priority metadata sources", "LabelMetadataProvider": "Poslužitelj metapodataka ", "LabelMetaTag": "Meta Tag", "LabelMetaTags": "Meta Tags", diff --git a/client/strings/it.json b/client/strings/it.json index c893212e12..d5cee73cba 100644 --- a/client/strings/it.json +++ b/client/strings/it.json @@ -92,6 +92,7 @@ "HeaderAppriseNotificationSettings": "Apprendi le impostazioni di Notifica", "HeaderAudiobookTools": "Utilità Audiobook File Management", "HeaderAudioTracks": "Tracce Audio", + "HeaderAuthentication": "Authentication", "HeaderBackups": "Backup", "HeaderChangePassword": "Cambia Password", "HeaderChapters": "Capitoli", @@ -275,6 +276,7 @@ "LabelHardDeleteFile": "Elimina Definitivamente", "LabelHasEbook": "Un ebook", "LabelHasSupplementaryEbook": "Un ebook Supplementare", + "LabelHighestPriority": "Highest priority", "LabelHost": "Host", "LabelHour": "Ora", "LabelIcon": "Icona", @@ -316,9 +318,10 @@ "LabelLogLevelInfo": "Info", "LabelLogLevelWarn": "Allarme", "LabelLookForNewEpisodesAfterDate": "Cerca nuovi episodi dopo questa data", + "LabelLowestPriority": "Lowest Priority", "LabelMediaPlayer": "Media Player", "LabelMediaType": "Tipo Media", - "LabelMetadataOrderOfPrecedenceDescription": "1 e bassa priorità, 5 è alta priorità", + "LabelMetadataOrderOfPrecedenceDescription": "Higher priority metadata sources will override lower priority metadata sources", "LabelMetadataProvider": "Metadata Provider", "LabelMetaTag": "Meta Tag", "LabelMetaTags": "Meta Tags", @@ -726,4 +729,4 @@ "ToastSocketFailedToConnect": "Socket non riesce a connettersi", "ToastUserDeleteFailed": "Errore eliminazione utente", "ToastUserDeleteSuccess": "Utente eliminato" -} +} \ No newline at end of file diff --git a/client/strings/lt.json b/client/strings/lt.json index ebc6b55888..520aaa7474 100644 --- a/client/strings/lt.json +++ b/client/strings/lt.json @@ -92,6 +92,7 @@ "HeaderAppriseNotificationSettings": "Apprise pranešimo nustatymai", "HeaderAudiobookTools": "Audioknygų failų valdymo įrankiai", "HeaderAudioTracks": "Garso takeliai", + "HeaderAuthentication": "Authentication", "HeaderBackups": "Atsarginės kopijos", "HeaderChangePassword": "Pakeisti slaptažodį", "HeaderChapters": "Skyriai", @@ -275,6 +276,7 @@ "LabelHardDeleteFile": "Galutinai ištrinti failą", "LabelHasEbook": "Turi e-knygą", "LabelHasSupplementaryEbook": "Turi papildomą e-knygą", + "LabelHighestPriority": "Highest priority", "LabelHost": "Serveris", "LabelHour": "Valanda", "LabelIcon": "Piktograma", @@ -316,9 +318,10 @@ "LabelLogLevelInfo": "Info", "LabelLogLevelWarn": "Warn", "LabelLookForNewEpisodesAfterDate": "Ieškoti naujų epizodų po šios datos", + "LabelLowestPriority": "Lowest Priority", "LabelMediaPlayer": "Grotuvas", "LabelMediaType": "Medijos tipas", - "LabelMetadataOrderOfPrecedenceDescription": "1 is lowest priority, 5 is highest priority", + "LabelMetadataOrderOfPrecedenceDescription": "Higher priority metadata sources will override lower priority metadata sources", "LabelMetadataProvider": "Metaduomenų tiekėjas", "LabelMetaTag": "Meta žymė", "LabelMetaTags": "Meta žymos", diff --git a/client/strings/nl.json b/client/strings/nl.json index 06aed90459..e05db32b9c 100644 --- a/client/strings/nl.json +++ b/client/strings/nl.json @@ -92,6 +92,7 @@ "HeaderAppriseNotificationSettings": "Apprise-notificatie instellingen", "HeaderAudiobookTools": "Audioboekbestandbeheer tools", "HeaderAudioTracks": "Audiotracks", + "HeaderAuthentication": "Authentication", "HeaderBackups": "Back-ups", "HeaderChangePassword": "Wachtwoord wijzigen", "HeaderChapters": "Hoofdstukken", @@ -275,6 +276,7 @@ "LabelHardDeleteFile": "Hard-delete bestand", "LabelHasEbook": "Heeft ebook", "LabelHasSupplementaryEbook": "Heeft supplementair ebook", + "LabelHighestPriority": "Highest priority", "LabelHost": "Host", "LabelHour": "Uur", "LabelIcon": "Icoon", @@ -316,9 +318,10 @@ "LabelLogLevelInfo": "Info", "LabelLogLevelWarn": "Waarschuwing", "LabelLookForNewEpisodesAfterDate": "Zoek naar nieuwe afleveringen na deze datum", + "LabelLowestPriority": "Lowest Priority", "LabelMediaPlayer": "Mediaspeler", "LabelMediaType": "Mediatype", - "LabelMetadataOrderOfPrecedenceDescription": "1 is lowest priority, 5 is highest priority", + "LabelMetadataOrderOfPrecedenceDescription": "Higher priority metadata sources will override lower priority metadata sources", "LabelMetadataProvider": "Metadatabron", "LabelMetaTag": "Meta-tag", "LabelMetaTags": "Meta-tags", diff --git a/client/strings/no.json b/client/strings/no.json index 7fcd1c96ab..b36a002601 100644 --- a/client/strings/no.json +++ b/client/strings/no.json @@ -92,6 +92,7 @@ "HeaderAppriseNotificationSettings": "Apprise notifikasjonsinstillinger", "HeaderAudiobookTools": "Lydbok Filbehandlingsverktøy", "HeaderAudioTracks": "Lydspor", + "HeaderAuthentication": "Authentication", "HeaderBackups": "Sikkerhetskopier", "HeaderChangePassword": "Bytt passord", "HeaderChapters": "Kapittel", @@ -275,6 +276,7 @@ "LabelHardDeleteFile": "Tving sletting av fil", "LabelHasEbook": "Har ebok", "LabelHasSupplementaryEbook": "Har supplerende ebok", + "LabelHighestPriority": "Highest priority", "LabelHost": "Tjener", "LabelHour": "Time", "LabelIcon": "Ikon", @@ -316,9 +318,10 @@ "LabelLogLevelInfo": "Info", "LabelLogLevelWarn": "Warn", "LabelLookForNewEpisodesAfterDate": "Se etter nye episoder etter denne datoen", + "LabelLowestPriority": "Lowest Priority", "LabelMediaPlayer": "Mediespiller", "LabelMediaType": "Medie type", - "LabelMetadataOrderOfPrecedenceDescription": "1 is lowest priority, 5 is highest priority", + "LabelMetadataOrderOfPrecedenceDescription": "Higher priority metadata sources will override lower priority metadata sources", "LabelMetadataProvider": "Metadata Leverandør", "LabelMetaTag": "Meta Tag", "LabelMetaTags": "Meta Tags", diff --git a/client/strings/pl.json b/client/strings/pl.json index dd3c1d4adc..e3729a6bb9 100644 --- a/client/strings/pl.json +++ b/client/strings/pl.json @@ -92,6 +92,7 @@ "HeaderAppriseNotificationSettings": "Ustawienia powiadomień Apprise", "HeaderAudiobookTools": "Narzędzia do zarządzania audiobookami", "HeaderAudioTracks": "Ścieżki audio", + "HeaderAuthentication": "Authentication", "HeaderBackups": "Kopie zapasowe", "HeaderChangePassword": "Zmień hasło", "HeaderChapters": "Rozdziały", @@ -275,6 +276,7 @@ "LabelHardDeleteFile": "Usuń trwale plik", "LabelHasEbook": "Has ebook", "LabelHasSupplementaryEbook": "Has supplementary ebook", + "LabelHighestPriority": "Highest priority", "LabelHost": "Host", "LabelHour": "Godzina", "LabelIcon": "Ikona", @@ -316,9 +318,10 @@ "LabelLogLevelInfo": "Informacja", "LabelLogLevelWarn": "Ostrzeżenie", "LabelLookForNewEpisodesAfterDate": "Szukaj nowych odcinków po dacie", + "LabelLowestPriority": "Lowest Priority", "LabelMediaPlayer": "Odtwarzacz", "LabelMediaType": "Typ mediów", - "LabelMetadataOrderOfPrecedenceDescription": "1 is lowest priority, 5 is highest priority", + "LabelMetadataOrderOfPrecedenceDescription": "Higher priority metadata sources will override lower priority metadata sources", "LabelMetadataProvider": "Dostawca metadanych", "LabelMetaTag": "Tag", "LabelMetaTags": "Meta Tags", diff --git a/client/strings/ru.json b/client/strings/ru.json index 832ffe8b62..9caabb72a6 100644 --- a/client/strings/ru.json +++ b/client/strings/ru.json @@ -92,6 +92,7 @@ "HeaderAppriseNotificationSettings": "Настройки оповещений", "HeaderAudiobookTools": "Инструменты файлов аудиокниг", "HeaderAudioTracks": "Аудио треки", + "HeaderAuthentication": "Authentication", "HeaderBackups": "Бэкапы", "HeaderChangePassword": "Изменить пароль", "HeaderChapters": "Главы", @@ -275,6 +276,7 @@ "LabelHardDeleteFile": "Жесткое удаление файла", "LabelHasEbook": "Есть e-книга", "LabelHasSupplementaryEbook": "Есть дополнительная e-книга", + "LabelHighestPriority": "Highest priority", "LabelHost": "Хост", "LabelHour": "Часы", "LabelIcon": "Иконка", @@ -316,9 +318,10 @@ "LabelLogLevelInfo": "Info", "LabelLogLevelWarn": "Warn", "LabelLookForNewEpisodesAfterDate": "Искать новые эпизоды после этой даты", + "LabelLowestPriority": "Lowest Priority", "LabelMediaPlayer": "Медиа проигрыватель", "LabelMediaType": "Тип медиа", - "LabelMetadataOrderOfPrecedenceDescription": "1 is lowest priority, 5 is highest priority", + "LabelMetadataOrderOfPrecedenceDescription": "Higher priority metadata sources will override lower priority metadata sources", "LabelMetadataProvider": "Провайдер", "LabelMetaTag": "Мета тег", "LabelMetaTags": "Мета теги", diff --git a/client/strings/sv.json b/client/strings/sv.json index 23d489d059..ab20e40b1d 100644 --- a/client/strings/sv.json +++ b/client/strings/sv.json @@ -92,6 +92,7 @@ "HeaderAppriseNotificationSettings": "Apprise Meddelandeinställningar", "HeaderAudiobookTools": "Ljudbokshantering", "HeaderAudioTracks": "Ljudspår", + "HeaderAuthentication": "Authentication", "HeaderBackups": "Säkerhetskopior", "HeaderChangePassword": "Ändra lösenord", "HeaderChapters": "Kapitel", @@ -275,6 +276,7 @@ "LabelHardDeleteFile": "Hård radering av fil", "LabelHasEbook": "Har e-bok", "LabelHasSupplementaryEbook": "Har kompletterande e-bok", + "LabelHighestPriority": "Highest priority", "LabelHost": "Värd", "LabelHour": "Timme", "LabelIcon": "Ikon", @@ -316,9 +318,10 @@ "LabelLogLevelInfo": "Felsökningsnivå: Information", "LabelLogLevelWarn": "Felsökningsnivå: Varning", "LabelLookForNewEpisodesAfterDate": "Sök efter nya avsnitt efter detta datum", + "LabelLowestPriority": "Lowest Priority", "LabelMediaPlayer": "Mediaspelare", "LabelMediaType": "Mediatyp", - "LabelMetadataOrderOfPrecedenceDescription": "1 är lägsta prioritet, 5 är högsta prioritet", + "LabelMetadataOrderOfPrecedenceDescription": "Higher priority metadata sources will override lower priority metadata sources", "LabelMetadataProvider": "Metadataleverantör", "LabelMetaTag": "Metamärke", "LabelMetaTags": "Metamärken", diff --git a/client/strings/zh-cn.json b/client/strings/zh-cn.json index 5d3de27ad5..616e4f6c41 100644 --- a/client/strings/zh-cn.json +++ b/client/strings/zh-cn.json @@ -92,6 +92,7 @@ "HeaderAppriseNotificationSettings": "测试通知设置", "HeaderAudiobookTools": "有声读物文件管理工具", "HeaderAudioTracks": "音轨", + "HeaderAuthentication": "Authentication", "HeaderBackups": "备份", "HeaderChangePassword": "更改密码", "HeaderChapters": "章节", @@ -275,6 +276,7 @@ "LabelHardDeleteFile": "完全删除文件", "LabelHasEbook": "有电子书", "LabelHasSupplementaryEbook": "有补充电子书", + "LabelHighestPriority": "Highest priority", "LabelHost": "主机", "LabelHour": "小时", "LabelIcon": "图标", @@ -316,9 +318,10 @@ "LabelLogLevelInfo": "信息", "LabelLogLevelWarn": "警告", "LabelLookForNewEpisodesAfterDate": "在此日期后查找新剧集", + "LabelLowestPriority": "Lowest Priority", "LabelMediaPlayer": "媒体播放器", "LabelMediaType": "媒体类型", - "LabelMetadataOrderOfPrecedenceDescription": "1 is lowest priority, 5 is highest priority", + "LabelMetadataOrderOfPrecedenceDescription": "Higher priority metadata sources will override lower priority metadata sources", "LabelMetadataProvider": "元数据提供者", "LabelMetaTag": "元数据标签", "LabelMetaTags": "元标签", From d9584174ffb153d812cda70af530492253ec1c1c Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 26 Nov 2023 14:33:35 -0600 Subject: [PATCH 4/6] Parse NFO trim final parsed description --- server/utils/parsers/parseNfoMetadata.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/server/utils/parsers/parseNfoMetadata.js b/server/utils/parsers/parseNfoMetadata.js index a7fbbceb4a..ac41cfe60f 100644 --- a/server/utils/parsers/parseNfoMetadata.js +++ b/server/utils/parsers/parseNfoMetadata.js @@ -60,7 +60,7 @@ function parseNfoMetadata(nfoText) { metadata.publishedYear = year } } - break; + break case 'position in series': metadata.sequence = value break @@ -76,19 +76,25 @@ function parseNfoMetadata(nfoText) { case 'asin': metadata.asin = value break - case 'isbn': - case 'isbn-10': - case 'isbn-13': + case 'isbn': + case 'isbn-10': + case 'isbn-13': metadata.isbn = value break - } + } } }) + + // Trim leading/trailing whitespace for description + if (metadata.description) { + metadata.description = metadata.description.trim() + } + return metadata } module.exports = { parseNfoMetadata } function extractYear(str) { const match = str.match(/\d{4}/g) - return match ? match[match.length-1] : null + return match ? match[match.length - 1] : null } \ No newline at end of file From b4c14fc78d032f896b5ffd9f0223b205c0510a43 Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 26 Nov 2023 14:38:25 -0600 Subject: [PATCH 5/6] Parse NFO comma separated strings remove empty strings --- server/utils/parsers/parseNfoMetadata.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/utils/parsers/parseNfoMetadata.js b/server/utils/parsers/parseNfoMetadata.js index ac41cfe60f..56e9400a71 100644 --- a/server/utils/parsers/parseNfoMetadata.js +++ b/server/utils/parsers/parseNfoMetadata.js @@ -32,20 +32,20 @@ function parseNfoMetadata(nfoText) { } break case 'author': - metadata.authors = value.split(/\s*,\s*/) + metadata.authors = value.split(/\s*,\s*/).filter(v => v) break case 'narrator': case 'read by': - metadata.narrators = value.split(/\s*,\s*/) + metadata.narrators = value.split(/\s*,\s*/).filter(v => v) break case 'series name': metadata.series = value break case 'genre': - metadata.genres = value.split(/\s*,\s*/) + metadata.genres = value.split(/\s*,\s*/).filter(v => v) break case 'tags': - metadata.tags = value.split(/\s*,\s*/) + metadata.tags = value.split(/\s*,\s*/).filter(v => v) break case 'copyright': case 'audible.com release': From 3d468339b38eef5dba72dd097f4d9eb4e9a99dd4 Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 26 Nov 2023 14:41:19 -0600 Subject: [PATCH 6/6] Update parse nfo metadata test for description --- test/server/utils/parsers/parseNfoMetadata.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/server/utils/parsers/parseNfoMetadata.test.js b/test/server/utils/parsers/parseNfoMetadata.test.js index 91141335b7..70e6a096f7 100644 --- a/test/server/utils/parsers/parseNfoMetadata.test.js +++ b/test/server/utils/parsers/parseNfoMetadata.test.js @@ -106,7 +106,7 @@ describe('parseNfoMetadata', () => { it('parses description', () => { const nfoText = 'Book Description\n=========\nThis is a book.\n It\'s good' const result = parseNfoMetadata(nfoText) - expect(result.description).to.equal('This is a book.\n It\'s good\n') + expect(result.description).to.equal('This is a book.\n It\'s good') }) it('no value', () => {