Add support to podcast type

This commit is contained in:
mfcar 2023-02-22 18:22:52 +00:00
parent 8c84640484
commit b1ee54522a
No known key found for this signature in database
16 changed files with 77 additions and 22 deletions

View File

@ -39,6 +39,11 @@
</div> </div>
</div> </div>
</div> </div>
<div class="flex mt-2 -mx-1">
<div class="w-1/4 px-1">
<ui-dropdown :label="$strings.LabelPodcastType" v-model="details.type" :items="podcastTypes" small class="max-w-52" />
</div>
</div>
</form> </form>
</div> </div>
</template> </template>
@ -65,7 +70,8 @@ export default {
itunesId: null, itunesId: null,
itunesArtistId: null, itunesArtistId: null,
explicit: false, explicit: false,
language: null language: null,
type: null
}, },
newTags: [] newTags: []
} }
@ -93,7 +99,10 @@ export default {
}, },
filterData() { filterData() {
return this.$store.state.libraries.filterData || {} return this.$store.state.libraries.filterData || {}
} },
podcastTypes() {
return this.$store.state.globals.podcastTypes || []
},
}, },
methods: { methods: {
getDetails() { getDetails() {
@ -219,6 +228,7 @@ export default {
this.details.itunesArtistId = this.mediaMetadata.itunesArtistId || '' this.details.itunesArtistId = this.mediaMetadata.itunesArtistId || ''
this.details.language = this.mediaMetadata.language || '' this.details.language = this.mediaMetadata.language || ''
this.details.explicit = !!this.mediaMetadata.explicit this.details.explicit = !!this.mediaMetadata.explicit
this.details.type = this.mediaMetadata.type || 'episodic'
this.newTags = [...(this.media.tags || [])] this.newTags = [...(this.media.tags || [])]
}, },
@ -228,4 +238,4 @@ export default {
}, },
mounted() {} mounted() {}
} }
</script> </script>

View File

@ -37,6 +37,15 @@ export const state = () => ({
value: 'yyyy-MM-dd' value: 'yyyy-MM-dd'
} }
], ],
podcastTypes: [
{ text: 'Episodic', value: 'episodic' },
{ text: 'Serial', value: 'serial' }
],
episodeTypes: [
{ text: 'Full', value: 'full' },
{ text: 'Trailer', value: 'trailer' },
{ text: 'Bonus', value: 'bonus' }
],
libraryIcons: ['database', 'audiobookshelf', 'books-1', 'books-2', 'book-1', 'microphone-1', 'microphone-3', 'radio', 'podcast', 'rss', 'headphones', 'music', 'file-picture', 'rocket', 'power', 'star', 'heart'] libraryIcons: ['database', 'audiobookshelf', 'books-1', 'books-2', 'book-1', 'microphone-1', 'microphone-3', 'radio', 'podcast', 'rss', 'headphones', 'music', 'file-picture', 'rocket', 'power', 'star', 'heart']
}) })
@ -169,4 +178,4 @@ export const mutations = {
state.selectedMediaItems.push(item) state.selectedMediaItems.push(item)
} }
} }
} }

View File

@ -301,6 +301,7 @@
"LabelPlayMethod": "Abspielmethode", "LabelPlayMethod": "Abspielmethode",
"LabelPodcast": "Podcast", "LabelPodcast": "Podcast",
"LabelPodcasts": "Podcasts", "LabelPodcasts": "Podcasts",
"LabelPodcastType": "Podcast Type",
"LabelPrefixesToIgnore": "Zu ignorierende(s) Vorwort(e) (Groß- und Kleinschreibung wird nicht berücksichtigt)", "LabelPrefixesToIgnore": "Zu ignorierende(s) Vorwort(e) (Groß- und Kleinschreibung wird nicht berücksichtigt)",
"LabelProgress": "Fortschritt", "LabelProgress": "Fortschritt",
"LabelProvider": "Anbieter", "LabelProvider": "Anbieter",

View File

@ -301,6 +301,7 @@
"LabelPlayMethod": "Play Method", "LabelPlayMethod": "Play Method",
"LabelPodcast": "Podcast", "LabelPodcast": "Podcast",
"LabelPodcasts": "Podcasts", "LabelPodcasts": "Podcasts",
"LabelPodcastType": "Podcast Type",
"LabelPrefixesToIgnore": "Prefixes to Ignore (case insensitive)", "LabelPrefixesToIgnore": "Prefixes to Ignore (case insensitive)",
"LabelProgress": "Progress", "LabelProgress": "Progress",
"LabelProvider": "Provider", "LabelProvider": "Provider",

