mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-08-25 13:35:44 +02:00
Update podcasts to new library item model
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
const uuidv4 = require('uuid').v4
|
||||
const fs = require('../libs/fsExtra')
|
||||
const Path = require('path')
|
||||
const Logger = require('../Logger')
|
||||
@@ -178,45 +177,6 @@ class LibraryItem {
|
||||
return this.libraryFiles.some((lf) => lf.fileType === 'audio')
|
||||
}
|
||||
|
||||
// Data comes from scandir library item data
|
||||
// TODO: Remove this function. Only used when creating a new podcast now
|
||||
setData(libraryMediaType, payload) {
|
||||
this.id = uuidv4()
|
||||
this.mediaType = libraryMediaType
|
||||
if (libraryMediaType === 'podcast') {
|
||||
this.media = new Podcast()
|
||||
} else {
|
||||
Logger.error(`[LibraryItem] setData called with unsupported media type "${libraryMediaType}"`)
|
||||
return
|
||||
}
|
||||
this.media.id = uuidv4()
|
||||
this.media.libraryItemId = this.id
|
||||
|
||||
for (const key in payload) {
|
||||
if (key === 'libraryFiles') {
|
||||
this.libraryFiles = payload.libraryFiles.map((lf) => lf.clone())
|
||||
|
||||
// Set cover image
|
||||
const imageFiles = this.libraryFiles.filter((lf) => lf.fileType === 'image')
|
||||
const coverMatch = imageFiles.find((iFile) => /\/cover\.[^.\/]*$/.test(iFile.metadata.path))
|
||||
if (coverMatch) {
|
||||
this.media.coverPath = coverMatch.metadata.path
|
||||
} else if (imageFiles.length) {
|
||||
this.media.coverPath = imageFiles[0].metadata.path
|
||||
}
|
||||
} else if (this[key] !== undefined && key !== 'media') {
|
||||
this[key] = payload[key]
|
||||
}
|
||||
}
|
||||
|
||||
if (payload.media) {
|
||||
this.media.setData(payload.media)
|
||||
}
|
||||
|
||||
this.addedAt = Date.now()
|
||||
this.updatedAt = Date.now()
|
||||
}
|
||||
|
||||
update(payload) {
|
||||
const json = this.toJSON()
|
||||
let hasUpdates = false
|
||||
|
@@ -6,8 +6,9 @@ const globals = require('../utils/globals')
|
||||
class PodcastEpisodeDownload {
|
||||
constructor() {
|
||||
this.id = null
|
||||
/** @type {import('../objects/entities/PodcastEpisode')} */
|
||||
this.podcastEpisode = null
|
||||
/** @type {import('../utils/podcastUtils').RssPodcastEpisode} */
|
||||
this.rssPodcastEpisode = null
|
||||
|
||||
this.url = null
|
||||
/** @type {import('../models/LibraryItem')} */
|
||||
this.libraryItem = null
|
||||
@@ -17,7 +18,7 @@ class PodcastEpisodeDownload {
|
||||
this.isFinished = false
|
||||
this.failed = false
|
||||
|
||||
this.appendEpisodeId = false
|
||||
this.appendRandomId = false
|
||||
|
||||
this.startedAt = null
|
||||
this.createdAt = null
|
||||
@@ -27,22 +28,22 @@ class PodcastEpisodeDownload {
|
||||
toJSONForClient() {
|
||||
return {
|
||||
id: this.id,
|
||||
episodeDisplayTitle: this.podcastEpisode?.title ?? null,
|
||||
episodeDisplayTitle: this.rssPodcastEpisode?.title ?? null,
|
||||
url: this.url,
|
||||
libraryItemId: this.libraryItemId,
|
||||
libraryId: this.libraryId || null,
|
||||
isFinished: this.isFinished,
|
||||
failed: this.failed,
|
||||
appendEpisodeId: this.appendEpisodeId,
|
||||
appendRandomId: this.appendRandomId,
|
||||
startedAt: this.startedAt,
|
||||
createdAt: this.createdAt,
|
||||
finishedAt: this.finishedAt,
|
||||
podcastTitle: this.libraryItem?.media.title ?? null,
|
||||
podcastExplicit: !!this.libraryItem?.media.explicit,
|
||||
season: this.podcastEpisode?.season ?? null,
|
||||
episode: this.podcastEpisode?.episode ?? null,
|
||||
episodeType: this.podcastEpisode?.episodeType ?? 'full',
|
||||
publishedAt: this.podcastEpisode?.publishedAt ?? null
|
||||
season: this.rssPodcastEpisode?.season ?? null,
|
||||
episode: this.rssPodcastEpisode?.episode ?? null,
|
||||
episodeType: this.rssPodcastEpisode?.episodeType ?? 'full',
|
||||
publishedAt: this.rssPodcastEpisode?.publishedAt ?? null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +57,7 @@ class PodcastEpisodeDownload {
|
||||
return 'mp3'
|
||||
}
|
||||
get enclosureType() {
|
||||
const enclosureType = this.podcastEpisode?.enclosure?.type
|
||||
const enclosureType = this.rssPodcastEpisode.enclosure.type
|
||||
return typeof enclosureType === 'string' ? enclosureType : null
|
||||
}
|
||||
/**
|
||||
@@ -69,10 +70,12 @@ class PodcastEpisodeDownload {
|
||||
if (this.enclosureType && !this.enclosureType.includes('mpeg')) return false
|
||||
return this.fileExtension === 'mp3'
|
||||
}
|
||||
|
||||
get episodeTitle() {
|
||||
return this.rssPodcastEpisode.title
|
||||
}
|
||||
get targetFilename() {
|
||||
const appendage = this.appendEpisodeId ? ` (${this.podcastEpisode.id})` : ''
|
||||
const filename = `${this.podcastEpisode.title}${appendage}.${this.fileExtension}`
|
||||
const appendage = this.appendRandomId ? ` (${uuidv4()})` : ''
|
||||
const filename = `${this.rssPodcastEpisode.title}${appendage}.${this.fileExtension}`
|
||||
return sanitizeFilename(filename)
|
||||
}
|
||||
get targetPath() {
|
||||
@@ -84,19 +87,23 @@ class PodcastEpisodeDownload {
|
||||
get libraryItemId() {
|
||||
return this.libraryItem?.id || null
|
||||
}
|
||||
get pubYear() {
|
||||
if (!this.rssPodcastEpisode.publishedAt) return null
|
||||
return new Date(this.rssPodcastEpisode.publishedAt).getFullYear()
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import('../objects/entities/PodcastEpisode')} podcastEpisode - old model
|
||||
* @param {import('../utils/podcastUtils').RssPodcastEpisode} rssPodcastEpisode - from rss feed
|
||||
* @param {import('../models/LibraryItem')} libraryItem
|
||||
* @param {*} isAutoDownload
|
||||
* @param {*} libraryId
|
||||
*/
|
||||
setData(podcastEpisode, libraryItem, isAutoDownload, libraryId) {
|
||||
setData(rssPodcastEpisode, libraryItem, isAutoDownload, libraryId) {
|
||||
this.id = uuidv4()
|
||||
this.podcastEpisode = podcastEpisode
|
||||
this.rssPodcastEpisode = rssPodcastEpisode
|
||||
|
||||
const url = podcastEpisode.enclosure.url
|
||||
const url = rssPodcastEpisode.enclosure.url
|
||||
if (decodeURIComponent(url) !== url) {
|
||||
// Already encoded
|
||||
this.url = url
|
||||
|
@@ -1,4 +1,3 @@
|
||||
const uuidv4 = require('uuid').v4
|
||||
const { areEquivalent, copyValue } = require('../../utils/index')
|
||||
const AudioFile = require('../files/AudioFile')
|
||||
const AudioTrack = require('../files/AudioTrack')
|
||||
@@ -127,27 +126,6 @@ class PodcastEpisode {
|
||||
get enclosureUrl() {
|
||||
return this.enclosure?.url || null
|
||||
}
|
||||
get pubYear() {
|
||||
if (!this.publishedAt) return null
|
||||
return new Date(this.publishedAt).getFullYear()
|
||||
}
|
||||
|
||||
setData(data, index = 1) {
|
||||
this.id = uuidv4()
|
||||
this.index = index
|
||||
this.title = data.title
|
||||
this.subtitle = data.subtitle || ''
|
||||
this.pubDate = data.pubDate || ''
|
||||
this.description = data.description || ''
|
||||
this.enclosure = data.enclosure ? { ...data.enclosure } : null
|
||||
this.guid = data.guid || null
|
||||
this.season = data.season || ''
|
||||
this.episode = data.episode || ''
|
||||
this.episodeType = data.episodeType || 'full'
|
||||
this.publishedAt = data.publishedAt || 0
|
||||
this.addedAt = Date.now()
|
||||
this.updatedAt = Date.now()
|
||||
}
|
||||
|
||||
update(payload) {
|
||||
let hasUpdates = false
|
||||
|
@@ -132,18 +132,6 @@ class Podcast {
|
||||
get numTracks() {
|
||||
return this.episodes.length
|
||||
}
|
||||
get latestEpisodePublished() {
|
||||
var largestPublishedAt = 0
|
||||
this.episodes.forEach((ep) => {
|
||||
if (ep.publishedAt && ep.publishedAt > largestPublishedAt) {
|
||||
largestPublishedAt = ep.publishedAt
|
||||
}
|
||||
})
|
||||
return largestPublishedAt
|
||||
}
|
||||
get episodesWithPubDate() {
|
||||
return this.episodes.filter((ep) => !!ep.publishedAt)
|
||||
}
|
||||
|
||||
update(payload) {
|
||||
var json = this.toJSON()
|
||||
@@ -178,34 +166,10 @@ class Podcast {
|
||||
return true
|
||||
}
|
||||
|
||||
setData(mediaData) {
|
||||
this.metadata = new PodcastMetadata()
|
||||
if (mediaData.metadata) {
|
||||
this.metadata.setData(mediaData.metadata)
|
||||
}
|
||||
|
||||
this.coverPath = mediaData.coverPath || null
|
||||
this.autoDownloadEpisodes = !!mediaData.autoDownloadEpisodes
|
||||
this.autoDownloadSchedule = mediaData.autoDownloadSchedule || global.ServerSettings.podcastEpisodeSchedule
|
||||
this.lastEpisodeCheck = Date.now() // Makes sure new episodes are after this
|
||||
}
|
||||
|
||||
checkHasEpisode(episodeId) {
|
||||
return this.episodes.some((ep) => ep.id === episodeId)
|
||||
}
|
||||
|
||||
addPodcastEpisode(podcastEpisode) {
|
||||
this.episodes.push(podcastEpisode)
|
||||
}
|
||||
|
||||
removeEpisode(episodeId) {
|
||||
const episode = this.episodes.find((ep) => ep.id === episodeId)
|
||||
if (episode) {
|
||||
this.episodes = this.episodes.filter((ep) => ep.id !== episodeId)
|
||||
}
|
||||
return episode
|
||||
}
|
||||
|
||||
getEpisode(episodeId) {
|
||||
if (!episodeId) return null
|
||||
|
||||
|
@@ -91,24 +91,6 @@ class PodcastMetadata {
|
||||
return getTitlePrefixAtEnd(this.title)
|
||||
}
|
||||
|
||||
setData(mediaMetadata = {}) {
|
||||
this.title = mediaMetadata.title || null
|
||||
this.author = mediaMetadata.author || null
|
||||
this.description = mediaMetadata.description || null
|
||||
this.releaseDate = mediaMetadata.releaseDate || null
|
||||
this.feedUrl = mediaMetadata.feedUrl || null
|
||||
this.imageUrl = mediaMetadata.imageUrl || null
|
||||
this.itunesPageUrl = mediaMetadata.itunesPageUrl || null
|
||||
this.itunesId = mediaMetadata.itunesId || null
|
||||
this.itunesArtistId = mediaMetadata.itunesArtistId || null
|
||||
this.explicit = !!mediaMetadata.explicit
|
||||
this.language = mediaMetadata.language || null
|
||||
this.type = mediaMetadata.type || null
|
||||
if (mediaMetadata.genres && mediaMetadata.genres.length) {
|
||||
this.genres = [...mediaMetadata.genres]
|
||||
}
|
||||
}
|
||||
|
||||
update(payload) {
|
||||
const json = this.toJSON()
|
||||
let hasUpdates = false
|
||||
|
Reference in New Issue
Block a user