mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-12-20 19:06:06 +01:00
Add:Parsing tags from OPF metadata #602, Update:OPF parser to check for prefix on package/metadata/meta objects
This commit is contained in:
parent
7e5ab477b2
commit
139ee013a7
@ -225,6 +225,7 @@ class Book {
|
||||
// Look for desc.txt, reader.txt, metadata.abs and opf file then update details if found
|
||||
async syncMetadataFiles(textMetadataFiles, opfMetadataOverrideDetails) {
|
||||
var metadataUpdatePayload = {}
|
||||
var tagsUpdated = false
|
||||
|
||||
var descTxt = textMetadataFiles.find(lf => lf.metadata.filename === 'desc.txt')
|
||||
if (descTxt) {
|
||||
@ -264,8 +265,13 @@ class Book {
|
||||
var opfMetadata = await parseOpfMetadataXML(xmlText)
|
||||
if (opfMetadata) {
|
||||
for (const key in opfMetadata) {
|
||||
// Add genres only if genres are empty
|
||||
if (key === 'genres') {
|
||||
|
||||
if (key === 'tags') { // Add tags only if tags are empty
|
||||
if (opfMetadata.tags.length && (!this.tags.length || opfMetadataOverrideDetails)) {
|
||||
this.tags = opfMetadata.tags
|
||||
tagsUpdated = true
|
||||
}
|
||||
} else if (key === 'genres') { // Add genres only if genres are empty
|
||||
if (opfMetadata.genres.length && (!this.metadata.genres.length || opfMetadataOverrideDetails)) {
|
||||
metadataUpdatePayload[key] = opfMetadata.genres
|
||||
}
|
||||
@ -290,9 +296,9 @@ class Book {
|
||||
}
|
||||
|
||||
if (Object.keys(metadataUpdatePayload).length) {
|
||||
return this.metadata.update(metadataUpdatePayload)
|
||||
return this.metadata.update(metadataUpdatePayload) || tagsUpdated
|
||||
}
|
||||
return false
|
||||
return tagsUpdated
|
||||
}
|
||||
|
||||
searchQuery(query) {
|
||||
|
@ -70,14 +70,14 @@ function fetchLanguage(metadata) {
|
||||
return fetchTagString(metadata, 'dc:language')
|
||||
}
|
||||
|
||||
function fetchSeries(metadata) {
|
||||
if (typeof metadata.meta == "undefined") return null
|
||||
return fetchTagString(metadata.meta, "calibre:series")
|
||||
function fetchSeries(metadataMeta) {
|
||||
if (!metadataMeta) return null
|
||||
return fetchTagString(metadataMeta, "calibre:series")
|
||||
}
|
||||
|
||||
function fetchVolumeNumber(metadata) {
|
||||
if (typeof metadata.meta == "undefined") return null
|
||||
return fetchTagString(metadata.meta, "calibre:series_index")
|
||||
function fetchVolumeNumber(metadataMeta) {
|
||||
if (!metadataMeta) return null
|
||||
return fetchTagString(metadataMeta, "calibre:series_index")
|
||||
}
|
||||
|
||||
function fetchNarrators(creators, metadata) {
|
||||
@ -91,21 +91,42 @@ function fetchNarrators(creators, metadata) {
|
||||
}
|
||||
}
|
||||
|
||||
function fetchTags(metadata) {
|
||||
if (!metadata['dc:tag'] || !metadata['dc:tag'].length) return []
|
||||
return metadata['dc:tag'].filter(tag => (typeof tag === 'string'))
|
||||
}
|
||||
|
||||
function stripPrefix(str) {
|
||||
if (!str) return ''
|
||||
return str.split(':').pop()
|
||||
}
|
||||
|
||||
module.exports.parseOpfMetadataXML = async (xml) => {
|
||||
var json = await xmlToJSON(xml)
|
||||
if (!json || !json.package || !json.package.metadata) return null
|
||||
var metadata = json.package.metadata
|
||||
|
||||
if (!json) return null
|
||||
|
||||
// Handle <package ...> or with prefix <ns0:package ...>
|
||||
const packageKey = Object.keys(json).find(key => stripPrefix(key) === 'package')
|
||||
if (!packageKey) return null
|
||||
const prefix = packageKey.split(':').shift()
|
||||
var metadata = prefix ? json[packageKey][`${prefix}:metadata`] || json[packageKey].metadata : json[packageKey].metadata
|
||||
if (!metadata) return null
|
||||
|
||||
if (Array.isArray(metadata)) {
|
||||
if (!metadata.length) return null
|
||||
metadata = metadata[0]
|
||||
}
|
||||
|
||||
if (typeof metadata.meta != "undefined") {
|
||||
metadata.meta = {}
|
||||
for (var match of xml.matchAll(/<meta name="(?<name>.+)" content="(?<content>.+)"\/>/g)) {
|
||||
metadata.meta[match.groups['name']] = [match.groups['content']]
|
||||
}
|
||||
const metadataMeta = prefix ? metadata[`${prefix}:meta`] || metadata.meta : metadata.meta
|
||||
|
||||
metadata.meta = {}
|
||||
if (metadataMeta && metadataMeta.length) {
|
||||
metadataMeta.forEach((meta) => {
|
||||
if (meta && meta['$'] && meta['$'].name) {
|
||||
metadata.meta[meta['$'].name] = [meta['$'].content || '']
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var creators = parseCreators(metadata)
|
||||
@ -119,8 +140,9 @@ module.exports.parseOpfMetadataXML = async (xml) => {
|
||||
description: fetchDescription(metadata),
|
||||
genres: fetchGenres(metadata),
|
||||
language: fetchLanguage(metadata),
|
||||
series: fetchSeries(metadata),
|
||||
sequence: fetchVolumeNumber(metadata)
|
||||
series: fetchSeries(metadata.meta),
|
||||
sequence: fetchVolumeNumber(metadata.meta),
|
||||
tags: fetchTags(metadata)
|
||||
}
|
||||
return data
|
||||
}
|
Loading…
Reference in New Issue
Block a user