diff --git a/client/pages/library/_library/podcast/search.vue b/client/pages/library/_library/podcast/search.vue index 841927c6f..b6c0676ff 100644 --- a/client/pages/library/_library/podcast/search.vue +++ b/client/pages/library/_library/podcast/search.vue @@ -113,18 +113,25 @@ export default { return } - await this.$axios - .$post(`/api/podcasts/opml`, { opmlText: txt }) - .then((data) => { - console.log(data) + try { + this.$root.socket.on('opml_feeds', (data) => { + this.$root.socket.off('opml_feeds') + this.processing = false + if (data.error) { + this.$toast.error(data.error) + return + } this.opmlFeeds = data.feeds || [] this.showOPMLFeedsModal = true }) - .catch((error) => { - console.error('Failed', error) - this.$toast.error('Failed to parse OPML file') - }) - this.processing = false + await this.$axios.$post(`/api/podcasts/opml`, { opmlText: txt }) + console.log('OPML import started') + } catch (error) { + this.$root.socket.off('opml_feeds') + this.processing = false + console.error('/api/podcasts/opml failed:', error) + this.$toast.error('Failed to start OPML import: ' + error.message) + } }, submit() { if (!this.searchInput) return @@ -222,6 +229,9 @@ export default { }, mounted() { this.fetchExistentPodcastsInYourLibrary() + }, + beforeDestroy() { + this.$root.socket.off('opml_feeds') } } diff --git a/server/controllers/PodcastController.js b/server/controllers/PodcastController.js index 119854864..28f0af70c 100644 --- a/server/controllers/PodcastController.js +++ b/server/controllers/PodcastController.js @@ -133,7 +133,7 @@ class PodcastController { res.json({ podcast }) } - async getFeedsFromOPMLText(req, res) { + getFeedsFromOPMLText(req, res) { if (!req.user.isAdminOrUp) { Logger.error(`[PodcastController] Non-admin user "${req.user.username}" attempted to get feeds from opml`) return res.sendStatus(403) @@ -143,8 +143,18 @@ class PodcastController { return res.sendStatus(400) } - const rssFeedsData = await this.podcastManager.getOPMLFeeds(req.body.opmlText) - res.json(rssFeedsData) + this.podcastManager + .getOPMLFeeds(req.body.opmlText) + .then((rssFeedsData) => { + Logger.info('[PodcastController] getOPMLFeeds finished successfully') + SocketAuthority.emitter('opml_feeds', rssFeedsData) + }) + .catch((error) => { + Logger.error('[PodcastController] getOPMLFeeds error:', error) + SocketAuthority.emitter('opml_feeds', { error: error.message }) + }) + Logger.info('[PodcastController] getOPMLFeeds started') + res.sendStatus(200) } async checkNewEpisodes(req, res) { diff --git a/server/managers/PodcastManager.js b/server/managers/PodcastManager.js index d8db6492e..21a08ed5b 100644 --- a/server/managers/PodcastManager.js +++ b/server/managers/PodcastManager.js @@ -354,9 +354,7 @@ class PodcastManager { var extractedFeeds = opmlParser.parse(opmlText) if (!extractedFeeds || !extractedFeeds.length) { Logger.error('[PodcastManager] getOPMLFeeds: No RSS feeds found in OPML') - return { - error: 'No RSS feeds found in OPML' - } + throw new Error('No RSS feeds found in OPML') } var rssFeedData = [] @@ -369,6 +367,11 @@ class PodcastManager { } } + if (!rssFeedData.length) { + Logger.error('[PodcastManager] getOPMLFeeds: No valid RSS feeds found in OPML') + throw new Error('No valid RSS feeds found in OPML') + } + return { feeds: rssFeedData } diff --git a/server/utils/podcastUtils.js b/server/utils/podcastUtils.js index bfe540edd..c677f9f41 100644 --- a/server/utils/podcastUtils.js +++ b/server/utils/podcastUtils.js @@ -231,7 +231,7 @@ module.exports.getPodcastFeed = (feedUrl, excludeEpisodeMetadata = false) => { return axios({ url: feedUrl, method: 'GET', - timeout: 12000, + timeout: 5000, responseType: 'arraybuffer', headers: { Accept: 'application/rss+xml, application/xhtml+xml, application/xml, */*;q=0.8', @@ -266,7 +266,7 @@ module.exports.getPodcastFeed = (feedUrl, excludeEpisodeMetadata = false) => { return payload.podcast }) .catch((error) => { - Logger.error('[podcastUtils] getPodcastFeed Error', error) + Logger.error('[podcastUtils] getPodcastFeed Error:', error.message) return null }) }