mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-12-20 19:06:06 +01:00
157 lines
4.3 KiB
JavaScript
157 lines
4.3 KiB
JavaScript
const Path = require('path')
|
|
const dir = require('node-dir')
|
|
const Logger = require('../Logger')
|
|
const { cleanString } = require('./index')
|
|
|
|
const AUDIO_FORMATS = ['m4b', 'mp3', 'm4a']
|
|
const INFO_FORMATS = ['nfo']
|
|
const IMAGE_FORMATS = ['png', 'jpg', 'jpeg', 'webp']
|
|
const EBOOK_FORMATS = ['epub', 'pdf']
|
|
|
|
function getPaths(path) {
|
|
return new Promise((resolve) => {
|
|
dir.paths(path, function (err, res) {
|
|
if (err) {
|
|
console.error(err)
|
|
resolve(false)
|
|
}
|
|
resolve(res)
|
|
})
|
|
})
|
|
}
|
|
|
|
function getFileType(ext) {
|
|
var ext_cleaned = ext.toLowerCase()
|
|
if (ext_cleaned.startsWith('.')) ext_cleaned = ext_cleaned.slice(1)
|
|
if (AUDIO_FORMATS.includes(ext_cleaned)) return 'audio'
|
|
if (INFO_FORMATS.includes(ext_cleaned)) return 'info'
|
|
if (IMAGE_FORMATS.includes(ext_cleaned)) return 'image'
|
|
if (EBOOK_FORMATS.includes(ext_cleaned)) return 'ebook'
|
|
return 'unknown'
|
|
}
|
|
|
|
// Input relative filepath, output all details that can be parsed
|
|
function getAudiobookDataFromFilepath(abRootPath, relpath, parseSubtitle = false) {
|
|
var pathformat = Path.parse(relpath)
|
|
var path = pathformat.dir
|
|
|
|
if (!path) {
|
|
Logger.error('Ignoring file in root dir', relpath)
|
|
return null
|
|
}
|
|
|
|
// If relative file directory has 3 folders, then the middle folder will be series
|
|
var splitDir = path.split(Path.sep)
|
|
var author = null
|
|
if (splitDir.length > 1) author = splitDir.shift()
|
|
var series = null
|
|
if (splitDir.length > 1) series = splitDir.shift()
|
|
var title = splitDir.shift()
|
|
|
|
var publishYear = null
|
|
var subtitle = null
|
|
|
|
// If Title is of format 1999 - Title, then use 1999 as publish year
|
|
var publishYearMatch = title.match(/^([0-9]{4}) - (.+)/)
|
|
if (publishYearMatch && publishYearMatch.length > 2) {
|
|
if (!isNaN(publishYearMatch[1])) {
|
|
publishYear = publishYearMatch[1]
|
|
title = publishYearMatch[2]
|
|
}
|
|
}
|
|
|
|
if (parseSubtitle && title.includes(' - ')) {
|
|
var splitOnSubtitle = title.split(' - ')
|
|
title = splitOnSubtitle.shift()
|
|
subtitle = splitOnSubtitle.join(' - ')
|
|
}
|
|
|
|
return {
|
|
author,
|
|
title,
|
|
subtitle,
|
|
series,
|
|
publishYear,
|
|
path, // relative audiobook path i.e. /Author Name/Book Name/..
|
|
fullPath: Path.join(abRootPath, path) // i.e. /audiobook/Author Name/Book Name/..
|
|
}
|
|
}
|
|
|
|
async function getAllAudiobookFileData(abRootPath, serverSettings = {}) {
|
|
var parseSubtitle = !!serverSettings.scannerParseSubtitle
|
|
|
|
var paths = await getPaths(abRootPath)
|
|
var audiobooks = {}
|
|
|
|
paths.files.forEach((filepath) => {
|
|
var relpath = Path.normalize(filepath).replace(abRootPath, '').slice(1)
|
|
var parsed = Path.parse(relpath)
|
|
var path = parsed.dir
|
|
|
|
if (!audiobooks[path]) {
|
|
var audiobookData = getAudiobookDataFromFilepath(abRootPath, relpath, parseSubtitle)
|
|
if (!audiobookData) return
|
|
|
|
audiobooks[path] = {
|
|
...audiobookData,
|
|
audioFiles: [],
|
|
otherFiles: []
|
|
}
|
|
}
|
|
|
|
var fileObj = {
|
|
filetype: getFileType(parsed.ext),
|
|
filename: parsed.base,
|
|
path: relpath,
|
|
fullPath: filepath,
|
|
ext: parsed.ext
|
|
}
|
|
if (fileObj.filetype === 'audio') {
|
|
audiobooks[path].audioFiles.push(fileObj)
|
|
} else {
|
|
audiobooks[path].otherFiles.push(fileObj)
|
|
}
|
|
})
|
|
return Object.values(audiobooks)
|
|
}
|
|
module.exports.getAllAudiobookFileData = getAllAudiobookFileData
|
|
|
|
|
|
async function getAudiobookFileData(abRootPath, audiobookPath, serverSettings = {}) {
|
|
var parseSubtitle = !!serverSettings.scannerParseSubtitle
|
|
|
|
var paths = await getPaths(audiobookPath)
|
|
var audiobook = null
|
|
|
|
paths.files.forEach((filepath) => {
|
|
var relpath = Path.normalize(filepath).replace(abRootPath, '').slice(1)
|
|
|
|
if (!audiobook) {
|
|
var audiobookData = getAudiobookDataFromFilepath(abRootPath, relpath, parseSubtitle)
|
|
if (!audiobookData) return
|
|
|
|
audiobook = {
|
|
...audiobookData,
|
|
audioFiles: [],
|
|
otherFiles: []
|
|
}
|
|
}
|
|
|
|
var extname = Path.extname(filepath)
|
|
var basename = Path.basename(filepath)
|
|
var fileObj = {
|
|
filetype: getFileType(extname),
|
|
filename: basename,
|
|
path: relpath,
|
|
fullPath: filepath,
|
|
ext: extname
|
|
}
|
|
if (fileObj.filetype === 'audio') {
|
|
audiobook.audioFiles.push(fileObj)
|
|
} else {
|
|
audiobook.otherFiles.push(fileObj)
|
|
}
|
|
})
|
|
return audiobook
|
|
}
|
|
module.exports.getAudiobookFileData = getAudiobookFileData |