View File

@ -301,6 +301,7 @@
"LabelPlayMethod": "Play Method", "LabelPlayMethod": "Play Method",
"LabelPodcast": "Podcast", "LabelPodcast": "Podcast",
"LabelPodcasts": "Podcasts", "LabelPodcasts": "Podcasts",
"LabelPodcastType": "Podcast Type",
"LabelPrefixesToIgnore": "Prefixes to Ignore (case insensitive)", "LabelPrefixesToIgnore": "Prefixes to Ignore (case insensitive)",
"LabelProgress": "Progress", "LabelProgress": "Progress",
"LabelProvider": "Provider", "LabelProvider": "Provider",
@ -616,4 +617,4 @@
"ToastSocketFailedToConnect": "Socket failed to connect", "ToastSocketFailedToConnect": "Socket failed to connect",
"ToastUserDeleteFailed": "Failed to delete user", "ToastUserDeleteFailed": "Failed to delete user",
"ToastUserDeleteSuccess": "User deleted" "ToastUserDeleteSuccess": "User deleted"
} }

View File

@ -301,6 +301,7 @@
"LabelPlayMethod": "Méthode d'écoute", "LabelPlayMethod": "Méthode d'écoute",
"LabelPodcast": "Podcast", "LabelPodcast": "Podcast",
"LabelPodcasts": "Podcasts", "LabelPodcasts": "Podcasts",
"LabelPodcastType": "Podcast Type",
"LabelPrefixesToIgnore": "Préfixes à Ignorer (Insensible à la Casse)", "LabelPrefixesToIgnore": "Préfixes à Ignorer (Insensible à la Casse)",
"LabelProgress": "Progression", "LabelProgress": "Progression",
"LabelProvider": "Fournisseur", "LabelProvider": "Fournisseur",
@ -616,4 +617,4 @@
"ToastSocketFailedToConnect": "Échec de la connexion WebSocket", "ToastSocketFailedToConnect": "Échec de la connexion WebSocket",
"ToastUserDeleteFailed": "Échec de la suppression de l'utilisateur", "ToastUserDeleteFailed": "Échec de la suppression de l'utilisateur",
"ToastUserDeleteSuccess": "Utilisateur supprimé" "ToastUserDeleteSuccess": "Utilisateur supprimé"
} }

View File

@ -301,6 +301,7 @@
"LabelPlayMethod": "Vrsta reprodukcije", "LabelPlayMethod": "Vrsta reprodukcije",
"LabelPodcast": "Podcast", "LabelPodcast": "Podcast",
"LabelPodcasts": "Podcasts", "LabelPodcasts": "Podcasts",
"LabelPodcastType": "Podcast Type",
"LabelPrefixesToIgnore": "Prefiksi za ignorirati (mala i velika slova nisu bitna)", "LabelPrefixesToIgnore": "Prefiksi za ignorirati (mala i velika slova nisu bitna)",
"LabelProgress": "Napredak", "LabelProgress": "Napredak",
"LabelProvider": "Dobavljač", "LabelProvider": "Dobavljač",
@ -616,4 +617,4 @@
"ToastSocketFailedToConnect": "Socket failed to connect", "ToastSocketFailedToConnect": "Socket failed to connect",
"ToastUserDeleteFailed": "Neuspješno brisanje korisnika", "ToastUserDeleteFailed": "Neuspješno brisanje korisnika",
"ToastUserDeleteSuccess": "Korisnik obrisan" "ToastUserDeleteSuccess": "Korisnik obrisan"
} }

View File

@ -301,6 +301,7 @@
"LabelPlayMethod": "Metodo di riproduzione", "LabelPlayMethod": "Metodo di riproduzione",
"LabelPodcast": "Podcast", "LabelPodcast": "Podcast",
"LabelPodcasts": "Podcasts", "LabelPodcasts": "Podcasts",
"LabelPodcastType": "Podcast Type",
"LabelPrefixesToIgnore": "Suffissi da ignorare (specificando maiuscole e minuscole)", "LabelPrefixesToIgnore": "Suffissi da ignorare (specificando maiuscole e minuscole)",
"LabelProgress": "Cominciati", "LabelProgress": "Cominciati",
"LabelProvider": "Provider", "LabelProvider": "Provider",
@ -616,4 +617,4 @@
"ToastSocketFailedToConnect": "Socket non riesce a connettersi", "ToastSocketFailedToConnect": "Socket non riesce a connettersi",
"ToastUserDeleteFailed": "Errore eliminazione utente", "ToastUserDeleteFailed": "Errore eliminazione utente",
"ToastUserDeleteSuccess": "Utente eliminato" "ToastUserDeleteSuccess": "Utente eliminato"
} }

