2024-01-15 00:51:26 +01:00
|
|
|
const Path = require('path')
|
|
|
|
const Logger = require('../../Logger')
|
|
|
|
const parseComicInfoMetadata = require('./parseComicInfoMetadata')
|
2024-09-18 21:26:10 +02:00
|
|
|
const globals = require('../globals')
|
|
|
|
const { xmlToJSON } = require('../index')
|
2024-09-18 07:28:15 +02:00
|
|
|
const { createComicBookExtractor } = require('../comicBookExtractors.js')
|
2024-01-15 00:51:26 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Extract cover image from comic return true if success
|
2024-08-20 06:00:16 +02:00
|
|
|
*
|
|
|
|
* @param {string} comicPath
|
|
|
|
* @param {string} comicImageFilepath
|
|
|
|
* @param {string} outputCoverPath
|
2024-01-15 00:51:26 +01:00
|
|
|
* @returns {Promise<boolean>}
|
|
|
|
*/
|
|
|
|
async function extractCoverImage(comicPath, comicImageFilepath, outputCoverPath) {
|
2024-09-15 10:48:33 +02:00
|
|
|
let archive = null
|
|
|
|
try {
|
2024-09-18 07:28:15 +02:00
|
|
|
archive = createComicBookExtractor(comicPath)
|
|
|
|
await archive.open()
|
|
|
|
return await archive.extractToFile(comicImageFilepath, outputCoverPath)
|
2024-01-15 00:51:26 +01:00
|
|
|
} catch (error) {
|
2024-09-15 10:48:33 +02:00
|
|
|
Logger.error(`[parseComicMetadata] Failed to extract image "${comicImageFilepath}" from comicPath "${comicPath}" into "${outputCoverPath}"`, error)
|
2024-01-15 00:51:26 +01:00
|
|
|
return false
|
2024-08-20 07:05:25 +02:00
|
|
|
} finally {
|
|
|
|
// Ensure we free the memory
|
2024-09-15 10:48:33 +02:00
|
|
|
archive?.close()
|
2024-01-15 00:51:26 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
module.exports.extractCoverImage = extractCoverImage
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Parse metadata from comic
|
2024-08-20 06:00:16 +02:00
|
|
|
*
|
|
|
|
* @param {import('../../models/Book').EBookFileObject} ebookFile
|
2024-01-15 00:51:26 +01:00
|
|
|
* @returns {Promise<import('./parseEbookMetadata').EBookFileScanData>}
|
|
|
|
*/
|
|
|
|
async function parse(ebookFile) {
|
|
|
|
const comicPath = ebookFile.metadata.path
|
2024-09-18 07:28:15 +02:00
|
|
|
Logger.debug(`[parseComicMetadata] Parsing comic metadata at "${comicPath}"`)
|
2024-09-15 10:48:33 +02:00
|
|
|
let archive = null
|
|
|
|
try {
|
2024-09-18 07:28:15 +02:00
|
|
|
archive = createComicBookExtractor(comicPath)
|
|
|
|
await archive.open()
|
2024-01-15 00:51:26 +01:00
|
|
|
|
2024-09-18 07:28:15 +02:00
|
|
|
const filePaths = await archive.getFilePaths()
|
2024-01-15 00:51:26 +01:00
|
|
|
|
2024-09-18 07:28:15 +02:00
|
|
|
// Sort the file paths in a natural order to get the first image
|
|
|
|
filePaths.sort((a, b) => {
|
|
|
|
return a.localeCompare(b, undefined, {
|
2024-09-15 10:48:33 +02:00
|
|
|
numeric: true,
|
|
|
|
sensitivity: 'base'
|
|
|
|
})
|
2024-01-15 00:51:26 +01:00
|
|
|
})
|
|
|
|
|
2024-09-15 10:48:33 +02:00
|
|
|
let metadata = null
|
2024-09-18 07:28:15 +02:00
|
|
|
const comicInfoPath = filePaths.find((filePath) => filePath === 'ComicInfo.xml')
|
|
|
|
if (comicInfoPath) {
|
|
|
|
const comicInfoData = await archive.extractToBuffer(comicInfoPath)
|
|
|
|
if (comicInfoData) {
|
|
|
|
const comicInfoStr = new TextDecoder().decode(comicInfoData)
|
2024-09-15 10:48:33 +02:00
|
|
|
const comicInfoJson = await xmlToJSON(comicInfoStr)
|
|
|
|
if (comicInfoJson) {
|
|
|
|
metadata = parseComicInfoMetadata.parse(comicInfoJson)
|
|
|
|
}
|
2024-01-15 00:51:26 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-15 10:48:33 +02:00
|
|
|
const payload = {
|
|
|
|
path: comicPath,
|
|
|
|
ebookFormat: ebookFile.ebookFormat,
|
|
|
|
metadata
|
|
|
|
}
|
2024-01-15 00:51:26 +01:00
|
|
|
|
2024-09-18 07:28:15 +02:00
|
|
|
const firstImagePath = filePaths.find((filePath) => globals.SupportedImageTypes.includes(Path.extname(filePath).toLowerCase().slice(1)))
|
|
|
|
if (firstImagePath) {
|
|
|
|
payload.ebookCoverPath = firstImagePath
|
2024-09-15 10:48:33 +02:00
|
|
|
} else {
|
|
|
|
Logger.warn(`[parseComicMetadata] Cover image not found in comic at "${comicPath}"`)
|
|
|
|
}
|
2024-08-20 07:05:25 +02:00
|
|
|
|
2024-09-15 10:48:33 +02:00
|
|
|
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()
|
|
|
|
}
|
2024-01-15 00:51:26 +01:00
|
|
|
}
|
2024-08-20 06:00:16 +02:00
|
|
|
module.exports.parse = parse
|