Add:OPF file pulls ASIN and subtitle #1330

This commit is contained in:
advplyr 2023-01-02 10:47:13 -06:00
parent b1d4e28027
commit 591d8a8ab1
2 changed files with 38 additions and 25 deletions

View File

@ -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) {

View File

@ -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 &lt; and &gt; // calibre stores < and > as &lt; and &gt;
@ -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(/&quot;/g, '"')) const narratorsJSON = JSON.parse(fetchTagString(metadata.meta, "calibre:user_metadata:#narrators").replace(/&quot;/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),