View File

@ -301,6 +301,7 @@
"LabelPlayMethod": "Metoda odtwarzania", "LabelPlayMethod": "Metoda odtwarzania",
"LabelPodcast": "Podcast", "LabelPodcast": "Podcast",
"LabelPodcasts": "Podcasty", "LabelPodcasts": "Podcasty",
"LabelPodcastType": "Podcast Type",
"LabelPrefixesToIgnore": "Ignorowane prefiksy (wielkość liter nie ma znaczenia)", "LabelPrefixesToIgnore": "Ignorowane prefiksy (wielkość liter nie ma znaczenia)",
"LabelProgress": "Postęp", "LabelProgress": "Postęp",
"LabelProvider": "Dostawca", "LabelProvider": "Dostawca",
@ -616,4 +617,4 @@
"ToastSocketFailedToConnect": "Poączenie z serwerem nie powiodło się", "ToastSocketFailedToConnect": "Poączenie z serwerem nie powiodło się",
"ToastUserDeleteFailed": "Nie udało się usunąć użytkownika", "ToastUserDeleteFailed": "Nie udało się usunąć użytkownika",
"ToastUserDeleteSuccess": "Użytkownik usunięty" "ToastUserDeleteSuccess": "Użytkownik usunięty"
} }

View File

@ -301,6 +301,7 @@
"LabelPlayMethod": "Метод Воспроизведения", "LabelPlayMethod": "Метод Воспроизведения",
"LabelPodcast": "Подкаст", "LabelPodcast": "Подкаст",
"LabelPodcasts": "Подкасты", "LabelPodcasts": "Подкасты",
"LabelPodcastType": "Podcast Type",
"LabelPrefixesToIgnore": "Игнорируемые Префиксы (без учета регистра)", "LabelPrefixesToIgnore": "Игнорируемые Префиксы (без учета регистра)",
"LabelProgress": "Прогресс", "LabelProgress": "Прогресс",
"LabelProvider": "Провайдер", "LabelProvider": "Провайдер",
@ -616,4 +617,4 @@
"ToastSocketFailedToConnect": "Не удалось подключить сокет", "ToastSocketFailedToConnect": "Не удалось подключить сокет",
"ToastUserDeleteFailed": "Не удалось удалить пользователя", "ToastUserDeleteFailed": "Не удалось удалить пользователя",
"ToastUserDeleteSuccess": "Пользователь удален" "ToastUserDeleteSuccess": "Пользователь удален"
} }

View File

@ -301,6 +301,7 @@
"LabelPlayMethod": "播放方法", "LabelPlayMethod": "播放方法",
"LabelPodcast": "播客", "LabelPodcast": "播客",
"LabelPodcasts": "播客", "LabelPodcasts": "播客",
"LabelPodcastType": "Podcast Type",
"LabelPrefixesToIgnore": "忽略的前缀 (不区分大小写)", "LabelPrefixesToIgnore": "忽略的前缀 (不区分大小写)",
"LabelProgress": "进度", "LabelProgress": "进度",
"LabelProvider": "供应商", "LabelProvider": "供应商",
@ -616,4 +617,4 @@
"ToastSocketFailedToConnect": "网络连接失败", "ToastSocketFailedToConnect": "网络连接失败",
"ToastUserDeleteFailed": "删除用户失败", "ToastUserDeleteFailed": "删除用户失败",
"ToastUserDeleteSuccess": "用户已删除" "ToastUserDeleteSuccess": "用户已删除"
} }

View File

