mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-02-01 00:18:14 +01:00
Add:OPF file pulls ASIN and subtitle #1330
This commit is contained in:
parent
b1d4e28027
commit
591d8a8ab1
@ -228,31 +228,31 @@ class Book {
|
|||||||
|
|
||||||
// Look for desc.txt, reader.txt, metadata.abs and opf file then update details if found
|
// Look for desc.txt, reader.txt, metadata.abs and opf file then update details if found
|
||||||
async syncMetadataFiles(textMetadataFiles, opfMetadataOverrideDetails) {
|
async syncMetadataFiles(textMetadataFiles, opfMetadataOverrideDetails) {
|
||||||
var metadataUpdatePayload = {}
|
let metadataUpdatePayload = {}
|
||||||
var tagsUpdated = false
|
let tagsUpdated = false
|
||||||
|
|
||||||
var descTxt = textMetadataFiles.find(lf => lf.metadata.filename === 'desc.txt')
|
const descTxt = textMetadataFiles.find(lf => lf.metadata.filename === 'desc.txt')
|
||||||
if (descTxt) {
|
if (descTxt) {
|
||||||
var descriptionText = await readTextFile(descTxt.metadata.path)
|
const descriptionText = await readTextFile(descTxt.metadata.path)
|
||||||
if (descriptionText) {
|
if (descriptionText) {
|
||||||
Logger.debug(`[Book] "${this.metadata.title}" found desc.txt updating description with "${descriptionText.slice(0, 20)}..."`)
|
Logger.debug(`[Book] "${this.metadata.title}" found desc.txt updating description with "${descriptionText.slice(0, 20)}..."`)
|
||||||
metadataUpdatePayload.description = descriptionText
|
metadataUpdatePayload.description = descriptionText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var readerTxt = textMetadataFiles.find(lf => lf.metadata.filename === 'reader.txt')
|
const readerTxt = textMetadataFiles.find(lf => lf.metadata.filename === 'reader.txt')
|
||||||
if (readerTxt) {
|
if (readerTxt) {
|
||||||
var narratorText = await readTextFile(readerTxt.metadata.path)
|
const narratorText = await readTextFile(readerTxt.metadata.path)
|
||||||
if (narratorText) {
|
if (narratorText) {
|
||||||
Logger.debug(`[Book] "${this.metadata.title}" found reader.txt updating narrator with "${narratorText}"`)
|
Logger.debug(`[Book] "${this.metadata.title}" found reader.txt updating narrator with "${narratorText}"`)
|
||||||
metadataUpdatePayload.narrators = this.metadata.parseNarratorsTag(narratorText)
|
metadataUpdatePayload.narrators = this.metadata.parseNarratorsTag(narratorText)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var metadataAbs = textMetadataFiles.find(lf => lf.metadata.filename === 'metadata.abs')
|
const metadataAbs = textMetadataFiles.find(lf => lf.metadata.filename === 'metadata.abs')
|
||||||
if (metadataAbs) {
|
if (metadataAbs) {
|
||||||
Logger.debug(`[Book] Found metadata.abs file for "${this.metadata.title}"`)
|
Logger.debug(`[Book] Found metadata.abs file for "${this.metadata.title}"`)
|
||||||
var metadataText = await readTextFile(metadataAbs.metadata.path)
|
const metadataText = await readTextFile(metadataAbs.metadata.path)
|
||||||
var abmetadataUpdates = abmetadataGenerator.parseAndCheckForUpdates(metadataText, this.metadata, 'book')
|
const abmetadataUpdates = abmetadataGenerator.parseAndCheckForUpdates(metadataText, this.metadata, 'book')
|
||||||
if (abmetadataUpdates && Object.keys(abmetadataUpdates).length) {
|
if (abmetadataUpdates && Object.keys(abmetadataUpdates).length) {
|
||||||
Logger.debug(`[Book] "${this.metadata.title}" changes found in metadata.abs file`, abmetadataUpdates)
|
Logger.debug(`[Book] "${this.metadata.title}" changes found in metadata.abs file`, abmetadataUpdates)
|
||||||
metadataUpdatePayload = {
|
metadataUpdatePayload = {
|
||||||
@ -262,11 +262,11 @@ class Book {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var metadataOpf = textMetadataFiles.find(lf => lf.isOPFFile || lf.metadata.filename === 'metadata.xml')
|
const metadataOpf = textMetadataFiles.find(lf => lf.isOPFFile || lf.metadata.filename === 'metadata.xml')
|
||||||
if (metadataOpf) {
|
if (metadataOpf) {
|
||||||
var xmlText = await readTextFile(metadataOpf.metadata.path)
|
const xmlText = await readTextFile(metadataOpf.metadata.path)
|
||||||
if (xmlText) {
|
if (xmlText) {
|
||||||
var opfMetadata = await parseOpfMetadataXML(xmlText)
|
const opfMetadata = await parseOpfMetadataXML(xmlText)
|
||||||
if (opfMetadata) {
|
if (opfMetadata) {
|
||||||
for (const key in opfMetadata) {
|
for (const key in opfMetadata) {
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ const htmlSanitizer = require('../htmlSanitizer')
|
|||||||
|
|
||||||
function parseCreators(metadata) {
|
function parseCreators(metadata) {
|
||||||
if (!metadata['dc:creator']) return null
|
if (!metadata['dc:creator']) return null
|
||||||
var creators = metadata['dc:creator']
|
const creators = metadata['dc:creator']
|
||||||
if (!creators.length) return null
|
if (!creators.length) return null
|
||||||
return creators.map(c => {
|
return creators.map(c => {
|
||||||
if (typeof c !== 'object' || !c['$'] || !c['_']) return false
|
if (typeof c !== 'object' || !c['$'] || !c['_']) return false
|
||||||
@ -22,15 +22,15 @@ function fetchCreators(creators, role) {
|
|||||||
|
|
||||||
function fetchTagString(metadata, tag) {
|
function fetchTagString(metadata, tag) {
|
||||||
if (!metadata[tag] || !metadata[tag].length) return null
|
if (!metadata[tag] || !metadata[tag].length) return null
|
||||||
var tag = metadata[tag][0]
|
const value = metadata[tag][0]
|
||||||
if (typeof tag !== 'string') return null
|
if (typeof value !== 'string') return null
|
||||||
return tag
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchDate(metadata) {
|
function fetchDate(metadata) {
|
||||||
var date = fetchTagString(metadata, 'dc:date')
|
const date = fetchTagString(metadata, 'dc:date')
|
||||||
if (!date) return null
|
if (!date) return null
|
||||||
var dateSplit = date.split('-')
|
const dateSplit = date.split('-')
|
||||||
if (!dateSplit.length || dateSplit[0].length !== 4 || isNaN(dateSplit[0])) return null
|
if (!dateSplit.length || dateSplit[0].length !== 4 || isNaN(dateSplit[0])) return null
|
||||||
return dateSplit[0]
|
return dateSplit[0]
|
||||||
}
|
}
|
||||||
@ -41,17 +41,28 @@ function fetchPublisher(metadata) {
|
|||||||
|
|
||||||
function fetchISBN(metadata) {
|
function fetchISBN(metadata) {
|
||||||
if (!metadata['dc:identifier'] || !metadata['dc:identifier'].length) return null
|
if (!metadata['dc:identifier'] || !metadata['dc:identifier'].length) return null
|
||||||
var identifiers = metadata['dc:identifier']
|
const identifiers = metadata['dc:identifier']
|
||||||
var isbnObj = identifiers.find(i => i['$'] && i['$']['opf:scheme'] === 'ISBN')
|
const isbnObj = identifiers.find(i => i['$'] && i['$']['opf:scheme'] === 'ISBN')
|
||||||
return isbnObj ? isbnObj['_'] || null : null
|
return isbnObj ? isbnObj['_'] || null : null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fetchASIN(metadata) {
|
||||||
|
if (!metadata['dc:identifier'] || !metadata['dc:identifier'].length) return null
|
||||||
|
const identifiers = metadata['dc:identifier']
|
||||||
|
const asinObj = identifiers.find(i => i['$'] && i['$']['opf:scheme'] === 'ASIN')
|
||||||
|
return asinObj ? asinObj['_'] || null : null
|
||||||
|
}
|
||||||
|
|
||||||
function fetchTitle(metadata) {
|
function fetchTitle(metadata) {
|
||||||
return fetchTagString(metadata, 'dc:title')
|
return fetchTagString(metadata, 'dc:title')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fetchSubtitle(metadata) {
|
||||||
|
return fetchTagString(metadata, 'dc:subtitle')
|
||||||
|
}
|
||||||
|
|
||||||
function fetchDescription(metadata) {
|
function fetchDescription(metadata) {
|
||||||
var description = fetchTagString(metadata, 'dc:description')
|
let description = fetchTagString(metadata, 'dc:description')
|
||||||
if (!description) return null
|
if (!description) return null
|
||||||
// check if description is HTML or plain text. only plain text allowed
|
// check if description is HTML or plain text. only plain text allowed
|
||||||
// calibre stores < and > as < and >
|
// calibre stores < and > as < and >
|
||||||
@ -79,10 +90,10 @@ function fetchVolumeNumber(metadataMeta) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function fetchNarrators(creators, metadata) {
|
function fetchNarrators(creators, metadata) {
|
||||||
var narrators = fetchCreators(creators, 'nrt')
|
const narrators = fetchCreators(creators, 'nrt')
|
||||||
if (typeof metadata.meta == "undefined" || narrators.length) return narrators
|
if (typeof metadata.meta == "undefined" || narrators.length) return narrators
|
||||||
try {
|
try {
|
||||||
var narratorsJSON = JSON.parse(fetchTagString(metadata.meta, "calibre:user_metadata:#narrators").replace(/"/g, '"'))
|
const narratorsJSON = JSON.parse(fetchTagString(metadata.meta, "calibre:user_metadata:#narrators").replace(/"/g, '"'))
|
||||||
return narratorsJSON["#value#"]
|
return narratorsJSON["#value#"]
|
||||||
} catch {
|
} catch {
|
||||||
return null
|
return null
|
||||||
@ -100,7 +111,7 @@ function stripPrefix(str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports.parseOpfMetadataXML = async (xml) => {
|
module.exports.parseOpfMetadataXML = async (xml) => {
|
||||||
var json = await xmlToJSON(xml)
|
const json = await xmlToJSON(xml)
|
||||||
|
|
||||||
if (!json) return null
|
if (!json) return null
|
||||||
|
|
||||||
@ -108,7 +119,7 @@ module.exports.parseOpfMetadataXML = async (xml) => {
|
|||||||
const packageKey = Object.keys(json).find(key => stripPrefix(key) === 'package')
|
const packageKey = Object.keys(json).find(key => stripPrefix(key) === 'package')
|
||||||
if (!packageKey) return null
|
if (!packageKey) return null
|
||||||
const prefix = packageKey.split(':').shift()
|
const prefix = packageKey.split(':').shift()
|
||||||
var metadata = prefix ? json[packageKey][`${prefix}:metadata`] || json[packageKey].metadata : json[packageKey].metadata
|
let metadata = prefix ? json[packageKey][`${prefix}:metadata`] || json[packageKey].metadata : json[packageKey].metadata
|
||||||
if (!metadata) return null
|
if (!metadata) return null
|
||||||
|
|
||||||
if (Array.isArray(metadata)) {
|
if (Array.isArray(metadata)) {
|
||||||
@ -132,11 +143,13 @@ module.exports.parseOpfMetadataXML = async (xml) => {
|
|||||||
const narrators = (fetchNarrators(creators, metadata) || []).filter(nrt => nrt && nrt.trim())
|
const narrators = (fetchNarrators(creators, metadata) || []).filter(nrt => nrt && nrt.trim())
|
||||||
const data = {
|
const data = {
|
||||||
title: fetchTitle(metadata),
|
title: fetchTitle(metadata),
|
||||||
|
subtitle: fetchSubtitle(metadata),
|
||||||
authors,
|
authors,
|
||||||
narrators,
|
narrators,
|
||||||
publishedYear: fetchDate(metadata),
|
publishedYear: fetchDate(metadata),
|
||||||
publisher: fetchPublisher(metadata),
|
publisher: fetchPublisher(metadata),
|
||||||
isbn: fetchISBN(metadata),
|
isbn: fetchISBN(metadata),
|
||||||
|
asin: fetchASIN(metadata),
|
||||||
description: fetchDescription(metadata),
|
description: fetchDescription(metadata),
|
||||||
genres: fetchGenres(metadata),
|
genres: fetchGenres(metadata),
|
||||||
language: fetchLanguage(metadata),
|
language: fetchLanguage(metadata),
|
||||||
|
Loading…
Reference in New Issue
Block a user