From 1b3d3f85727d03ba8f54f288d600bad20cfec50a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Nyi=CC=81ri?= Date: Tue, 13 Jul 2021 23:33:04 +0200 Subject: [PATCH] Update: Improve performance by requesting only data that is needed and parallelising calls to Plex where possible --- dist/plex-meets-homeassistant.js | 155 +++++++++++++++++++------------ src/modules/Plex.ts | 15 ++- src/plex-meets-homeassistant.ts | 135 +++++++++++++++++---------- 3 files changed, 190 insertions(+), 115 deletions(-) diff --git a/dist/plex-meets-homeassistant.js b/dist/plex-meets-homeassistant.js index 1ec5f6d..1288fb5 100644 --- a/dist/plex-meets-homeassistant.js +++ b/dist/plex-meets-homeassistant.js @@ -18675,12 +18675,7 @@ class Plex { this.requestTimeout = 10000; this.sections = []; this.init = async () => { - await this.getClients(); - /* - setInterval(() => { - this.getClients(); - }, 30000); - */ + await Promise.all([this.getSections(), this.getClients(), this.getServerID()]); }; this.getClients = async () => { const url = this.authorizeURL(`${this.getBasicURL()}/clients`); @@ -18719,6 +18714,9 @@ class Plex { return this.sections; }; this.getSectionData = async (sectionID) => { + return this.exportSectionsData([await this.getSectionDataWithoutProcessing(sectionID)]); + }; + this.getSectionDataWithoutProcessing = async (sectionID) => { const bulkItems = 50; let url = this.authorizeURL(`${this.getBasicURL()}/library/sections/${sectionID}/all`); url += `&sort=${this.sort}`; @@ -18759,7 +18757,7 @@ class Plex { const sections = await this.getSections(); const sectionsRequests = []; lodash.forEach(sections, section => { - sectionsRequests.push(this.getSectionData(section.key)); + sectionsRequests.push(this.getSectionDataWithoutProcessing(section.key)); }); return this.exportSectionsData(await Promise.all(sectionsRequests)); }; @@ -20954,73 +20952,114 @@ class PlexMeetsHomeAssistant extends HTMLElement { await this.playController.init(); } await this.plex.init(); - try { - const onDeck = await this.plex.getOnDeck(); - this.data.Deck = onDeck.Metadata; - } - catch (err) { - if (lodash.includes(err.message, 'Request failed with status code 404')) { - console.warn(getOldPlexServerErrorMessage('Deck')); - } - else { - throw err; - } - } - try { - const continueWatching = await this.plex.getContinueWatching(); - this.data['Continue Watching'] = continueWatching.Metadata; - } - catch (err) { - if (lodash.includes(err.message, 'Request failed with status code 404')) { - console.warn(getOldPlexServerErrorMessage('Continue Watching')); - } - else { - throw err; + const plexAllSections = await this.plex.getSections(); + const getOnDeck = async () => { + if (this.plex) { + try { + const onDeck = await this.plex.getOnDeck(); + this.data.Deck = onDeck.Metadata; + } + catch (err) { + if (lodash.includes(err.message, 'Request failed with status code 404')) { + console.warn(getOldPlexServerErrorMessage('Deck')); + } + else { + throw err; + } + } } - } - try { - const watchNext = await this.plex.getWatchNext(); - this.data['Watch Next'] = watchNext.Metadata; - } - catch (err) { - if (lodash.includes(err.message, 'Request failed with status code 404')) { - console.warn(getOldPlexServerErrorMessage('Watch Next')); + }; + const getContinueWatching = async () => { + if (this.plex) { + try { + const continueWatching = await this.plex.getContinueWatching(); + this.data['Continue Watching'] = continueWatching.Metadata; + } + catch (err) { + if (lodash.includes(err.message, 'Request failed with status code 404')) { + console.warn(getOldPlexServerErrorMessage('Continue Watching')); + } + else { + throw err; + } + } } - else { - throw err; + }; + const getWatchNext = async () => { + if (this.plex) { + try { + const watchNext = await this.plex.getWatchNext(); + this.data['Watch Next'] = watchNext.Metadata; + } + catch (err) { + if (lodash.includes(err.message, 'Request failed with status code 404')) { + console.warn(getOldPlexServerErrorMessage('Watch Next')); + } + else { + throw err; + } + } } - } - try { - const recentlyAdded = await this.plex.getRecentyAdded(); - this.data['Recently Added'] = recentlyAdded.Metadata; - } - catch (err) { - if (lodash.includes(err.message, 'Request failed with status code 404')) { + }; + const getRecentyAdded = async () => { + if (this.plex) { try { - console.warn('PlexMeetsHomeAssistant: Using old endpoint for recently added tv shows. Consider updating your Plex server.'); - const recentlyAdded = await this.plex.getRecentyAdded(true); + const recentlyAdded = await this.plex.getRecentyAdded(); this.data['Recently Added'] = recentlyAdded.Metadata; - // eslint-disable-next-line no-shadow } catch (err) { if (lodash.includes(err.message, 'Request failed with status code 404')) { - console.warn(getOldPlexServerErrorMessage('Recently Added')); + try { + console.warn('PlexMeetsHomeAssistant: Using old endpoint for recently added tv shows. Consider updating your Plex server.'); + const recentlyAdded = await this.plex.getRecentyAdded(true); + this.data['Recently Added'] = recentlyAdded.Metadata; + // eslint-disable-next-line no-shadow + } + catch (err) { + if (lodash.includes(err.message, 'Request failed with status code 404')) { + console.warn(getOldPlexServerErrorMessage('Recently Added')); + } + else { + throw err; + } + } } else { throw err; } } } - else { - throw err; + }; + let sectionKey = 0; + lodash.forEach(plexAllSections, (section) => { + if (lodash.isEqual(section.title, this.config.libraryName)) { + sectionKey = section.key; + return false; } - } - const [serverID, plexSections] = await Promise.all([this.plex.getServerID(), this.plex.getSectionsData()]); - // eslint-disable-next-line @typescript-eslint/camelcase - this.data.serverID = serverID; - lodash.forEach(plexSections, section => { - this.data[section.title1] = section.Metadata; + return true; }); + const loadDataRequests = []; + if (sectionKey) { + loadDataRequests.push(this.plex.getSectionData(sectionKey)); + } + if (lodash.isEqual(this.config.libraryName, 'Deck')) { + loadDataRequests.push(getOnDeck()); + } + else if (lodash.isEqual(this.config.libraryName, 'Continue Watching')) { + loadDataRequests.push(getContinueWatching()); + } + else if (lodash.isEqual(this.config.libraryName, 'Watch Next')) { + loadDataRequests.push(getWatchNext()); + } + else if (lodash.isEqual(this.config.libraryName, 'Recently Added')) { + loadDataRequests.push(getRecentyAdded()); + } + const [plexSections] = await Promise.all(loadDataRequests); + if (plexSections && sectionKey) { + lodash.forEach(plexSections, section => { + this.data[section.title1] = section.Metadata; + }); + } if (this.data[this.config.libraryName] === undefined) { this.error = `Library name ${this.config.libraryName} does not exist.`; } diff --git a/src/modules/Plex.ts b/src/modules/Plex.ts index 83639af..b506062 100644 --- a/src/modules/Plex.ts +++ b/src/modules/Plex.ts @@ -36,12 +36,7 @@ class Plex { } init = async (): Promise => { - await this.getClients(); - /* - setInterval(() => { - this.getClients(); - }, 30000); - */ + await Promise.all([this.getSections(), this.getClients(), this.getServerID()]); }; getClients = async (): Promise> => { @@ -74,7 +69,7 @@ class Plex { return this.serverInfo; }; - getSections = async (): Promise => { + getSections = async (): Promise>> => { if (_.isEmpty(this.sections)) { const url = this.authorizeURL(`${this.getBasicURL()}/library/sections`); const sectionsData = await axios.get(url, { @@ -86,6 +81,10 @@ class Plex { }; getSectionData = async (sectionID: number): Promise => { + return this.exportSectionsData([await this.getSectionDataWithoutProcessing(sectionID)]); + }; + + private getSectionDataWithoutProcessing = async (sectionID: number): Promise => { const bulkItems = 50; let url = this.authorizeURL(`${this.getBasicURL()}/library/sections/${sectionID}/all`); url += `&sort=${this.sort}`; @@ -137,7 +136,7 @@ class Plex { const sections = await this.getSections(); const sectionsRequests: Array> = []; _.forEach(sections, section => { - sectionsRequests.push(this.getSectionData(section.key)); + sectionsRequests.push(this.getSectionDataWithoutProcessing(section.key)); }); return this.exportSectionsData(await Promise.all(sectionsRequests)); }; diff --git a/src/plex-meets-homeassistant.ts b/src/plex-meets-homeassistant.ts index 6f4c535..f47c288 100644 --- a/src/plex-meets-homeassistant.ts +++ b/src/plex-meets-homeassistant.ts @@ -319,70 +319,107 @@ class PlexMeetsHomeAssistant extends HTMLElement { await this.playController.init(); } await this.plex.init(); + const plexAllSections = await this.plex.getSections(); - try { - const onDeck = await this.plex.getOnDeck(); - this.data.Deck = onDeck.Metadata; - } catch (err) { - if (_.includes(err.message, 'Request failed with status code 404')) { - console.warn(getOldPlexServerErrorMessage('Deck')); - } else { - throw err; + const getOnDeck = async (): Promise => { + if (this.plex) { + try { + const onDeck = await this.plex.getOnDeck(); + this.data.Deck = onDeck.Metadata; + } catch (err) { + if (_.includes(err.message, 'Request failed with status code 404')) { + console.warn(getOldPlexServerErrorMessage('Deck')); + } else { + throw err; + } + } } - } - - try { - const continueWatching = await this.plex.getContinueWatching(); - this.data['Continue Watching'] = continueWatching.Metadata; - } catch (err) { - if (_.includes(err.message, 'Request failed with status code 404')) { - console.warn(getOldPlexServerErrorMessage('Continue Watching')); - } else { - throw err; + }; + const getContinueWatching = async (): Promise => { + if (this.plex) { + try { + const continueWatching = await this.plex.getContinueWatching(); + this.data['Continue Watching'] = continueWatching.Metadata; + } catch (err) { + if (_.includes(err.message, 'Request failed with status code 404')) { + console.warn(getOldPlexServerErrorMessage('Continue Watching')); + } else { + throw err; + } + } } - } - - try { - const watchNext = await this.plex.getWatchNext(); - this.data['Watch Next'] = watchNext.Metadata; - } catch (err) { - if (_.includes(err.message, 'Request failed with status code 404')) { - console.warn(getOldPlexServerErrorMessage('Watch Next')); - } else { - throw err; + }; + const getWatchNext = async (): Promise => { + if (this.plex) { + try { + const watchNext = await this.plex.getWatchNext(); + this.data['Watch Next'] = watchNext.Metadata; + } catch (err) { + if (_.includes(err.message, 'Request failed with status code 404')) { + console.warn(getOldPlexServerErrorMessage('Watch Next')); + } else { + throw err; + } + } } - } - - try { - const recentlyAdded = await this.plex.getRecentyAdded(); - this.data['Recently Added'] = recentlyAdded.Metadata; - } catch (err) { - if (_.includes(err.message, 'Request failed with status code 404')) { + }; + const getRecentyAdded = async (): Promise => { + if (this.plex) { try { - console.warn( - 'PlexMeetsHomeAssistant: Using old endpoint for recently added tv shows. Consider updating your Plex server.' - ); - const recentlyAdded = await this.plex.getRecentyAdded(true); + const recentlyAdded = await this.plex.getRecentyAdded(); this.data['Recently Added'] = recentlyAdded.Metadata; - // eslint-disable-next-line no-shadow } catch (err) { if (_.includes(err.message, 'Request failed with status code 404')) { - console.warn(getOldPlexServerErrorMessage('Recently Added')); + try { + console.warn( + 'PlexMeetsHomeAssistant: Using old endpoint for recently added tv shows. Consider updating your Plex server.' + ); + const recentlyAdded = await this.plex.getRecentyAdded(true); + this.data['Recently Added'] = recentlyAdded.Metadata; + // eslint-disable-next-line no-shadow + } catch (err) { + if (_.includes(err.message, 'Request failed with status code 404')) { + console.warn(getOldPlexServerErrorMessage('Recently Added')); + } else { + throw err; + } + } } else { throw err; } } - } else { - throw err; } - } + }; - const [serverID, plexSections] = await Promise.all([this.plex.getServerID(), this.plex.getSectionsData()]); - // eslint-disable-next-line @typescript-eslint/camelcase - this.data.serverID = serverID; - _.forEach(plexSections, section => { - this.data[section.title1] = section.Metadata; + let sectionKey: number | false = 0; + _.forEach(plexAllSections, (section: Record) => { + if (_.isEqual(section.title, this.config.libraryName)) { + sectionKey = section.key; + return false; + } + return true; }); + const loadDataRequests = []; + if (sectionKey) { + loadDataRequests.push(this.plex.getSectionData(sectionKey)); + } + if (_.isEqual(this.config.libraryName, 'Deck')) { + loadDataRequests.push(getOnDeck()); + } else if (_.isEqual(this.config.libraryName, 'Continue Watching')) { + loadDataRequests.push(getContinueWatching()); + } else if (_.isEqual(this.config.libraryName, 'Watch Next')) { + loadDataRequests.push(getWatchNext()); + } else if (_.isEqual(this.config.libraryName, 'Recently Added')) { + loadDataRequests.push(getRecentyAdded()); + } + + const [plexSections] = await Promise.all(loadDataRequests); + + if (plexSections && sectionKey) { + _.forEach(plexSections, section => { + this.data[section.title1] = section.Metadata; + }); + } if (this.data[this.config.libraryName] === undefined) { this.error = `Library name ${this.config.libraryName} does not exist.`;