diff --git a/client/components/app/SideRail.vue b/client/components/app/SideRail.vue index bf58e341..25350d24 100644 --- a/client/components/app/SideRail.vue +++ b/client/components/app/SideRail.vue @@ -86,6 +86,14 @@
+{{ $strings.ButtonDownloadQueue }}
+ + +{{ podcastAuthor }}
-{{ musicArtists }}
-
-
{{ $strings.LabelUnknown }}
+#{{ episode.episode }}
-{{ episode.title }}
+{{ episode.subtitle }}
Published {{ episode.publishedAt ? $dateDistanceFromNow(episode.publishedAt) : 'Unknown' }}
{{ $strings.HeaderDownloadQueue }}
+{{ $strings.LabelPodcast }} | +{{ $strings.LabelEpisode }} | +{{ $strings.LabelEpisodeTitle }} | +{{ $strings.LabelPubDate }} | +
---|---|---|---|
+
+
+ |
+
+
+
+ {{ downloadQueued.season }}x
+ {{ downloadQueued.episode }}
+ |
+ + {{ downloadQueued.episodeDisplayTitle }} + | +
+
+
+ {{ $dateDistanceFromNow(downloadQueued.publishedAt) }} + |
+
- {{ title }} -
+{{ subtitle }}
@@ -205,4 +206,4 @@ export default { } } } - \ No newline at end of file + diff --git a/client/components/widgets/PodcastTypeIndicator.vue b/client/components/widgets/PodcastTypeIndicator.vue new file mode 100644 index 00000000..d914d283 --- /dev/null +++ b/client/components/widgets/PodcastTypeIndicator.vue @@ -0,0 +1,31 @@ + +{{ $strings.HeaderCurrentDownloads }}
+{{ $strings.MessageNoDownloadsInProgress }}
+ +{{ $dateDistanceFromNow(episode.publishedAt) }}
+{{ $dateDistanceFromNow(episode.publishedAt) }}
+{{ episode.subtitle }}
+{{ $dateDistanceFromNow(episode.publishedAt) }}
{{ episode.title }}
+{{ episode.subtitle }}
diff --git a/client/strings/de.json b/client/strings/de.json index 57915ccd..e1c3b02f 100644 --- a/client/strings/de.json +++ b/client/strings/de.json @@ -20,6 +20,7 @@ "ButtonCreate": "Erstellen", "ButtonCreateBackup": "Sicherung erstellen", "ButtonDelete": "Löschen", + "ButtonDownloadQueue": "Queue", "ButtonEdit": "Bearbeiten", "ButtonEditChapters": "Kapitel bearbeiten", "ButtonEditPodcast": "Podcast bearbeiten", @@ -92,7 +93,9 @@ "HeaderCollection": "Sammlungen", "HeaderCollectionItems": "Sammlungseinträge", "HeaderCover": "Titelbild", + "HeaderCurrentDownloads": "Current Downloads", "HeaderDetails": "Details", + "HeaderDownloadQueue": "Download Queue", "HeaderEpisodes": "Episoden", "HeaderFiles": "Dateien", "HeaderFindChapters": "Kapitel suchen", @@ -493,6 +496,8 @@ "MessageNoCollections": "Keine Sammlungen", "MessageNoCoversFound": "Keine Titelbilder gefunden", "MessageNoDescription": "Keine Beschreibung", + "MessageNoDownloadsQueued": "No downloads queued", + "MessageNoDownloadsInProgress": "No downloads currently in progress", "MessageNoEpisodeMatchesFound": "Keine Episodenübereinstimmungen gefunden", "MessageNoEpisodes": "Keine Episoden", "MessageNoFoldersAvailable": "Keine Ordner verfügbar", @@ -623,4 +628,4 @@ "ToastSocketFailedToConnect": "Verbindung zum WebSocket fehlgeschlagen", "ToastUserDeleteFailed": "Benutzer konnte nicht gelöscht werden", "ToastUserDeleteSuccess": "Benutzer gelöscht" -} \ No newline at end of file +} diff --git a/client/strings/en-us.json b/client/strings/en-us.json index 710d5ef8..c8e87d28 100644 --- a/client/strings/en-us.json +++ b/client/strings/en-us.json @@ -20,6 +20,7 @@ "ButtonCreate": "Create", "ButtonCreateBackup": "Create Backup", "ButtonDelete": "Delete", + "ButtonDownloadQueue": "Queue", "ButtonEdit": "Edit", "ButtonEditChapters": "Edit Chapters", "ButtonEditPodcast": "Edit Podcast", @@ -92,7 +93,9 @@ "HeaderCollection": "Collection", "HeaderCollectionItems": "Collection Items", "HeaderCover": "Cover", + "HeaderCurrentDownloads": "Current Downloads", "HeaderDetails": "Details", + "HeaderDownloadQueue": "Download Queue", "HeaderEpisodes": "Episodes", "HeaderFiles": "Files", "HeaderFindChapters": "Find Chapters", @@ -493,6 +496,8 @@ "MessageNoCollections": "No Collections", "MessageNoCoversFound": "No Covers Found", "MessageNoDescription": "No description", + "MessageNoDownloadsQueued": "No downloads queued", + "MessageNoDownloadsInProgress": "No downloads currently in progress", "MessageNoEpisodeMatchesFound": "No episode matches found", "MessageNoEpisodes": "No Episodes", "MessageNoFoldersAvailable": "No Folders Available", diff --git a/client/strings/es.json b/client/strings/es.json index 710d5ef8..c8e87d28 100644 --- a/client/strings/es.json +++ b/client/strings/es.json @@ -20,6 +20,7 @@ "ButtonCreate": "Create", "ButtonCreateBackup": "Create Backup", "ButtonDelete": "Delete", + "ButtonDownloadQueue": "Queue", "ButtonEdit": "Edit", "ButtonEditChapters": "Edit Chapters", "ButtonEditPodcast": "Edit Podcast", @@ -92,7 +93,9 @@ "HeaderCollection": "Collection", "HeaderCollectionItems": "Collection Items", "HeaderCover": "Cover", + "HeaderCurrentDownloads": "Current Downloads", "HeaderDetails": "Details", + "HeaderDownloadQueue": "Download Queue", "HeaderEpisodes": "Episodes", "HeaderFiles": "Files", "HeaderFindChapters": "Find Chapters", @@ -493,6 +496,8 @@ "MessageNoCollections": "No Collections", "MessageNoCoversFound": "No Covers Found", "MessageNoDescription": "No description", + "MessageNoDownloadsQueued": "No downloads queued", + "MessageNoDownloadsInProgress": "No downloads currently in progress", "MessageNoEpisodeMatchesFound": "No episode matches found", "MessageNoEpisodes": "No Episodes", "MessageNoFoldersAvailable": "No Folders Available", diff --git a/client/strings/fr.json b/client/strings/fr.json index 47f84209..2393110b 100644 --- a/client/strings/fr.json +++ b/client/strings/fr.json @@ -20,6 +20,7 @@ "ButtonCreate": "Créer", "ButtonCreateBackup": "Créer une sauvegarde", "ButtonDelete": "Effacer", + "ButtonDownloadQueue": "Queue", "ButtonEdit": "Modifier", "ButtonEditChapters": "Modifier les chapitres", "ButtonEditPodcast": "Modifier les podcasts", @@ -92,7 +93,9 @@ "HeaderCollection": "Collection", "HeaderCollectionItems": "Entrées de la Collection", "HeaderCover": "Couverture", + "HeaderCurrentDownloads": "Current Downloads", "HeaderDetails": "Détails", + "HeaderDownloadQueue": "Download Queue", "HeaderEpisodes": "Épisodes", "HeaderFiles": "Fichiers", "HeaderFindChapters": "Trouver les chapitres", @@ -493,6 +496,8 @@ "MessageNoCollections": "Pas de collections", "MessageNoCoversFound": "Aucune couverture trouvée", "MessageNoDescription": "Pas de description", + "MessageNoDownloadsQueued": "No downloads queued", + "MessageNoDownloadsInProgress": "No downloads currently in progress", "MessageNoEpisodeMatchesFound": "Pas de correspondance d'épisode trouvée", "MessageNoEpisodes": "Aucun épisode", "MessageNoFoldersAvailable": "Aucun dossier disponible", diff --git a/client/strings/hr.json b/client/strings/hr.json index 36e67444..00d27566 100644 --- a/client/strings/hr.json +++ b/client/strings/hr.json @@ -20,6 +20,7 @@ "ButtonCreate": "Napravi", "ButtonCreateBackup": "Napravi backup", "ButtonDelete": "Obriši", + "ButtonDownloadQueue": "Queue", "ButtonEdit": "Edit", "ButtonEditChapters": "Uredi poglavlja", "ButtonEditPodcast": "Uredi podcast", @@ -92,7 +93,9 @@ "HeaderCollection": "Kolekcija", "HeaderCollectionItems": "Stvari u kolekciji", "HeaderCover": "Cover", + "HeaderCurrentDownloads": "Current Downloads", "HeaderDetails": "Detalji", + "HeaderDownloadQueue": "Download Queue", "HeaderEpisodes": "Epizode", "HeaderFiles": "Datoteke", "HeaderFindChapters": "Pronađi poglavlja", @@ -493,6 +496,8 @@ "MessageNoCollections": "Nema kolekcija", "MessageNoCoversFound": "Covers nisu pronađeni", "MessageNoDescription": "Nema opisa", + "MessageNoDownloadsQueued": "No downloads queued", + "MessageNoDownloadsInProgress": "No downloads currently in progress", "MessageNoEpisodeMatchesFound": "Nijedna epizoda pronađena", "MessageNoEpisodes": "Nema epizoda", "MessageNoFoldersAvailable": "Nema dostupnih foldera", diff --git a/client/strings/it.json b/client/strings/it.json index 21bc3ae9..8818f8fd 100644 --- a/client/strings/it.json +++ b/client/strings/it.json @@ -20,6 +20,7 @@ "ButtonCreate": "Crea", "ButtonCreateBackup": "Crea un Backup", "ButtonDelete": "Elimina", + "ButtonDownloadQueue": "Queue", "ButtonEdit": "Edit", "ButtonEditChapters": "Modifica Capitoli", "ButtonEditPodcast": "Modifica Podcast", @@ -92,7 +93,9 @@ "HeaderCollection": "Raccolta", "HeaderCollectionItems": "Elementi della Raccolta", "HeaderCover": "Cover", + "HeaderCurrentDownloads": "Current Downloads", "HeaderDetails": "Dettagli", + "HeaderDownloadQueue": "Download Queue", "HeaderEpisodes": "Episodi", "HeaderFiles": "File", "HeaderFindChapters": "Trova Capitoli", @@ -493,6 +496,8 @@ "MessageNoCollections": "Nessuna Raccolta", "MessageNoCoversFound": "Nessuna Cover Trovata", "MessageNoDescription": "Nessuna descrizione", + "MessageNoDownloadsQueued": "No downloads queued", + "MessageNoDownloadsInProgress": "No downloads currently in progress", "MessageNoEpisodeMatchesFound": "Nessun episodio corrispondente trovato", "MessageNoEpisodes": "Nessun Episodio", "MessageNoFoldersAvailable": "Nessuna Cartella disponibile", diff --git a/client/strings/pl.json b/client/strings/pl.json index c907e612..4ecdcff9 100644 --- a/client/strings/pl.json +++ b/client/strings/pl.json @@ -20,6 +20,7 @@ "ButtonCreate": "Utwórz", "ButtonCreateBackup": "Utwórz kopię zapasową", "ButtonDelete": "Usuń", + "ButtonDownloadQueue": "Queue", "ButtonEdit": "Edit", "ButtonEditChapters": "Edytuj rozdziały", "ButtonEditPodcast": "Edytuj podcast", @@ -92,7 +93,9 @@ "HeaderCollection": "Kolekcja", "HeaderCollectionItems": "Elementy kolekcji", "HeaderCover": "Okładka", + "HeaderCurrentDownloads": "Current Downloads", "HeaderDetails": "Szczegóły", + "HeaderDownloadQueue": "Download Queue", "HeaderEpisodes": "Rozdziały", "HeaderFiles": "Pliki", "HeaderFindChapters": "Wyszukaj rozdziały", @@ -493,6 +496,8 @@ "MessageNoCollections": "Brak kolekcji", "MessageNoCoversFound": "Okładki nieznalezione", "MessageNoDescription": "Brak opisu", + "MessageNoDownloadsQueued": "No downloads queued", + "MessageNoDownloadsInProgress": "No downloads currently in progress", "MessageNoEpisodeMatchesFound": "Nie znaleziono pasujących odcinków", "MessageNoEpisodes": "Brak odcinków", "MessageNoFoldersAvailable": "Brak dostępnych folderów", diff --git a/client/strings/ru.json b/client/strings/ru.json index a1a34f70..dd50a169 100644 --- a/client/strings/ru.json +++ b/client/strings/ru.json @@ -20,6 +20,7 @@ "ButtonCreate": "Создать", "ButtonCreateBackup": "Создать бэкап", "ButtonDelete": "Удалить", + "ButtonDownloadQueue": "Queue", "ButtonEdit": "Редактировать", "ButtonEditChapters": "Редактировать Главы", "ButtonEditPodcast": "Редактировать Подкаст", @@ -92,7 +93,9 @@ "HeaderCollection": "Коллекция", "HeaderCollectionItems": "Элементы Коллекции", "HeaderCover": "Обложка", + "HeaderCurrentDownloads": "Current Downloads", "HeaderDetails": "Подробности", + "HeaderDownloadQueue": "Download Queue", "HeaderEpisodes": "Эпизоды", "HeaderFiles": "Файлы", "HeaderFindChapters": "Найти Главы", @@ -493,6 +496,8 @@ "MessageNoCollections": "Нет Коллекций", "MessageNoCoversFound": "Обложек не найдено", "MessageNoDescription": "Нет описания", + "MessageNoDownloadsQueued": "No downloads queued", + "MessageNoDownloadsInProgress": "No downloads currently in progress", "MessageNoEpisodeMatchesFound": "Совпадения эпизодов не найдены", "MessageNoEpisodes": "Нет Эпизодов", "MessageNoFoldersAvailable": "Нет доступных папок", diff --git a/client/strings/zh-cn.json b/client/strings/zh-cn.json index 433a87bc..671fde5a 100644 --- a/client/strings/zh-cn.json +++ b/client/strings/zh-cn.json @@ -20,6 +20,7 @@ "ButtonCreate": "创建", "ButtonCreateBackup": "创建备份", "ButtonDelete": "删除", + "ButtonDownloadQueue": "Queue", "ButtonEdit": "编辑", "ButtonEditChapters": "编辑章节", "ButtonEditPodcast": "编辑播客", @@ -92,7 +93,9 @@ "HeaderCollection": "收藏", "HeaderCollectionItems": "收藏项目", "HeaderCover": "封面", + "HeaderCurrentDownloads": "Current Downloads", "HeaderDetails": "详情", + "HeaderDownloadQueue": "Download Queue", "HeaderEpisodes": "剧集", "HeaderFiles": "文件", "HeaderFindChapters": "查找章节", @@ -493,6 +496,8 @@ "MessageNoCollections": "没有收藏", "MessageNoCoversFound": "没有找到封面", "MessageNoDescription": "没有描述", + "MessageNoDownloadsQueued": "No downloads queued", + "MessageNoDownloadsInProgress": "No downloads currently in progress", "MessageNoEpisodeMatchesFound": "没有找到任何剧集匹配项", "MessageNoEpisodes": "没有剧集", "MessageNoFoldersAvailable": "没有可用文件夹", diff --git a/server/controllers/LibraryController.js b/server/controllers/LibraryController.js index ece93ca2..7f814591 100644 --- a/server/controllers/LibraryController.js +++ b/server/controllers/LibraryController.js @@ -82,6 +82,13 @@ class LibraryController { return res.json(req.library) } + async getDownloadQueue(req, res) { + const library = req.library + + let queue = this.podcastManager.getDownloadQueueDetails().filter(q => q.libraryId === library.id) + return res.json(queue) + } + async update(req, res) { const library = req.library diff --git a/server/managers/PodcastManager.js b/server/managers/PodcastManager.js index 74751d45..3b7e352b 100644 --- a/server/managers/PodcastManager.js +++ b/server/managers/PodcastManager.js @@ -56,12 +56,13 @@ class PodcastManager { newPe.setData(ep, index++) newPe.libraryItemId = libraryItem.id var newPeDl = new PodcastEpisodeDownload() - newPeDl.setData(newPe, libraryItem, isAutoDownload) + newPeDl.setData(newPe, libraryItem, isAutoDownload, libraryItem.libraryId) this.startPodcastEpisodeDownload(newPeDl) }) } async startPodcastEpisodeDownload(podcastEpisodeDownload) { + SocketAuthority.emitter('download_queue_updated', this.getDownloadQueueDetails()) if (this.currentDownload) { this.downloadQueue.push(podcastEpisodeDownload) SocketAuthority.emitter('episode_download_queued', podcastEpisodeDownload.toJSONForClient()) @@ -99,6 +100,7 @@ class PodcastManager { } SocketAuthority.emitter('episode_download_finished', this.currentDownload.toJSONForClient()) + SocketAuthority.emitter('download_queue_updated', this.getDownloadQueueDetails()) this.watcher.removeIgnoreDir(this.currentDownload.libraryItem.path) this.currentDownload = null @@ -329,5 +331,22 @@ class PodcastManager { feeds: rssFeedData } } + + getDownloadQueueDetails() { + return this.downloadQueue.map(item => { + return { + id: item.id, + libraryId: item.libraryId || null, + libraryItemId: item.libraryItemId || null, + podcastTitle: item.libraryItem.media.metadata.title || null, + podcastExplicit: item.libraryItem.media.metadata.explicit || false, + episodeDisplayTitle: item.podcastEpisode.title || null, + season: item.podcastEpisode.season || null, + episode: item.podcastEpisode.episode || null, + episodeType: item.podcastEpisode.episodeType || 'full', + publishedAt: item.podcastEpisode.publishedAt || null + } + }) + } } -module.exports = PodcastManager \ No newline at end of file +module.exports = PodcastManager diff --git a/server/objects/PodcastEpisodeDownload.js b/server/objects/PodcastEpisodeDownload.js index 38a371e5..c5ee99ab 100644 --- a/server/objects/PodcastEpisodeDownload.js +++ b/server/objects/PodcastEpisodeDownload.js @@ -8,6 +8,7 @@ class PodcastEpisodeDownload { this.podcastEpisode = null this.url = null this.libraryItem = null + this.libraryId = null this.isAutoDownload = false this.isDownloading = false @@ -25,12 +26,17 @@ class PodcastEpisodeDownload { episodeDisplayTitle: this.podcastEpisode ? this.podcastEpisode.title : null, url: this.url, libraryItemId: this.libraryItem ? this.libraryItem.id : null, + libraryId: this.libraryId || null, isDownloading: this.isDownloading, isFinished: this.isFinished, failed: this.failed, startedAt: this.startedAt, createdAt: this.createdAt, - finishedAt: this.finishedAt + finishedAt: this.finishedAt, + season: this.podcastEpisode ? this.podcastEpisode.season : null, + episode: this.podcastEpisode ? this.podcastEpisode.episode : null, + episodeType: this.podcastEpisode ? this.podcastEpisode.episodeType : 'full', + publishedAt: this.podcastEpisode ? this.podcastEpisode.publishedAt : null } } @@ -47,13 +53,14 @@ class PodcastEpisodeDownload { return this.libraryItem ? this.libraryItem.id : null } - setData(podcastEpisode, libraryItem, isAutoDownload) { + setData(podcastEpisode, libraryItem, isAutoDownload, libraryId) { this.id = getId('epdl') this.podcastEpisode = podcastEpisode this.url = encodeURI(podcastEpisode.enclosure.url) this.libraryItem = libraryItem this.isAutoDownload = isAutoDownload this.createdAt = Date.now() + this.libraryId = libraryId } setFinished(success) { @@ -62,4 +69,4 @@ class PodcastEpisodeDownload { this.failed = !success } } -module.exports = PodcastEpisodeDownload \ No newline at end of file +module.exports = PodcastEpisodeDownload diff --git a/server/routers/ApiRouter.js b/server/routers/ApiRouter.js index 41c26769..6e1837b3 100644 --- a/server/routers/ApiRouter.js +++ b/server/routers/ApiRouter.js @@ -76,6 +76,7 @@ class ApiRouter { this.router.get('/libraries/:id/items', LibraryController.middleware.bind(this), LibraryController.getLibraryItems.bind(this)) this.router.delete('/libraries/:id/issues', LibraryController.middleware.bind(this), LibraryController.removeLibraryItemsWithIssues.bind(this)) + this.router.get('/libraries/:id/downloads', LibraryController.middleware.bind(this), LibraryController.getDownloadQueue.bind(this)) this.router.get('/libraries/:id/series', LibraryController.middleware.bind(this), LibraryController.getAllSeriesForLibrary.bind(this)) this.router.get('/libraries/:id/collections', LibraryController.middleware.bind(this), LibraryController.getCollectionsForLibrary.bind(this)) this.router.get('/libraries/:id/playlists', LibraryController.middleware.bind(this), LibraryController.getUserPlaylistsForLibrary.bind(this)) @@ -553,4 +554,4 @@ class ApiRouter { } } } -module.exports = ApiRouter \ No newline at end of file +module.exports = ApiRouter