@ -106,6 +106,7 @@ class Feed {
this.meta.feedUrl = feedUrl this.meta.feedUrl = feedUrl
this.meta.link = `${serverAddress}/item/${libraryItem.id}` this.meta.link = `${serverAddress}/item/${libraryItem.id}`
this.meta.explicit = !!mediaMetadata.explicit this.meta.explicit = !!mediaMetadata.explicit
this.meta.type = mediaMetadata.type
this.episodes = [] this.episodes = []
if (isPodcast) { // PODCAST EPISODES if (isPodcast) { // PODCAST EPISODES
@ -142,6 +143,7 @@ class Feed {
this.meta.author = author this.meta.author = author
this.meta.imageUrl = media.coverPath ? `${this.serverAddress}/feed/${this.slug}/cover` : `${this.serverAddress}/Logo.png` this.meta.imageUrl = media.coverPath ? `${this.serverAddress}/feed/${this.slug}/cover` : `${this.serverAddress}/Logo.png`
this.meta.explicit = !!mediaMetadata.explicit this.meta.explicit = !!mediaMetadata.explicit
this.meta.type = mediaMetadata.type
this.episodes = [] this.episodes = []
if (isPodcast) { // PODCAST EPISODES if (isPodcast) { // PODCAST EPISODES
@ -333,4 +335,4 @@ class Feed {
return author return author
} }
} }
module.exports = Feed module.exports = Feed

View File

@ -14,6 +14,9 @@ class FeedEpisode {
this.author = null this.author = null
this.explicit = null this.explicit = null
this.duration = null this.duration = null
this.season = null
this.episode = null
this.episodeType = null
this.libraryItemId = null this.libraryItemId = null
this.episodeId = null this.episodeId = null
@ -35,6 +38,9 @@ class FeedEpisode {
this.author = episode.author this.author = episode.author
this.explicit = episode.explicit this.explicit = episode.explicit
this.duration = episode.duration this.duration = episode.duration
this.season = episode.season
this.episode = episode.episode
this.episodeType = episode.episodeType
this.libraryItemId = episode.libraryItemId this.libraryItemId = episode.libraryItemId
this.episodeId = episode.episodeId || null this.episodeId = episode.episodeId || null
this.trackIndex = episode.trackIndex || 0 this.trackIndex = episode.trackIndex || 0
@ -52,6 +58,9 @@ class FeedEpisode {
author: this.author, author: this.author,
explicit: this.explicit, explicit: this.explicit,
duration: this.duration, duration: this.duration,
season: this.season,
episode: this.episode,
episodeType: this.episodeType,
libraryItemId: this.libraryItemId, libraryItemId: this.libraryItemId,
episodeId: this.episodeId, episodeId: this.episodeId,
trackIndex: this.trackIndex, trackIndex: this.trackIndex,
@ -77,6 +86,9 @@ class FeedEpisode {
this.author = meta.author this.author = meta.author
this.explicit = mediaMetadata.explicit this.explicit = mediaMetadata.explicit
this.duration = episode.duration this.duration = episode.duration
this.season = episode.season
this.episode = episode.episode
this.episodeType = episode.episodeType
this.libraryItemId = libraryItem.id this.libraryItemId = libraryItem.id
this.episodeId = episode.id this.episodeId = episode.id
this.trackIndex = 0 this.trackIndex = 0
@ -144,9 +156,12 @@ class FeedEpisode {
{ 'itunes:summary': this.description || '' }, { 'itunes:summary': this.description || '' },
{ {
"itunes:explicit": !!this.explicit "itunes:explicit": !!this.explicit
} },
{"itunes:episodeType": this.episodeType},
{"itunes:season": this.season},
{"itunes:episode": this.episode}
] ]
} }
} }
} }
module.exports = FeedEpisode module.exports = FeedEpisode

View File

