Skip to content

Commit

Permalink
catch file extraction errors in parseComicMetadata
Browse files Browse the repository at this point in the history
  • Loading branch information
mikiher committed Sep 15, 2024
1 parent b35fabb commit 0b31792
Showing 1 changed file with 51 additions and 43 deletions.
94 changes: 51 additions & 43 deletions server/utils/parsers/parseComicMetadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ const parseComicInfoMetadata = require('./parseComicInfoMetadata')
*/
async function getComicFileBuffer(filepath) {
if (!(await fs.pathExists(filepath))) {
Logger.error(`Comic path does not exist "${filepath}"`)
Logger.error(`[parseComicMetadata] Comic path does not exist "${filepath}"`)
return null
}
try {
return fs.readFile(filepath)
} catch (error) {
Logger.error(`Failed to read comic at "${filepath}"`, error)
Logger.error(`[parseComicMetadata] Failed to read comic at "${filepath}"`, error)
return null
}
}
Expand All @@ -36,23 +36,25 @@ async function extractCoverImage(comicPath, comicImageFilepath, outputCoverPath)
const comicFileBuffer = await getComicFileBuffer(comicPath)
if (!comicFileBuffer) return null

const archive = await Archive.open(comicFileBuffer)
const fileEntry = await archive.extractSingleFile(comicImageFilepath)
let archive = null
try {
archive = await Archive.open(comicFileBuffer)
const fileEntry = await archive.extractSingleFile(comicImageFilepath)

if (!fileEntry?.fileData) {
Logger.error(`[parseComicMetadata] Invalid file entry data for comicPath "${comicPath}"/${comicImageFilepath}`)
return false
}
if (!fileEntry?.fileData) {
Logger.error(`[parseComicMetadata] Invalid file entry data for comicPath "${comicPath}"/${comicImageFilepath}`)
return false
}

try {
await fs.writeFile(outputCoverPath, fileEntry.fileData)

return true
} catch (error) {
Logger.error(`[parseComicMetadata] Failed to extract image from comicPath "${comicPath}"`, error)
Logger.error(`[parseComicMetadata] Failed to extract image "${comicImageFilepath}" from comicPath "${comicPath}" into "${outputCoverPath}"`, error)
return false
} finally {
// Ensure we free the memory
archive.close()
archive?.close()
}
}
module.exports.extractCoverImage = extractCoverImage
Expand All @@ -70,46 +72,52 @@ async function parse(ebookFile) {
const comicFileBuffer = await getComicFileBuffer(comicPath)
if (!comicFileBuffer) return null

const archive = await Archive.open(comicFileBuffer)
let archive = null
try {
archive = await Archive.open(comicFileBuffer)

const fileObjects = await archive.getFilesArray()
const fileObjects = await archive.getFilesArray()

fileObjects.sort((a, b) => {
return a.file.name.localeCompare(b.file.name, undefined, {
numeric: true,
sensitivity: 'base'
fileObjects.sort((a, b) => {
return a.file.name.localeCompare(b.file.name, undefined, {
numeric: true,
sensitivity: 'base'
})
})
})

let metadata = null
const comicInfo = fileObjects.find((fo) => fo.file.name === 'ComicInfo.xml')
if (comicInfo) {
const comicInfoEntry = await comicInfo.file.extract()
if (comicInfoEntry?.fileData) {
const comicInfoStr = new TextDecoder().decode(comicInfoEntry.fileData)
const comicInfoJson = await xmlToJSON(comicInfoStr)
if (comicInfoJson) {
metadata = parseComicInfoMetadata.parse(comicInfoJson)
let metadata = null
const comicInfo = fileObjects.find((fo) => fo.file.name === 'ComicInfo.xml')
if (comicInfo) {
const comicInfoEntry = await comicInfo.file.extract()
if (comicInfoEntry?.fileData) {
const comicInfoStr = new TextDecoder().decode(comicInfoEntry.fileData)
const comicInfoJson = await xmlToJSON(comicInfoStr)
if (comicInfoJson) {
metadata = parseComicInfoMetadata.parse(comicInfoJson)
}
}
}
}

const payload = {
path: comicPath,
ebookFormat: ebookFile.ebookFormat,
metadata
}

const firstImage = fileObjects.find((fo) => globals.SupportedImageTypes.includes(Path.extname(fo.file.name).toLowerCase().slice(1)))
if (firstImage?.file?._path) {
payload.ebookCoverPath = firstImage.file._path
} else {
Logger.warn(`Cover image not found in comic at "${comicPath}"`)
}
const payload = {
path: comicPath,
ebookFormat: ebookFile.ebookFormat,
metadata
}

// Ensure we close the archive to free memory
archive.close()
const firstImage = fileObjects.find((fo) => globals.SupportedImageTypes.includes(Path.extname(fo.file.name).toLowerCase().slice(1)))
if (firstImage?.file?._path) {
payload.ebookCoverPath = firstImage.file._path
} else {
Logger.warn(`[parseComicMetadata] Cover image not found in comic at "${comicPath}"`)
}

return payload
return payload
} catch (error) {
Logger.error(`[parseComicMetadata] Failed to parse comic metadata at "${comicPath}"`, error)
return null
} finally {
// Ensure we free the memory
archive?.close()
}
}
module.exports.parse = parse

0 comments on commit 0b31792

Please sign in to comment.