mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-12-28 22:59:38 +00:00
Add support to custom episode cover art
This commit is contained in:
parent
0c7b738b7c
commit
f703fb60da
16 changed files with 446 additions and 20 deletions
|
|
@ -39,6 +39,8 @@ class FeedEpisode extends Model {
|
|||
this.filePath
|
||||
/** @type {boolean} */
|
||||
this.explicit
|
||||
/** @type {string} */
|
||||
this.episodeCoverURL
|
||||
/** @type {UUIDV4} */
|
||||
this.feedId
|
||||
/** @type {Date} */
|
||||
|
|
@ -57,6 +59,12 @@ class FeedEpisode extends Model {
|
|||
*/
|
||||
static getFeedEpisodeObjFromPodcastEpisode(libraryItemExpanded, feed, slug, episode, existingEpisodeId = null) {
|
||||
const episodeId = existingEpisodeId || uuidv4()
|
||||
|
||||
let episodeCoverURL = null
|
||||
if (episode.coverPath) {
|
||||
episodeCoverURL = `/api/podcasts/${libraryItemExpanded.id}/episode/${episode.id}/cover`
|
||||
}
|
||||
|
||||
return {
|
||||
id: episodeId,
|
||||
title: episode.title,
|
||||
|
|
@ -73,6 +81,7 @@ class FeedEpisode extends Model {
|
|||
duration: episode.audioFile.duration,
|
||||
filePath: episode.audioFile.metadata.path,
|
||||
explicit: libraryItemExpanded.media.explicit,
|
||||
episodeCoverURL,
|
||||
feedId: feed.id
|
||||
}
|
||||
}
|
||||
|
|
@ -106,7 +115,7 @@ class FeedEpisode extends Model {
|
|||
feedEpisodeObjs.push(this.getFeedEpisodeObjFromPodcastEpisode(libraryItemExpanded, feed, slug, episode, existingEpisode?.id))
|
||||
}
|
||||
Logger.info(`[FeedEpisode] Upserting ${feedEpisodeObjs.length} episodes for feed ${feed.id} (${numExisting} existing)`)
|
||||
return this.bulkCreate(feedEpisodeObjs, { transaction, updateOnDuplicate: ['title', 'author', 'description', 'siteURL', 'enclosureURL', 'enclosureType', 'enclosureSize', 'pubDate', 'season', 'episode', 'episodeType', 'duration', 'filePath', 'explicit'] })
|
||||
return this.bulkCreate(feedEpisodeObjs, { transaction, updateOnDuplicate: ['title', 'author', 'description', 'siteURL', 'enclosureURL', 'enclosureType', 'enclosureSize', 'pubDate', 'season', 'episode', 'episodeType', 'duration', 'filePath', 'explicit', 'episodeCoverURL'] })
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -203,7 +212,7 @@ class FeedEpisode extends Model {
|
|||
feedEpisodeObjs.push(this.getFeedEpisodeObjFromAudiobookTrack(libraryItemExpanded.media, libraryItemExpanded.createdAt, feed, slug, track, useChapterTitles, i, existingEpisode?.id))
|
||||
}
|
||||
Logger.info(`[FeedEpisode] Upserting ${feedEpisodeObjs.length} episodes for feed ${feed.id} (${numExisting} existing)`)
|
||||
return this.bulkCreate(feedEpisodeObjs, { transaction, updateOnDuplicate: ['title', 'author', 'description', 'siteURL', 'enclosureURL', 'enclosureType', 'enclosureSize', 'pubDate', 'season', 'episode', 'episodeType', 'duration', 'filePath', 'explicit'] })
|
||||
return this.bulkCreate(feedEpisodeObjs, { transaction, updateOnDuplicate: ['title', 'author', 'description', 'siteURL', 'enclosureURL', 'enclosureType', 'enclosureSize', 'pubDate', 'season', 'episode', 'episodeType', 'duration', 'filePath', 'explicit', 'episodeCoverURL'] })
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -240,7 +249,7 @@ class FeedEpisode extends Model {
|
|||
}
|
||||
}
|
||||
Logger.info(`[FeedEpisode] Upserting ${feedEpisodeObjs.length} episodes for feed ${feed.id} (${numExisting} existing)`)
|
||||
return this.bulkCreate(feedEpisodeObjs, { transaction, updateOnDuplicate: ['title', 'author', 'description', 'siteURL', 'enclosureURL', 'enclosureType', 'enclosureSize', 'pubDate', 'season', 'episode', 'episodeType', 'duration', 'filePath', 'explicit'] })
|
||||
return this.bulkCreate(feedEpisodeObjs, { transaction, updateOnDuplicate: ['title', 'author', 'description', 'siteURL', 'enclosureURL', 'enclosureType', 'enclosureSize', 'pubDate', 'season', 'episode', 'episodeType', 'duration', 'filePath', 'explicit', 'episodeCoverURL'] })
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -268,7 +277,8 @@ class FeedEpisode extends Model {
|
|||
episodeType: DataTypes.STRING,
|
||||
duration: DataTypes.FLOAT,
|
||||
filePath: DataTypes.STRING,
|
||||
explicit: DataTypes.BOOLEAN
|
||||
explicit: DataTypes.BOOLEAN,
|
||||
episodeCoverURL: DataTypes.STRING
|
||||
},
|
||||
{
|
||||
sequelize,
|
||||
|
|
@ -328,6 +338,9 @@ class FeedEpisode extends Model {
|
|||
if (this.description) {
|
||||
customElements.push({ 'itunes:summary': { _cdata: this.description } })
|
||||
}
|
||||
if (this.episodeCoverURL) {
|
||||
customElements.push({ 'itunes:image': { _attr: { href: `${hostPrefix}${this.episodeCoverURL}` } } })
|
||||
}
|
||||
|
||||
return {
|
||||
title: this.title,
|
||||
|
|
|
|||
|
|
@ -45,6 +45,10 @@ class PodcastEpisode extends Model {
|
|||
/** @type {Object} */
|
||||
this.extraData
|
||||
/** @type {string} */
|
||||
this.coverPath
|
||||
/** @type {string} */
|
||||
this.imageURL
|
||||
/** @type {string} */
|
||||
this.podcastId
|
||||
/** @type {Date} */
|
||||
this.createdAt
|
||||
|
|
@ -75,7 +79,8 @@ class PodcastEpisode extends Model {
|
|||
podcastId,
|
||||
audioFile: audioFile.toJSON(),
|
||||
chapters: [],
|
||||
extraData: {}
|
||||
extraData: {},
|
||||
imageURL: rssPodcastEpisode.image || null
|
||||
}
|
||||
if (rssPodcastEpisode.guid) {
|
||||
podcastEpisode.extraData.guid = rssPodcastEpisode.guid
|
||||
|
|
@ -117,7 +122,9 @@ class PodcastEpisode extends Model {
|
|||
|
||||
audioFile: DataTypes.JSON,
|
||||
chapters: DataTypes.JSON,
|
||||
extraData: DataTypes.JSON
|
||||
extraData: DataTypes.JSON,
|
||||
coverPath: DataTypes.STRING,
|
||||
imageURL: DataTypes.STRING
|
||||
},
|
||||
{
|
||||
sequelize,
|
||||
|
|
@ -158,6 +165,22 @@ class PodcastEpisode extends Model {
|
|||
return this.audioFile?.duration || 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if episode has a custom cover
|
||||
* @returns {boolean}
|
||||
*/
|
||||
hasCover() {
|
||||
return !!this.coverPath
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cover path for this episode
|
||||
* @returns {string|null}
|
||||
*/
|
||||
getCoverPath() {
|
||||
return this.coverPath || null
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for matching the episode with an episode in the RSS feed
|
||||
*
|
||||
|
|
@ -223,7 +246,9 @@ class PodcastEpisode extends Model {
|
|||
audioFile: structuredClone(this.audioFile),
|
||||
publishedAt: this.publishedAt?.valueOf() || null,
|
||||
addedAt: this.createdAt.valueOf(),
|
||||
updatedAt: this.updatedAt.valueOf()
|
||||
updatedAt: this.updatedAt.valueOf(),
|
||||
coverPath: this.coverPath || null,
|
||||
imageURL: this.imageURL || null
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue