Add logs when sanitizing filename and update podcast episode download to set targetFilename on init #4121

This commit is contained in:
advplyr 2025-03-19 17:39:23 -05:00
parent 7d0f61663e
commit 92bb3527de
3 changed files with 32 additions and 6 deletions

View File

@ -108,7 +108,7 @@ class PodcastManager {
// e.g. "/tagesschau 20 Uhr.mp3" becomes "/tagesschau 20 Uhr (ep_asdfasdf).mp3"
// this handles podcasts where every title is the same (ref https://github.com/advplyr/audiobookshelf/issues/1802)
if (await fs.pathExists(this.currentDownload.targetPath)) {
this.currentDownload.appendRandomId = true
this.currentDownload.setAppendRandomId(true)
}
// Ignores all added files to this dir

View File

@ -20,6 +20,8 @@ class PodcastEpisodeDownload {
this.appendRandomId = false
this.targetFilename = null
this.startedAt = null
this.createdAt = null
this.finishedAt = null
@ -74,11 +76,6 @@ class PodcastEpisodeDownload {
get episodeTitle() {
return this.rssPodcastEpisode.title
}
get targetFilename() {
const appendage = this.appendRandomId ? ` (${this.id})` : ''
const filename = `${this.rssPodcastEpisode.title}${appendage}.${this.fileExtension}`
return sanitizeFilename(filename)
}
get targetPath() {
return filePathToPOSIX(Path.join(this.libraryItem.path, this.targetFilename))
}
@ -93,6 +90,23 @@ class PodcastEpisodeDownload {
return new Date(this.rssPodcastEpisode.publishedAt).getFullYear()
}
/**
* @param {string} title
*/
getSanitizedFilename(title) {
const appendage = this.appendRandomId ? ` (${this.id})` : ''
const filename = `${title.trim()}${appendage}.${this.fileExtension}`
return sanitizeFilename(filename)
}
/**
* @param {boolean} appendRandomId
*/
setAppendRandomId(appendRandomId) {
this.appendRandomId = appendRandomId
this.targetFilename = this.getSanitizedFilename(this.rssPodcastEpisode.title || '')
}
/**
*
* @param {import('../utils/podcastUtils').RssPodcastEpisode} rssPodcastEpisode - from rss feed
@ -112,6 +126,8 @@ class PodcastEpisodeDownload {
this.url = encodeURI(url)
}
this.targetFilename = this.getSanitizedFilename(this.rssPodcastEpisode.title || '')
this.libraryItem = libraryItem
this.isAutoDownload = isAutoDownload
this.createdAt = Date.now()

View File

@ -362,6 +362,9 @@ module.exports.sanitizeFilename = (filename, colonReplacement = ' - ') => {
return false
}
// Normalize the string first to ensure consistent byte calculations
filename = filename.normalize('NFC')
// Most file systems use number of bytes for max filename
// to support most filesystems we will use max of 255 bytes in utf-16
// Ref: https://doc.owncloud.com/server/next/admin_manual/troubleshooting/path_filename_length.html
@ -390,8 +393,11 @@ module.exports.sanitizeFilename = (filename, colonReplacement = ' - ') => {
const ext = Path.extname(sanitized) // separate out file extension
const basename = Path.basename(sanitized, ext)
const extByteLength = Buffer.byteLength(ext, 'utf16le')
const basenameByteLength = Buffer.byteLength(basename, 'utf16le')
if (basenameByteLength + extByteLength > MAX_FILENAME_BYTES) {
Logger.debug(`[fileUtils] Filename "${filename}" is too long (${basenameByteLength + extByteLength} bytes), trimming basename to ${MAX_FILENAME_BYTES - extByteLength} bytes.`)
const MaxBytesForBasename = MAX_FILENAME_BYTES - extByteLength
let totalBytes = 0
let trimmedBasename = ''
@ -407,6 +413,10 @@ module.exports.sanitizeFilename = (filename, colonReplacement = ' - ') => {
sanitized = trimmedBasename + ext
}
if (filename !== sanitized) {
Logger.debug(`[fileUtils] Sanitized filename "${filename}" to "${sanitized}" (${Buffer.byteLength(sanitized, 'utf16le')} bytes)`)
}
return sanitized
}