@ -7,6 +7,7 @@ class FeedMeta {
this.feedUrl = null this.feedUrl = null
this.link = null this.link = null
this.explicit = null this.explicit = null
this.type = null
if (meta) { if (meta) {
this.construct(meta) this.construct(meta)
@ -21,6 +22,7 @@ class FeedMeta {
this.feedUrl = meta.feedUrl this.feedUrl = meta.feedUrl
this.link = meta.link this.link = meta.link
this.explicit = meta.explicit this.explicit = meta.explicit
this.type = meta.type
} }
toJSON() { toJSON() {
@ -31,7 +33,8 @@ class FeedMeta {
imageUrl: this.imageUrl, imageUrl: this.imageUrl,
feedUrl: this.feedUrl, feedUrl: this.feedUrl,
link: this.link, link: this.link,
explicit: this.explicit explicit: this.explicit,
type: this.type
} }
} }
@ -53,6 +56,7 @@ class FeedMeta {
{ 'author': this.author || 'advplyr' }, { 'author': this.author || 'advplyr' },
{ 'itunes:author': this.author || 'advplyr' }, { 'itunes:author': this.author || 'advplyr' },
{ 'itunes:summary': this.description || '' }, { 'itunes:summary': this.description || '' },
{ 'itunes:type': this.type },
{ {
'itunes:image': { 'itunes:image': {
_attr: { _attr: {
@ -73,4 +77,4 @@ class FeedMeta {
} }
} }
} }
module.exports = FeedMeta module.exports = FeedMeta

View File

@ -15,6 +15,7 @@ class PodcastMetadata {
this.itunesArtistId = null this.itunesArtistId = null
this.explicit = false this.explicit = false
this.language = null this.language = null
this.type = null
if (metadata) { if (metadata) {
this.construct(metadata) this.construct(metadata)
@ -34,6 +35,7 @@ class PodcastMetadata {
this.itunesArtistId = metadata.itunesArtistId this.itunesArtistId = metadata.itunesArtistId
this.explicit = metadata.explicit this.explicit = metadata.explicit
this.language = metadata.language || null this.language = metadata.language || null
this.type = metadata.type || 'episodic'
} }
toJSON() { toJSON() {
@ -49,7 +51,8 @@ class PodcastMetadata {
itunesId: this.itunesId, itunesId: this.itunesId,
itunesArtistId: this.itunesArtistId, itunesArtistId: this.itunesArtistId,
explicit: this.explicit, explicit: this.explicit,
language: this.language language: this.language,
type: this.type
} }
} }
@ -67,7 +70,8 @@ class PodcastMetadata {
itunesId: this.itunesId, itunesId: this.itunesId,
itunesArtistId: this.itunesArtistId, itunesArtistId: this.itunesArtistId,
explicit: this.explicit, explicit: this.explicit,
language: this.language language: this.language,
type: this.type
} }
} }
@ -112,6 +116,7 @@ class PodcastMetadata {
this.itunesArtistId = mediaMetadata.itunesArtistId || null this.itunesArtistId = mediaMetadata.itunesArtistId || null
this.explicit = !!mediaMetadata.explicit this.explicit = !!mediaMetadata.explicit
this.language = mediaMetadata.language || null this.language = mediaMetadata.language || null
this.type = mediaMetadata.type || null
if (mediaMetadata.genres && mediaMetadata.genres.length) { if (mediaMetadata.genres && mediaMetadata.genres.length) {
this.genres = [...mediaMetadata.genres] this.genres = [...mediaMetadata.genres]
} }
@ -132,4 +137,4 @@ class PodcastMetadata {
return hasUpdates return hasUpdates
} }
} }
module.exports = PodcastMetadata module.exports = PodcastMetadata

View File

@ -46,7 +46,8 @@ function extractPodcastMetadata(channel) {
categories: extractCategories(channel), categories: extractCategories(channel),
feedUrl: null, feedUrl: null,
description: null, description: null,
descriptionPlain: null descriptionPlain: null,
type: null
} }
if (channel['itunes:new-feed-url']) { if (channel['itunes:new-feed-url']) {
@ -61,7 +62,7 @@ function extractPodcastMetadata(channel) {
metadata.descriptionPlain = htmlSanitizer.stripAllTags(rawDescription) metadata.descriptionPlain = htmlSanitizer.stripAllTags(rawDescription)
} }
var arrayFields = ['title', 'language', 'itunes:explicit', 'itunes:author', 'pubDate', 'link'] var arrayFields = ['title', 'language', 'itunes:explicit', 'itunes:author', 'pubDate', 'link', 'itunes:type']
arrayFields.forEach((key) => { arrayFields.forEach((key) => {
var cleanKey = key.split(':').pop() var cleanKey = key.split(':').pop()
metadata[cleanKey] = extractFirstArrayItem(channel, key) metadata[cleanKey] = extractFirstArrayItem(channel, key)
@ -258,4 +259,4 @@ module.exports.findMatchingEpisodesInFeed = (feed, searchTitle) => {
} }
}) })
return matches.sort((a, b) => a.levenshtein - b.levenshtein) return matches.sort((a, b) => a.levenshtein - b.levenshtein)
} }