From a97f017722183c310e6e6666b23bcbbe5246a0f3 Mon Sep 17 00:00:00 2001 From: Luke Hagar Date: Fri, 29 Jul 2022 22:54:09 -0500 Subject: [PATCH] RFC Compat testing --- package-lock.json | 4 +- package.json | 2 +- src/PlexAPIOAuth/PlexAPIOAuth.js | 1788 ++++++++++++++---------------- src/index.js | 23 +- test/index.test.js | 357 +++--- 5 files changed, 1056 insertions(+), 1118 deletions(-) diff --git a/package-lock.json b/package-lock.json index f890fb7..f1e955f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "plex-api-oauth", - "version": "1.1.10", + "version": "1.1.46", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "plex-api-oauth", - "version": "1.1.10", + "version": "1.1.46", "license": "MIT", "dependencies": { "axios": "^0.27.2", diff --git a/package.json b/package.json index c126db5..8c631ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "plex-api-oauth", - "version": "1.1.46", + "version": "1.1.58", "description": "An NPM Module designed to make Plex Media Server and plex.tv API calls easier to implement in JavaScript and React projects", "main": "./src/index.js", "type": "module", diff --git a/src/PlexAPIOAuth/PlexAPIOAuth.js b/src/PlexAPIOAuth/PlexAPIOAuth.js index 5fba485..c7beac2 100644 --- a/src/PlexAPIOAuth/PlexAPIOAuth.js +++ b/src/PlexAPIOAuth/PlexAPIOAuth.js @@ -2,1042 +2,942 @@ import { PlexOauth } from "plex-oauth"; import { v4 } from "uuid"; import axios from "axios"; import qs from "qs"; -import InfiniteScroll from "react-infinite-scroller"; +// import InfiniteScroll from "react-infinite-scroller"; import { useState, useEffect } from "react"; -export class PlexAPIOAuth { - plexClientInformation; - clientId; - product; - device; - version; - forwardUrl; - platform; - plexTVAuthToken; - plexTVUserData; - plexServers; - plexLibraries; - plexDevices; - cancelToken; - constructor( - clientId = "", - product = "Plex-API-OAuth", - device = "Web-Client", - version = "1", - forwardUrl = "", - platform = "Web", - plexTVAuthToken = "", - plexTVUserData = {}, - plexServers = [], - plexLibraries = [], - plexDevices = [], - cancelToken = null - ) { - this.clientId = clientId; - this.product = product; - this.device = device; - this.version = version; - this.forwardUrl = forwardUrl; - this.platform = platform; - this.plexTVAuthToken = plexTVAuthToken; - this.plexTVUserData = plexTVUserData; - this.plexServers = plexServers; - this.plexDevices = plexDevices; - this.plexLibraries = plexLibraries; - this.cancelToken = cancelToken; +export async function PlexLogin(plexClientInformation) { + var plexOauth = new PlexOauth(plexClientInformation); + let data = await plexOauth.requestHostedLoginURL().catch((err) => { + throw err; + }); - this.plexClientInformation = { - clientIdentifier: this.clientId, // This is a unique identifier used to identify your app with Plex. - If none is provided a new one is generated and saved locally - product: this.product, // Name of your application - Defaults to Plex-API-OAuth - device: this.device, // The type of device your application is running on - Defaults to "Web Client" - version: this.version, // Version of your application - Defaults to 1 - forwardUrl: this.forwardUrl, // Url to forward back to after signing in - Defaults to an empty string - platform: this.platform, // Platform your application runs on - Defaults to 'Web' - }; + let [hostedUILink, pinId] = data; + + console.log("Plex Auth URL:"); + console.log(hostedUILink); // UI URL used to log into Plex + + if (typeof window !== "undefined") { + window.open(hostedUILink, "_blank"); + window.focus(); } - onlyUnique(value, index, self) { - return self.indexOf(value) === index; - } - - PlexLogout() { - this.clientId = ""; - this.product = "Plex-API-OAuth"; - this.device = "Web-Client"; - this.version = "1"; - this.forwardUrl = ""; - this.platform = "Web"; - this.plexTVAuthToken = ""; - this.plexTVUserData = {}; - this.plexServers = []; - this.plexLibraries = []; - this.plexDevices = []; - this.plexClientInformation = { - clientIdentifier: this.clientId, // This is a unique identifier used to identify your app with Plex. - If none is provided a new one is generated and saved locally - product: this.product, // Name of your application - Defaults to Plex-API-OAuth - device: this.device, // The type of device your application is running on - Defaults to "Web Client" - version: this.version, // Version of your application - Defaults to 1 - forwardUrl: this.forwardUrl, // Url to forward back to after signing in - Defaults to an empty string - platform: this.platform, // Platform your application runs on - Defaults to 'Web' - }; - } - - SetPlexSession({ - clientId = "", - product = "Plex-API-OAuth", - device = "Web-Client", - version = "1", - forwardUrl = "", - platform = "Web", - plexTVAuthToken = "", - plexTVUserData = {}, - plexServers = [], - plexDevices = [], - plexLibraries = [], - plexLibraryContent = [], - }) { - this.plexTVAuthToken = plexTVAuthToken; - this.plexTVUserData = plexTVUserData; - this.clientId = clientId; - this.product = product; - this.device = device; - this.version = version; - this.forwardUrl = forwardUrl; - this.platform = platform; - this.plexServers = plexServers; - this.plexDevices = plexDevices; - this.plexLibraries = plexLibraries; - this.plexClientInformation = { - clientIdentifier: this.clientId, // This is a unique identifier used to identify your app with Plex. - If none is provided a new one is generated and saved locally - product: this.product, // Name of your application - Defaults to Plex-API-OAuth - device: this.device, // The type of device your application is running on - Defaults to "Web Client" - version: this.version, // Version of your application - Defaults to 1 - forwardUrl: this.forwardUrl, // Url to forward back to after signing in - Defaults to an empty string - platform: this.platform, // Platform your application runs on - Defaults to 'Web' - }; - } - - SavePlexSession() { - window.localStorage.setItem( - "plexSessionData", - JSON.stringify({ - plexTVAuthToken: this.plexTVAuthToken, - plexTVUserData: this.plexTVUserData, - clientId: this.clientId, - product: this.product, - device: this.device, - version: this.version, - forwardUrl: this.forwardUrl, - platform: this.platform, - plexServers: this.plexServers, - plexDevices: this.plexDevices, - plexLibraries: this.plexLibraries, - plexClientInformation: this.plexClientInformation, - }) - ); - } - - LoadPlexSession() { - this.SetPlexSession( - JSON.parse(window.localStorage?.getItem("plexSessionData") || "{}") - ); - } - - fnBrowserDetect() { - let userAgent = navigator.userAgent; - let browserName; - - if (userAgent.match(/chrome|chromium|crios/i)) { - browserName = "chrome"; - } else if (userAgent.match(/firefox|fxios/i)) { - browserName = "firefox"; - } else if (userAgent.match(/safari/i)) { - browserName = "safari"; - } else if (userAgent.match(/opr\//i)) { - browserName = "opera"; - } else if (userAgent.match(/edg/i)) { - browserName = "edge"; - } else { - browserName = "No browser detection"; - } - return browserName; - } - - GenerateClientId() { - this.clientId = v4(); - this.plexClientInformation.clientIdentifier = this.clientId; - } - - GenerateClientInformation() { - if (typeof navigator !== "undefined") { - this.clientId = v4(); - this.product = this.fnBrowserDetect; - this.device = navigator.userAgentData.platform; - this.version = navigator.userAgentData.brands[0].version; - this.plexClientInformation = { - clientIdentifier: this.clientId, - product: this.product, - device: this.device, - version: this.version, - forwardUrl: this.forwardUrl, - platform: this.platform, - }; - console.log("Client Information generated successfully"); - } - throw "Unable to detect Client"; - } - - async PlexLogin() { - var plexOauth = new PlexOauth(this.plexClientInformation); - let data = await plexOauth.requestHostedLoginURL().catch((err) => { + let authToken = await plexOauth + .checkForAuthToken(pinId, 1000, 10) + .catch((err) => { throw err; }); - let [hostedUILink, pinId] = data; + if (authToken !== null) { + console.log("Plex Authentication Successful"); + } else { + console.log("Plex Authentication Failed"); + } + return authToken; + // An auth token will only be null if the user never signs into the hosted UI, or you stop checking for a new one before they can log in +} - console.log("Plex Auth URL:"); - console.log(hostedUILink); // UI URL used to log into Plex - - if (typeof window !== "undefined") { - window.open(hostedUILink, "_blank"); - window.focus(); - } - - /* - * You can now navigate the user's browser to the 'hostedUILink'. This will include the forward URL - * for your application, so when they have finished signing into Plex, they will be redirected back - * to the specified URL. From there, you just need to perform a query to check for the auth token. - * (See Below) - */ - - // Check for the auth token, once returning to the application - - let authToken = await plexOauth - .checkForAuthToken(pinId, 1000, 10) - .catch((err) => { - throw err; - }); - - if (authToken !== null) { - this.plexTVAuthToken = authToken; - console.log("Plex Authentication Successful"); - return authToken; +export async function GetPlexUserData(plexClientInformation, plexTVAuthToken) { + let response = await axios({ + method: "GET", + url: + "https://plex.tv/api/v2/user?" + + qs.stringify({ + "X-Plex-Product": plexClientInformation.product, + "X-Plex-Client-Identifier": plexClientInformation.clientIdentifier, + "X-Plex-Token": plexTVAuthToken, + }), + headers: { accept: "application/json" }, + }).catch(function (error) { + if (error.response) { + console.log(error.response.data); + console.log(error.response.status); + console.log(error.response.headers); + } else if (error.request) { + console.log(error.request); } else { - console.log("Plex Authentication Failed"); - return authToken; + console.log("Error", error.message); } - // An auth token will only be null if the user never signs into the hosted UI, or you stop checking for a new one before they can log in - } + console.log(error.config); + }); - async GetPlexUserData() { - let response = await axios({ - method: "GET", - url: - "https://plex.tv/api/v2/user?" + - qs.stringify({ - "X-Plex-Product": this.plexClientInformation.product, - "X-Plex-Client-Identifier": - this.plexClientInformation.clientIdentifier, - "X-Plex-Token": this.plexTVAuthToken, - }), - headers: { accept: "application/json" }, - }).catch(function (error) { - if (error.response) { - console.log(error.response.data); - console.log(error.response.status); - console.log(error.response.headers); - } else if (error.request) { - console.log(error.request); - } else { - console.log("Error", error.message); + if (response?.status === 200) { + return response.data; + } + if (response?.status === 401) { + return null; + } +} + +export async function GetPlexDevices(plexClientInformation, plexAuthToken) { + let serverArray = []; + let response = await axios({ + method: "GET", + url: + "https://plex.tv/api/v2/resources?" + + qs.stringify({ + includeHttps: 1, + includeRelay: 1, + includeIPv6: 1, + "X-Plex-Product": plexClientInformation.product, + "X-Plex-Client-Identifier": plexClientInformation.clientIdentifier, + "X-Plex-Token": plexTVAuthToken, + }), + headers: { accept: "application/json" }, + }).catch((err) => { + throw err; + }); + return response.data; +} + +export async function GetPlexServers(plexClientInformation, plexTVAuthToken) { + let serverArray = []; + let response = await axios({ + method: "GET", + url: + "https://plex.tv/api/v2/resources?" + + qs.stringify({ + includeHttps: 1, + includeRelay: 1, + includeIPv6: 1, + "X-Plex-Product": plexClientInformation.product, + "X-Plex-Client-Identifier": plexClientInformation.clientIdentifier, + "X-Plex-Token": plexTVAuthToken, + }), + headers: { accept: "application/json" }, + }).catch((err) => { + throw err; + }); + for (const server of response.data.filter( + (Obj) => Obj.product === "Plex Media Server" + )) { + let localConnection = null; + let serverCapabilities = null; + let preferredConnection = server.connections.filter( + (connection) => connection.relay === true + )[0]; + for (const connection of server.connections.filter( + (entry) => entry.local === true + )) { + if (localConnection === null && serverCapabilities === null) { + try { + let response = await axios({ + method: "GET", + url: + connection.uri + + "/?" + + qs.stringify({ "X-Plex-Token": server.accessToken }), + timeout: 1000, + }); + localConnection = connection; + serverCapabilities = response.data.MediaContainer; + preferredConnection = connection; + } catch {} } - console.log(error.config); + } + serverArray.push({ + name: server.name, + product: server.product, + productVersion: server.productVersion, + platform: server.platform, + platformVersion: server.platformVersion, + device: server.device, + clientIdentifier: server.clientIdentifier, + createdAt: server.createdAt, + lastSeenAt: server.lastSeenAt, + localConnection: localConnection, + preferredConnection: preferredConnection, + provides: server.provides, + ownerId: server.ownerId, + sourceTitle: server.sourceTitle, + publicAddress: server.publicAddress, + accessToken: server.accessToken, + owned: server.owned, + home: server.home, + synced: server.synced, + relay: server.relay, + relayConnection: server.connections.filter( + (connection) => connection.relay === true + )[0], + serverCapabilities: serverCapabilities, + presence: server.presence, + httpsRequired: server.httpsRequired, + publicAddressMatches: server.publicAddressMatches, + dnsRebindingProtection: server.dnsRebindingProtection, + natLoopbackSupported: server.natLoopbackSupported, + connections: server.connections, }); - - if (response.status === 200) { - this.plexTVUserData = response.data; - return this.plexTVUserData; - } - if (response.status === 401) { - return null; - } } + return serverArray; +} - async GetPlexServers(searchParams = {}, filter = {}) { - let serverArray = []; +export async function GetPlexLibraries(servers) { + let libraryArray = []; + if (typeof servers === Object) { + console.log("Single Object Detected"); + } + for (const server of servers) { + let connectionUri = server.relayConnection; + if (server.localConnection) { + connectionUri = server.localConnection; + } let response = await axios({ method: "GET", url: - "https://plex.tv/api/v2/resources?" + + connectionUri.uri + + "/library/sections/?" + qs.stringify({ - ...searchParams, - includeHttps: 1, - includeRelay: 1, - includeIPv6: 1, - "X-Plex-Product": this.plexClientInformation.product, - "X-Plex-Client-Identifier": - this.plexClientInformation.clientIdentifier, - "X-Plex-Token": this.plexTVAuthToken, + "X-Plex-Token": server.accessToken, }), headers: { accept: "application/json" }, }).catch((err) => { throw err; }); - this.plexDevices = response.data; - for (const server of response.data - .filter((Obj) => Obj.product === "Plex Media Server") - .filter((Obj) => { - for (var key in filter) { - if (Obj[key] === filter[key]) { - return Obj; - } - } - })) { - let localConnection = null; - let serverCapabilities = null; - let preferredConnection = server.connections.filter( - (connection) => connection.relay === true - )[0]; - for (const connection of server.connections.filter( - (entry) => entry.local === true - )) { - if (localConnection === null && serverCapabilities === null) { - try { - let response = await axios({ - method: "GET", - url: - connection.uri + - "/?" + - qs.stringify({ "X-Plex-Token": server.accessToken }), - timeout: 1000, - }); - localConnection = connection; - serverCapabilities = response.data.MediaContainer; - preferredConnection = connection; - } catch {} - } - } - serverArray.push({ - name: server.name, - product: server.product, - productVersion: server.productVersion, - platform: server.platform, - platformVersion: server.platformVersion, - device: server.device, - clientIdentifier: server.clientIdentifier, - createdAt: server.createdAt, - lastSeenAt: server.lastSeenAt, - localConnection: localConnection, - preferredConnection: preferredConnection, - provides: server.provides, - ownerId: server.ownerId, - sourceTitle: server.sourceTitle, - publicAddress: server.publicAddress, - accessToken: server.accessToken, - owned: server.owned, - home: server.home, - synced: server.synced, - relay: server.relay, - relayConnection: server.connections.filter( - (connection) => connection.relay === true - )[0], - serverCapabilities: serverCapabilities, - presence: server.presence, - httpsRequired: server.httpsRequired, - publicAddressMatches: server.publicAddressMatches, - dnsRebindingProtection: server.dnsRebindingProtection, - natLoopbackSupported: server.natLoopbackSupported, - connections: server.connections, + for (const library of response.data.MediaContainer.Directory) { + libraryArray.push({ + server: server, + allowSync: library.allowSync, + art: library.art, + composite: library.composite, + filters: library.filters, + refreshing: library.refreshing, + thumb: library.thumb, + key: library.key, + type: library.type, + title: library.title, + agent: library.agent, + scanner: library.scanner, + language: library.language, + uuid: library.uuid, + updatedAt: library.updatedAt, + createdAt: library.createdAt, + scannedAt: library.scannedAt, + content: library.content, + directory: library.directory, + contentChangedAt: library.contentChangedAt, + hidden: library.hidden, + Location: library.Location, }); } - this.plexServers = serverArray; - return serverArray; } + return libraryArray; +} - async GetPlexLibraries(servers = this.plexServers) { - let libraryArray = []; - for (const server of servers) { - let connectionUri = server.relayConnection; - if (server.localConnection) { - connectionUri = server.localConnection; - } +export async function GetPlexMovieLibraries(servers) { + let libraryArray = []; + for (const server of servers) { + let connectionUri = server.relayConnection; + if (server.localConnection) { + connectionUri = server.localConnection; + } + let response = await axios({ + method: "GET", + url: + connectionUri.uri + + "/library/sections/?" + + qs.stringify({ + "X-Plex-Token": server.accessToken, + }), + headers: { accept: "application/json" }, + }).catch((err) => { + throw err; + }); + for (const library of response.data.MediaContainer.Directory.filter( + (Obj) => Obj.type === "movie" + )) { + libraryArray.push({ + server: server, + allowSync: library.allowSync, + art: library.art, + composite: library.composite, + filters: library.filters, + refreshing: library.refreshing, + thumb: library.thumb, + key: library.key, + type: library.type, + title: library.title, + agent: library.agent, + scanner: library.scanner, + language: library.language, + uuid: library.uuid, + updatedAt: library.updatedAt, + createdAt: library.createdAt, + scannedAt: library.scannedAt, + content: library.content, + directory: library.directory, + contentChangedAt: library.contentChangedAt, + hidden: library.hidden, + Location: library.Location, + }); + } + } + return libraryArray; +} + +export async function GetPlexMusicLibraries(servers) { + let libraryArray = []; + for (const server of servers) { + let connectionUri = server.relayConnection; + if (server.localConnection) { + connectionUri = server.localConnection; + } + let response = await axios({ + method: "GET", + url: + connectionUri.uri + + "/library/sections/?" + + qs.stringify({ + "X-Plex-Token": server.accessToken, + }), + headers: { accept: "application/json" }, + }).catch((err) => { + throw err; + }); + for (const library of response.data.MediaContainer.Directory.filter( + (Obj) => Obj.type === "artist" + )) { + libraryArray.push({ + server: server, + allowSync: library.allowSync, + art: library.art, + composite: library.composite, + filters: library.filters, + refreshing: library.refreshing, + thumb: library.thumb, + key: library.key, + type: library.type, + title: library.title, + agent: library.agent, + scanner: library.scanner, + language: library.language, + uuid: library.uuid, + updatedAt: library.updatedAt, + createdAt: library.createdAt, + scannedAt: library.scannedAt, + content: library.content, + directory: library.directory, + contentChangedAt: library.contentChangedAt, + hidden: library.hidden, + Location: library.Location, + }); + } + } + return libraryArray; +} + +export async function GetPlexTVShowLibraries(servers) { + let libraryArray = []; + for (const server of servers) { + let connectionUri = server.relayConnection; + if (server.localConnection) { + connectionUri = server.localConnection; + } + let response = await axios({ + method: "GET", + url: + connectionUri.uri + + "/library/sections/?" + + qs.stringify({ + "X-Plex-Token": server.accessToken, + }), + headers: { accept: "application/json" }, + }).catch((err) => { + throw err; + }); + for (const library of response.data.MediaContainer.Directory.filter( + (Obj) => Obj.type === "show" + )) { + libraryArray.push({ + server: server, + allowSync: library.allowSync, + art: library.art, + composite: library.composite, + filters: library.filters, + refreshing: library.refreshing, + thumb: library.thumb, + key: library.key, + type: library.type, + title: library.title, + agent: library.agent, + scanner: library.scanner, + language: library.language, + uuid: library.uuid, + updatedAt: library.updatedAt, + createdAt: library.createdAt, + scannedAt: library.scannedAt, + content: library.content, + directory: library.directory, + contentChangedAt: library.contentChangedAt, + hidden: library.hidden, + Location: library.Location, + }); + } + } + return libraryArray; +} + +export async function GetPlexMovies(searchParams = {}, servers, libraries) { + let movieLibraryContent = []; + for (const server of servers) { + let connectionUri = server.relayConnection; + if (server.localConnection) { + connectionUri = server.localConnection; + } + for (const library of libraries.filter( + (Obj) => + Obj.server.clientIdentifier === server.clientIdentifier && + Obj.type === "movie" + )) { let response = await axios({ method: "GET", - url: - connectionUri.uri + - "/library/sections/?" + - qs.stringify({ - "X-Plex-Token": server.accessToken, - }), + url: connectionUri.uri + "/library/sections/" + library?.key + "/all", + params: { + type: 1, + ...searchParams, + "X-Plex-Token": server?.accessToken, + }, + cancelToken: axios.CancelToken((c) => (cancelToken = c)), headers: { accept: "application/json" }, + }).catch((e) => { + if (axios.isCancel(e)) return; + throw e; + }); + for (const data of response.data.MediaContainer.Metadata) { + movieLibraryContent.push({ + server: server, + library: library, + ratingKey: data.ratingKey, + key: data.key, + guid: data.guid, + studio: data.studio, + type: data.type, + title: data.title, + contentRating: data.contentRating, + summary: data.summary, + rating: data.rating, + audienceRating: data.audienceRating, + year: data.year, + tagline: data.tagline, + thumb: data.thumb, + art: data.art, + duration: data.duration, + originallyAvailableAt: data.originallyAvailableAt, + addedAt: data.addedAt, + updatedAt: data.updatedAt, + audienceRatingImage: data.audienceRatingImage, + primaryExtraKey: data.primaryExtraKey, + ratingImage: data.ratingImage, + Media: data.Media, + Genre: data.Genre, + Director: data.Director, + Writer: data.Writer, + Country: data.Country, + Role: data.Role, + }); + } + } + } + return movieLibraryContent; +} + +export async function GetPlexArtists(searchParams = {}, servers, libraries) { + let artistLibraryContent = []; + for (const server of servers) { + let connectionUri = server.relayConnection; + if (server.localConnection) { + connectionUri = server.localConnection; + } + for (const library of libraries.filter( + (Obj) => + Obj.server.clientIdentifier === server.clientIdentifier && + Obj.type === "artist" + )) { + let response = await axios({ + method: "GET", + url: connectionUri.uri + "/library/sections/" + library?.key + "/all", + headers: { accept: "application/json" }, + params: { + type: 8, + ...searchParams, + "X-Plex-Token": server.accessToken, + }, + cancelToken: axios.CancelToken((c) => (cancelToken = c)), }).catch((err) => { throw err; }); - for (const library of response.data.MediaContainer.Directory) { - libraryArray.push({ + for (const data of response.data.MediaContainer.Metadata) { + artistLibraryContent.push({ server: server, - allowSync: library.allowSync, - art: library.art, - composite: library.composite, - filters: library.filters, - refreshing: library.refreshing, - thumb: library.thumb, - key: library.key, - type: library.type, - title: library.title, - agent: library.agent, - scanner: library.scanner, - language: library.language, - uuid: library.uuid, - updatedAt: library.updatedAt, - createdAt: library.createdAt, - scannedAt: library.scannedAt, - content: library.content, - directory: library.directory, - contentChangedAt: library.contentChangedAt, - hidden: library.hidden, - Location: library.Location, + library: library, + ratingKey: data.ratingKey, + key: data.key, + guid: data.guid, + type: data.type, + title: data.title, + summary: data.summary, + index: data.index, + thumb: data.thumb, + art: data.art, + addedAt: data.addedAt, + updatedAt: data.updatedAt, + Genre: data.Genre, + Country: data.Country, }); } } - this.plexLibraries = libraryArray; - return this.plexLibraries; } - async GetPlexMovieLibraries(servers = this.plexServers) { - let libraryArray = []; - for (const server of servers) { - let connectionUri = server.relayConnection; - if (server.localConnection) { - connectionUri = server.localConnection; - } + return artistLibraryContent; +} + +export async function GetPlexAlbums( + searchParams = {}, + servers, + libraries, + cancelToken +) { + let albumLibraryContent = []; + for (const server of servers) { + let connectionUri = server.relayConnection; + if (server.localConnection) { + connectionUri = server.localConnection; + } + for (const library of libraries.filter( + (Obj) => + Obj.server.clientIdentifier === server.clientIdentifier && + Obj.type === "artist" + )) { let response = await axios({ method: "GET", - url: - connectionUri.uri + - "/library/sections/?" + - qs.stringify({ - "X-Plex-Token": server.accessToken, - }), + url: connectionUri.uri + "/library/sections/" + library?.key + "/all", headers: { accept: "application/json" }, + params: { + type: 9, + ...searchParams, + "X-Plex-Token": server.accessToken, + }, + cancelToken: axios.CancelToken((c) => this.props.getCancelToken(c)), }).catch((err) => { throw err; }); - for (const library of response.data.MediaContainer.Directory.filter( - (Obj) => Obj.type === "movie" - )) { - libraryArray.push({ + for (const data of response.data.MediaContainer.Metadata) { + albumLibraryContent.push({ server: server, - allowSync: library.allowSync, - art: library.art, - composite: library.composite, - filters: library.filters, - refreshing: library.refreshing, - thumb: library.thumb, - key: library.key, - type: library.type, - title: library.title, - agent: library.agent, - scanner: library.scanner, - language: library.language, - uuid: library.uuid, - updatedAt: library.updatedAt, - createdAt: library.createdAt, - scannedAt: library.scannedAt, - content: library.content, - directory: library.directory, - contentChangedAt: library.contentChangedAt, - hidden: library.hidden, - Location: library.Location, + library: library, + addedAt: data.addedAt, + guid: data.guid, + index: data.index, + key: data.key, + loudnessAnalysisVersion: data.loudnessAnalysisVersion, + musicAnalysisVersion: data.musicAnalysisVersion, + originallyAvailableAt: data.originallyAvailableAt, + parentGuid: data.parentGuid, + parentKey: data.parentKey, + parentRatingKey: data.parentRatingKey, + parentThumb: data.parentThumb, + parentTitle: data.parentTitle, + ratingKey: data.ratingKey, + summary: data.summary, + thumb: data.thumb, + title: data.title, + type: data.type, + updatedAt: data.updatedAt, + year: data.year, }); } } - return libraryArray; } + return albumLibraryContent; +} - async GetPlexMusicLibraries(servers = this.plexServers) { - let libraryArray = []; - for (const server of servers) { - let connectionUri = server.relayConnection; - if (server.localConnection) { - connectionUri = server.localConnection; - } +export async function GetPlexSongs(searchParams = {}, servers, libraries) { + let songLibraryContent = []; + for (const server of servers) { + let connectionUri = server.relayConnection; + if (server.localConnection) { + connectionUri = server.localConnection; + } + for (const library of libraries.filter( + (Obj) => + Obj.server.clientIdentifier === server.clientIdentifier && + Obj.type === "artist" + )) { let response = await axios({ method: "GET", - url: - connectionUri.uri + - "/library/sections/?" + - qs.stringify({ - "X-Plex-Token": server.accessToken, - }), + url: connectionUri.uri + "/library/sections/" + library?.key + "/all", headers: { accept: "application/json" }, + params: { + type: 10, + ...searchParams, + "X-Plex-Token": server.accessToken, + }, + cancelToken: axios.CancelToken((c) => (cancelToken = c)), }).catch((err) => { + if (axios.isCancel(err)) return; throw err; }); - for (const library of response.data.MediaContainer.Directory.filter( - (Obj) => Obj.type === "artist" - )) { - libraryArray.push({ - server: server, - allowSync: library.allowSync, - art: library.art, - composite: library.composite, - filters: library.filters, - refreshing: library.refreshing, - thumb: library.thumb, - key: library.key, - type: library.type, - title: library.title, - agent: library.agent, - scanner: library.scanner, - language: library.language, - uuid: library.uuid, - updatedAt: library.updatedAt, - createdAt: library.createdAt, - scannedAt: library.scannedAt, - content: library.content, - directory: library.directory, - contentChangedAt: library.contentChangedAt, - hidden: library.hidden, - Location: library.Location, - }); - } - } - return libraryArray; - } - - async GetPlexTVShowLibraries(servers = this.plexServers) { - let libraryArray = []; - for (const server of servers) { - let connectionUri = server.relayConnection; - if (server.localConnection) { - connectionUri = server.localConnection; - } - let response = await axios({ - method: "GET", - url: - connectionUri.uri + - "/library/sections/?" + - qs.stringify({ - "X-Plex-Token": server.accessToken, - }), - headers: { accept: "application/json" }, - }).catch((err) => { - throw err; - }); - for (const library of response.data.MediaContainer.Directory.filter( - (Obj) => Obj.type === "show" - )) { - libraryArray.push({ - server: server, - allowSync: library.allowSync, - art: library.art, - composite: library.composite, - filters: library.filters, - refreshing: library.refreshing, - thumb: library.thumb, - key: library.key, - type: library.type, - title: library.title, - agent: library.agent, - scanner: library.scanner, - language: library.language, - uuid: library.uuid, - updatedAt: library.updatedAt, - createdAt: library.createdAt, - scannedAt: library.scannedAt, - content: library.content, - directory: library.directory, - contentChangedAt: library.contentChangedAt, - hidden: library.hidden, - Location: library.Location, - }); - } - } - return libraryArray; - } - - async GetPlexMovies( - searchParams = {}, - servers = this.plexServers, - libraries = this.plexLibraries - ) { - let movieLibraryContent = []; - for (const server of servers) { - let connectionUri = server.relayConnection; - if (server.localConnection) { - connectionUri = server.localConnection; - } - for (const library of libraries.filter( - (Obj) => - Obj.server.clientIdentifier === server.clientIdentifier && - Obj.type === "movie" - )) { - let response = await axios({ - method: "GET", - url: connectionUri.uri + "/library/sections/" + library?.key + "/all", - params: { - type: 1, - ...searchParams, - "X-Plex-Token": server?.accessToken, - }, - cancelToken: axios.CancelToken((c) => (this.cancelToken = c)), - headers: { accept: "application/json" }, - }).catch((e) => { - if (axios.isCancel(e)) return; - throw e; - }); + console.log(response); + try { for (const data of response.data.MediaContainer.Metadata) { - movieLibraryContent.push({ + songLibraryContent.push({ server: server, library: library, ratingKey: data.ratingKey, key: data.key, - guid: data.guid, - studio: data.studio, - type: data.type, - title: data.title, - contentRating: data.contentRating, - summary: data.summary, - rating: data.rating, - audienceRating: data.audienceRating, - year: data.year, - tagline: data.tagline, - thumb: data.thumb, - art: data.art, - duration: data.duration, - originallyAvailableAt: data.originallyAvailableAt, - addedAt: data.addedAt, - updatedAt: data.updatedAt, - audienceRatingImage: data.audienceRatingImage, - primaryExtraKey: data.primaryExtraKey, - ratingImage: data.ratingImage, - Media: data.Media, - Genre: data.Genre, - Director: data.Director, - Writer: data.Writer, - Country: data.Country, - Role: data.Role, - }); - } - } - } - return movieLibraryContent; - } - - async GetPlexArtists( - searchParams = {}, - servers = this.plexServers, - libraries = this.plexLibraries - ) { - let artistLibraryContent = []; - for (const server of servers) { - let connectionUri = server.relayConnection; - if (server.localConnection) { - connectionUri = server.localConnection; - } - for (const library of libraries.filter( - (Obj) => - Obj.server.clientIdentifier === server.clientIdentifier && - Obj.type === "artist" - )) { - let response = await axios({ - method: "GET", - url: connectionUri.uri + "/library/sections/" + library?.key + "/all", - headers: { accept: "application/json" }, - params: { - type: 8, - ...searchParams, - "X-Plex-Token": server.accessToken, - }, - cancelToken: axios.CancelToken((c) => (this.cancelToken = c)), - }).catch((err) => { - throw err; - }); - for (const data of response.data.MediaContainer.Metadata) { - artistLibraryContent.push({ - server: server, - library: library, - ratingKey: data.ratingKey, - key: data.key, - guid: data.guid, - type: data.type, - title: data.title, - summary: data.summary, - index: data.index, - thumb: data.thumb, - art: data.art, - addedAt: data.addedAt, - updatedAt: data.updatedAt, - Genre: data.Genre, - Country: data.Country, - }); - } - } - } - - return artistLibraryContent; - } - - async GetPlexAlbums( - searchParams = {}, - servers = this.plexServers, - libraries = this.plexLibraries - ) { - let albumLibraryContent = []; - for (const server of servers) { - let connectionUri = server.relayConnection; - if (server.localConnection) { - connectionUri = server.localConnection; - } - for (const library of libraries.filter( - (Obj) => - Obj.server.clientIdentifier === server.clientIdentifier && - Obj.type === "artist" - )) { - let response = await axios({ - method: "GET", - url: connectionUri.uri + "/library/sections/" + library?.key + "/all", - headers: { accept: "application/json" }, - params: { - type: 9, - ...searchParams, - "X-Plex-Token": server.accessToken, - }, - cancelToken: axios.CancelToken((c) => (this.cancelToken = c)), - }).catch((err) => { - throw err; - }); - for (const data of response.data.MediaContainer.Metadata) { - albumLibraryContent.push({ - server: server, - library: library, - addedAt: data.addedAt, - guid: data.guid, - index: data.index, - key: data.key, - loudnessAnalysisVersion: data.loudnessAnalysisVersion, - musicAnalysisVersion: data.musicAnalysisVersion, - originallyAvailableAt: data.originallyAvailableAt, - parentGuid: data.parentGuid, - parentKey: data.parentKey, parentRatingKey: data.parentRatingKey, - parentThumb: data.parentThumb, - parentTitle: data.parentTitle, - ratingKey: data.ratingKey, - summary: data.summary, - thumb: data.thumb, - title: data.title, - type: data.type, - updatedAt: data.updatedAt, - year: data.year, - }); - } - } - } - return albumLibraryContent; - } - - async GetPlexSongs( - searchParams = {}, - servers = this.plexServers, - libraries = this.plexLibraries - ) { - let songLibraryContent = []; - for (const server of servers) { - let connectionUri = server.relayConnection; - if (server.localConnection) { - connectionUri = server.localConnection; - } - for (const library of libraries.filter( - (Obj) => - Obj.server.clientIdentifier === server.clientIdentifier && - Obj.type === "artist" - )) { - let response = await axios({ - method: "GET", - url: connectionUri.uri + "/library/sections/" + library?.key + "/all", - headers: { accept: "application/json" }, - params: { - type: 10, - ...searchParams, - "X-Plex-Token": server.accessToken, - }, - cancelToken: axios.CancelToken((c) => (this.cancelToken = c)), - }).catch((err) => { - if (axios.isCancel(err)) return; - throw err; - }); - console.log(response); - try { - for (const data of response.data.MediaContainer.Metadata) { - songLibraryContent.push({ - server: server, - library: library, - ratingKey: data.ratingKey, - key: data.key, - parentRatingKey: data.parentRatingKey, - grandparentRatingKey: data.grandparentRatingKey, - guid: data.guid, - parentGuid: data.parentGuid, - grandparentGuid: data.grandparentGuid, - type: data.type, - title: data.title, - grandparentKey: data.grandparentKey, - parentKey: data.parentKey, - grandparentTitle: data.grandparentTitle, - parentTitle: data.parentTitle, - originalTitle: data.originalTitle, - summary: data.summary, - index: data.index, - parentIndex: data.parentIndex, - thumb: data.thumb, - parentThumb: data.parentThumb, - grandparentThumb: data.grandparentThumb, - duration: data.duration, - addedAt: data.addedAt, - updatedAt: data.updatedAt, - musicAnalysisVersion: data.musicAnalysisVersion, - Media: data.Media, - }); - } - } catch {} - } - } - return songLibraryContent; - } - - async GetPlexShows( - searchParams = {}, - servers = this.plexServers, - libraries = this.plexLibraries - ) { - let tvShowLibraryContent = []; - for (const server of servers) { - let connectionUri = server.relayConnection; - if (server.localConnection) { - connectionUri = server.localConnection; - } - for (const showLibrary of libraries.filter( - (Obj) => - Obj.server.clientIdentifier === server.clientIdentifier && - Obj.type === "show" - )) { - let response = await axios({ - method: "GET", - url: - connectionUri.uri + - "/library/sections/" + - showLibrary?.key + - "/all", - headers: { accept: "application/json" }, - params: { - type: 2, - ...searchParams, - "X-Plex-Token": server?.accessToken, - }, - cancelToken: axios.CancelToken((c) => (this.cancelToken = c)), - }).catch((err) => { - throw err; - }); - for (const data of response.data.MediaContainer.Metadata) { - tvShowLibraryContent.push({ - server: server, - library: showLibrary, - ratingKey: data.ratingKey, - key: data.key, + grandparentRatingKey: data.grandparentRatingKey, guid: data.guid, - studio: data.studio, + parentGuid: data.parentGuid, + grandparentGuid: data.grandparentGuid, type: data.type, title: data.title, - contentRating: data.contentRating, + grandparentKey: data.grandparentKey, + parentKey: data.parentKey, + grandparentTitle: data.grandparentTitle, + parentTitle: data.parentTitle, + originalTitle: data.originalTitle, summary: data.summary, index: data.index, - rating: data.rating, - audienceRating: data.audienceRating, - year: data.year, - tagline: data.tagline, + parentIndex: data.parentIndex, thumb: data.thumb, - art: data.art, - theme: data.theme, + parentThumb: data.parentThumb, + grandparentThumb: data.grandparentThumb, duration: data.duration, - originallyAvailableAt: data.originallyAvailableAt, - leafCount: data.leafCount, - viewedLeafCount: data.viewedLeafCount, - childCount: data.childCount, addedAt: data.addedAt, updatedAt: data.updatedAt, - audienceRatingImage: data.audienceRatingImage, - primaryExtraKey: data.primaryExtraKey, - ratingImage: data.ratingImage, + musicAnalysisVersion: data.musicAnalysisVersion, Media: data.Media, - Genre: data.Genre, - Country: data.Country, - Role: data.Role, }); } - } + } catch {} } - return tvShowLibraryContent; } + return songLibraryContent; +} - async GetPlexSeasons( - searchParams = {}, - servers = this.plexServers, - libraries = this.plexLibraries - ) { - let seasonArray = []; - for (const server of servers) { - let connectionUri = server.relayConnection; - if (server.localConnection) { - connectionUri = server.localConnection; - } - for (const showLibrary of libraries.filter( - (Obj) => - Obj.server.clientIdentifier === server.clientIdentifier && - Obj.type === "show" - )) { - let response = await axios({ - method: "GET", - url: - connectionUri.uri + - "/library/sections/" + - showLibrary?.key + - "/all", - headers: { accept: "application/json" }, - params: { - type: 3, - ...searchParams, - "X-Plex-Token": server?.accessToken, - }, - cancelToken: axios.CancelToken((c) => (this.cancelToken = c)), - }).catch((err) => { - throw err; +export async function GetPlexShows(searchParams = {}, servers, libraries) { + let tvShowLibraryContent = []; + for (const server of servers) { + let connectionUri = server.relayConnection; + if (server.localConnection) { + connectionUri = server.localConnection; + } + for (const showLibrary of libraries.filter( + (Obj) => + Obj.server.clientIdentifier === server.clientIdentifier && + Obj.type === "show" + )) { + let response = await axios({ + method: "GET", + url: + connectionUri.uri + "/library/sections/" + showLibrary?.key + "/all", + headers: { accept: "application/json" }, + params: { + type: 2, + ...searchParams, + "X-Plex-Token": server?.accessToken, + }, + cancelToken: axios.CancelToken((c) => (cancelToken = c)), + }).catch((err) => { + throw err; + }); + for (const data of response.data.MediaContainer.Metadata) { + tvShowLibraryContent.push({ + server: server, + library: showLibrary, + ratingKey: data.ratingKey, + key: data.key, + guid: data.guid, + studio: data.studio, + type: data.type, + title: data.title, + contentRating: data.contentRating, + summary: data.summary, + index: data.index, + rating: data.rating, + audienceRating: data.audienceRating, + year: data.year, + tagline: data.tagline, + thumb: data.thumb, + art: data.art, + theme: data.theme, + duration: data.duration, + originallyAvailableAt: data.originallyAvailableAt, + leafCount: data.leafCount, + viewedLeafCount: data.viewedLeafCount, + childCount: data.childCount, + addedAt: data.addedAt, + updatedAt: data.updatedAt, + audienceRatingImage: data.audienceRatingImage, + primaryExtraKey: data.primaryExtraKey, + ratingImage: data.ratingImage, + Media: data.Media, + Genre: data.Genre, + Country: data.Country, + Role: data.Role, }); - for (const season of response.data.MediaContainer.Metadata) { - seasonArray.push(season); - } } } - return seasonArray; } + return tvShowLibraryContent; +} - async GetPlexEpisodes( - searchParams = {}, - servers = this.plexServers, - libraries = this.plexLibraries - ) { - let episodeLibrary = []; - for (const server of servers) { - let connectionUri = server.relayConnection; - if (server.localConnection) { - connectionUri = server.localConnection; - } - for (const showLibrary of libraries.filter( - (Obj) => - Obj.server.clientIdentifier === server.clientIdentifier && - Obj.type === "show" - )) { - let response = await axios({ - method: "GET", - url: - connectionUri.uri + - "/library/sections/" + - showLibrary?.key + - "/all", - headers: { accept: "application/json" }, - params: { - type: 4, - ...searchParams, - "X-Plex-Token": server?.accessToken, - }, - cancelToken: axios.CancelToken((c) => (this.cancelToken = c)), - }).catch((err) => { - throw err; - }); - for (const episode of response.data.MediaContainer.Metadata) { - episodeLibrary.push(episode); - } +export async function GetPlexSeasons(searchParams = {}, servers, libraries) { + let seasonArray = []; + for (const server of servers) { + let connectionUri = server.relayConnection; + if (server.localConnection) { + connectionUri = server.localConnection; + } + for (const showLibrary of libraries.filter( + (Obj) => + Obj.server.clientIdentifier === server.clientIdentifier && + Obj.type === "show" + )) { + let response = await axios({ + method: "GET", + url: + connectionUri.uri + "/library/sections/" + showLibrary?.key + "/all", + headers: { accept: "application/json" }, + params: { + type: 3, + ...searchParams, + "X-Plex-Token": server?.accessToken, + }, + cancelToken: axios.CancelToken((c) => (cancelToken = c)), + }).catch((err) => { + throw err; + }); + for (const season of response.data.MediaContainer.Metadata) { + seasonArray.push(season); } } - return episodeLibrary; + } + return seasonArray; +} + +export async function GetPlexEpisodes(searchParams = {}, servers, libraries) { + let episodeLibrary = []; + for (const server of servers) { + let connectionUri = server.relayConnection; + if (server.localConnection) { + connectionUri = server.localConnection; + } + for (const showLibrary of libraries.filter( + (Obj) => + Obj.server.clientIdentifier === server.clientIdentifier && + Obj.type === "show" + )) { + let response = await axios({ + method: "GET", + url: + connectionUri.uri + "/library/sections/" + showLibrary?.key + "/all", + headers: { accept: "application/json" }, + params: { + type: 4, + ...searchParams, + "X-Plex-Token": server?.accessToken, + }, + cancelToken: axios.CancelToken((c) => (cancelToken = c)), + }).catch((err) => { + throw err; + }); + for (const episode of response.data.MediaContainer.Metadata) { + episodeLibrary.push(episode); + } + } + } + return episodeLibrary; +} + +export function fnBrowserDetect() { + let userAgent = navigator.userAgent; + let browserName; + + if (userAgent.match(/chrome|chromium|crios/i)) { + browserName = "chrome"; + } else if (userAgent.match(/firefox|fxios/i)) { + browserName = "firefox"; + } else if (userAgent.match(/safari/i)) { + browserName = "safari"; + } else if (userAgent.match(/opr\//i)) { + browserName = "opera"; + } else if (userAgent.match(/edg/i)) { + browserName = "edge"; + } else { + browserName = "No browser detection"; + } + return browserName; +} + +export function SavePlexSession(plexClientInformation, plexTVAuthToken) { + window.localStorage.setItem( + "plexSessionData", + JSON.stringify({ + plexClientInformation: plexClientInformation, + plexTVAuthToken: plexTVAuthToken, + }) + ); +} + +export function LoadPlexSession() { + return JSON.parse(window.localStorage?.getItem("plexSessionData") || "{}"); +} + +export function GeneratePlexClientInformation(forwardUrl = "") { + if (typeof navigator !== "undefined") { + let plexClientInformation = { + clientIdentifier: v4(), + product: fnBrowserDetect(), + device: navigator.userAgentData.platform, + version: navigator.userAgentData.brands[0].version, + forwardUrl: forwardUrl, + platform: "Plex-API-OAuth", + }; + console.log("Client Information generated successfully"); + return plexClientInformation; + } else { + throw "Unable to detect Client"; + } +} + +export function CreatePlexClientInformation( + clientIdentifier = v4(), + product = "Plex-API-OAuth", + device = "Web-Client", + version = "1", + forwardUrl = "", + platform = "Web" +) { + let plexClientInformation = { + clientIdentifier: clientIdentifier, + product: product, + device: device, + version: version, + forwardUrl: forwardUrl, + platform: platform, + }; + console.log("Client Information generated successfully"); + return plexClientInformation; +} + +export function GetLibraryPages( + servers, + libraries, + libraryType = "", + query = null, + pageNumber = 0, + chunkSize = 50 +) { + const [loading, setLoading] = useState(true); + const [error, setError] = useState(false); + const [items, setItems] = useState([]); + const [hasMore, setHasMore] = useState(false); + + let data = null; + + useEffect(() => { + setItems([]); + }, [query, libraryType]); + + const [cancelToken, setCancelToken] = useState(); + + function getCancelToken(event) { + setCancelToken(event); + event.preventDefault(); } - GetLibraryPages( - libraryType = "", - query = null, - pageNumber = 0, - chunkSize = 50 - ) { - const [loading, setLoading] = useState(true); - const [error, setError] = useState(false); - const [items, setItems] = useState([]); - const [hasMore, setHasMore] = useState(false); - - let data = null; - - useEffect(() => { - setItems([]); - }, [query, libraryType]); - - useEffect(() => { - setLoading(true); - setError(false); - let searchParams = { + useEffect(() => { + setLoading(true); + setError(false); + let searchParams = { + "X-Plex-Container-Start": pageNumber * chunkSize, + "X-Plex-Container-Size": chunkSize, + }; + if (query !== null) { + searchParams = { + title: query, "X-Plex-Container-Start": pageNumber * chunkSize, "X-Plex-Container-Size": chunkSize, }; - if (query !== null) { - searchParams = { - title: query, - "X-Plex-Container-Start": pageNumber * chunkSize, - "X-Plex-Container-Size": chunkSize, - }; - } + } - switch (libraryType) { - case "artists": - data = this.GetPlexArtists(searchParams); - break; - case "albums": - data = this.GetPlexAlbums(searchParams); - break; - case "songs": - data = this.GetPlexSongs(searchParams); - break; - case "shows": - data = this.GetPlexShows(searchParams); - break; - case "seasons": - data = this.GetPlexSeasons(searchParams); - break; - case "episodes": - data = this.GetPlexEpisodes(searchParams); - break; - case "movies": - data = this.GetPlexMovies(searchParams); - break; - } - try { - data - .then((finalData) => { - setItems((previousData) => { - return [...previousData, ...finalData]; - }); - setHasMore(finalData.length > 0); - setLoading(false); - console.log({ loading, error, items, hasMore }); - }) - .catch((e) => { - setError(e); + switch (libraryType) { + case "artists": + data = GetPlexArtists( + searchParams, + servers, + libraries, + this.getCancelToken.bind(this) + ); + break; + case "albums": + data = GetPlexAlbums( + searchParams, + servers, + libraries, + this.getCancelToken.bind(this) + ); + break; + case "songs": + data = GetPlexSongs( + searchParams, + servers, + libraries, + this.getCancelToken.bind(this) + ); + break; + case "shows": + data = GetPlexShows( + searchParams, + servers, + libraries, + this.getCancelToken.bind(this) + ); + break; + case "seasons": + data = PlexSession.GetPlexSeasons( + searchParams, + servers, + libraries, + this.getCancelToken.bind(this) + ); + break; + case "episodes": + data = GetPlexEpisodes( + searchParams, + servers, + libraries, + this.getCancelToken.bind(this) + ); + break; + case "movies": + data = GetPlexMovies( + searchParams, + servers, + libraries, + this.getCancelToken.bind(this) + ); + break; + } + try { + data + .then((finalData) => { + setItems((previousData) => { + return [...previousData, ...finalData]; }); - } catch {} - return () => { - if (this.cancelToken) { - this.cancelToken(); - } - }; - }, [query, pageNumber]); - return { loading, error, items, hasMore }; - } + setHasMore(finalData.length > 0); + setLoading(false); + console.log({ loading, error, items, hasMore }); + }) + .catch((e) => { + setError(e); + }); + } catch {} + return () => { + if (cancelToken) { + cancelToken(); + } + }; + }, [query, pageNumber]); + return { loading, error, items, hasMore }; } diff --git a/src/index.js b/src/index.js index c82b148..eca2e26 100644 --- a/src/index.js +++ b/src/index.js @@ -1 +1,22 @@ -export { PlexAPIOAuth } from "./PlexAPIOAuth/PlexAPIOAuth.js"; +export { + GeneratePlexClientInformation, + CreatePlexClientInformation, + PlexLogin, + GetPlexUserData, + GetPlexServers, + GetPlexMovies, + GetPlexShows, + GetPlexSeasons, + GetPlexEpisodes, + GetPlexMovieLibraries, + GetPlexMusicLibraries, + GetPlexTVShowLibraries, + GetPlexArtists, + GetPlexAlbums, + GetPlexSongs, + GetPlexLibraries, + GetPlexDevices, + GetLibraryPages, + LoadPlexSession, + SavePlexSession, +} from "./PlexAPIOAuth/PlexAPIOAuth.js"; diff --git a/test/index.test.js b/test/index.test.js index 73ac42c..c438083 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -1,177 +1,194 @@ -import { PlexAPIOAuth } from "../src/index.js"; import { strict as assert } from "assert"; +import { + CreatePlexClientInformation, + GeneratePlexClientInformation, + PlexLogin, + GetPlexUserData, +} from "../src/index.js"; +import React, { useState } from "React"; -describe("Unit Tests", function () { - let PlexSession = new PlexAPIOAuth(); - let emptyArray = []; - it("Generate ClientId", function () { - PlexSession.GenerateClientId(); - assert.notEqual(PlexSession.clientId, null); - assert.notEqual(PlexSession.clientId, undefined); - // console.log("Plex Session"); - // console.log(PlexSession); - }); - it("Login", async function () { - this.timeout(10000); - let response = await PlexSession.PlexLogin(); - assert.notEqual(PlexSession.plexTVAuthToken, undefined); - assert.notEqual(response, undefined); - // console.log("Auth Token"); - // console.log(PlexSession.plexTVAuthToken); - }); - it("Get Plex User Data", async function () { - this.timeout(5000); - let response = await PlexSession.GetPlexUserData(); - assert.notEqual(PlexSession.plexTVUserData, undefined); - assert.notEqual(response, undefined); - // console.log("User Data"); - // console.log(PlexSession.plexTVUserData); - }); - it("Get Plex Servers", async function () { - this.timeout(12000); - let response = await PlexSession.GetPlexServers({}, { owned: true }); - assert.notEqual(PlexSession.plexServers, emptyArray); - assert.notEqual(PlexSession.plexServers, null); - assert.notEqual(PlexSession.plexServers, undefined); - assert.notEqual(PlexSession.plexDevices, emptyArray); - assert.notEqual(PlexSession.plexDevices, null); - assert.notEqual(PlexSession.plexDevices, undefined); - assert.notEqual(response, emptyArray); - assert.notEqual(response, null); - assert.notEqual(response, undefined); - // console.log("Plex Servers"); - // console.log(PlexSession.plexServers); - }); - it("Get Plex Libraries", async function () { - this.timeout(10000); - let response = await PlexSession.GetPlexLibraries(); - assert.notEqual(PlexSession.plexLibraries, null); - assert.notEqual(PlexSession.plexLibraries, undefined); - assert.notEqual(PlexSession.plexLibraries, emptyArray); - assert.notEqual(response, emptyArray); - assert.notEqual(response, null); - assert.notEqual(response, undefined); - //console.log("Plex Libraries"); - //console.log(PlexSession.plexLibraries); - }); - it("Get Plex Movie Libraries", async function () { - this.timeout(20000); - let response = await PlexSession.GetPlexMovieLibraries(); - assert.notEqual(response, emptyArray); - assert.notEqual(response, null); - assert.notEqual(response, undefined); - // console.log("Plex Movie Libraries"); - // console.log(response); - }); - it("Get Plex Music Libraries", async function () { - this.timeout(10000); - let response = await PlexSession.GetPlexMusicLibraries(); - assert.notEqual(response, emptyArray); - assert.notEqual(response, null); - assert.notEqual(response, undefined); - // console.log("Plex Music Libraries"); - // console.log(response); - }); - it("Get Plex TV Libraries", async function () { - this.timeout(10000); - let response = await PlexSession.GetPlexTVShowLibraries(); - assert.notEqual(response, emptyArray); - assert.notEqual(response, null); - assert.notEqual(response, undefined); - // console.log("Plex TV Libraries"); - // console.log(response); - }); - it("Get Plex Movies", async function () { - this.timeout(10000); - let response = await PlexSession.GetPlexMovies({ - "X-Plex-Container-Start": 0, - "X-Plex-Container-Size": 2, +function UnitTests() { + const [plexClientInformation, setPlexClientInformation] = useState(); + const [plexTVAuthToken, setPlexTVAuthToken] = useState(); + const [plexTVUserData, setPlexUserData] = useState(); + const [plexServers, setPlexServers] = useState(); + describe("Unit Tests", function () { + let emptyArray = []; + it("Generate ClientId", function () { + setPlexClientInformation(CreatePlexClientInformation()); + assert.notEqual(plexClientInformation, null); + assert.notEqual(plexClientInformation, undefined); + console.log("Plex Session"); + console.log(plexClientInformation); }); - assert.notEqual(response, emptyArray); - assert.notEqual(response, null); - assert.notEqual(response, undefined); - // console.log("Plex Movies"); - // console.log(response); - }); - it("Get Plex Shows", async function () { - this.timeout(10000); - let response = await PlexSession.GetPlexShows({ - "X-Plex-Container-Start": 0, - "X-Plex-Container-Size": 2, + it("Login", async function () { + this.timeout(10000); + setPlexClientInformation(await PlexLogin(plexClientInformation)); + assert.notEqual(plexTVAuthToken, null); + assert.notEqual(plexTVAuthToken, undefined); + console.log("Auth Token"); + console.log(plexTVAuthToken); }); - assert.notEqual(response, emptyArray); - assert.notEqual(response, null); - assert.notEqual(response, undefined); - // console.log("Plex Shows"); - // console.log(response); - }); - it("Get Plex Seasons", async function () { - this.timeout(10000); - let response = await PlexSession.GetPlexSeasons({ - "X-Plex-Container-Start": 0, - "X-Plex-Container-Size": 2, + it("Get Plex User Data", async function () { + this.timeout(5000); + setPlexUserData( + await GetPlexUserData(plexClientInformation, plexTVAuthToken) + ); + assert.notEqual(plexTVUserData, undefined); + assert.notEqual(plexTVUserData, null); + console.log("User Data"); + console.log(plexTVUserData); }); - assert.notEqual(response, emptyArray); - assert.notEqual(response, null); - assert.notEqual(response, undefined); - // console.log("Plex Seasons"); - // console.log(response); - }); - it("Get Plex Episodes", async function () { - this.timeout(20000); - let response = await PlexSession.GetPlexEpisodes({ - "X-Plex-Container-Start": 0, - "X-Plex-Container-Size": 2, + it("Get Plex Servers", async function () { + this.timeout(12000); + setPlexServers( + await PlexSession.GetPlexServers( + plexClientInformation, + plexTVAuthToken, + { + owned: true, + } + ) + ); + assert.notEqual(plexServers, emptyArray); + assert.notEqual(plexServers, null); + assert.notEqual(plexServers, undefined); + console.log("Plex Servers"); + console.log(plexServers); }); - assert.notEqual(response, emptyArray); - assert.notEqual(response, null); - assert.notEqual(response, undefined); - // console.log("Plex Episodes"); - // console.log(response); + // it("Get Plex Libraries", async function () { + // this.timeout(10000); + // let response = await PlexSession.GetPlexLibraries(); + // assert.notEqual(PlexSession.plexLibraries, null); + // assert.notEqual(PlexSession.plexLibraries, undefined); + // assert.notEqual(PlexSession.plexLibraries, emptyArray); + // assert.notEqual(response, emptyArray); + // assert.notEqual(response, null); + // assert.notEqual(response, undefined); + // //console.log("Plex Libraries"); + // //console.log(PlexSession.plexLibraries); + // }); + // it("Get Plex Movie Libraries", async function () { + // this.timeout(20000); + // let response = await PlexSession.GetPlexMovieLibraries(); + // assert.notEqual(response, emptyArray); + // assert.notEqual(response, null); + // assert.notEqual(response, undefined); + // // console.log("Plex Movie Libraries"); + // // console.log(response); + // }); + // it("Get Plex Music Libraries", async function () { + // this.timeout(10000); + // let response = await PlexSession.GetPlexMusicLibraries(); + // assert.notEqual(response, emptyArray); + // assert.notEqual(response, null); + // assert.notEqual(response, undefined); + // // console.log("Plex Music Libraries"); + // // console.log(response); + // }); + // it("Get Plex TV Libraries", async function () { + // this.timeout(10000); + // let response = await PlexSession.GetPlexTVShowLibraries(); + // assert.notEqual(response, emptyArray); + // assert.notEqual(response, null); + // assert.notEqual(response, undefined); + // // console.log("Plex TV Libraries"); + // // console.log(response); + // }); + // it("Get Plex Movies", async function () { + // this.timeout(10000); + // let response = await PlexSession.GetPlexMovies({ + // "X-Plex-Container-Start": 0, + // "X-Plex-Container-Size": 2, + // }); + // assert.notEqual(response, emptyArray); + // assert.notEqual(response, null); + // assert.notEqual(response, undefined); + // // console.log("Plex Movies"); + // // console.log(response); + // }); + // it("Get Plex Shows", async function () { + // this.timeout(10000); + // let response = await PlexSession.GetPlexShows({ + // "X-Plex-Container-Start": 0, + // "X-Plex-Container-Size": 2, + // }); + // assert.notEqual(response, emptyArray); + // assert.notEqual(response, null); + // assert.notEqual(response, undefined); + // // console.log("Plex Shows"); + // // console.log(response); + // }); + // it("Get Plex Seasons", async function () { + // this.timeout(10000); + // let response = await PlexSession.GetPlexSeasons({ + // "X-Plex-Container-Start": 0, + // "X-Plex-Container-Size": 2, + // }); + // assert.notEqual(response, emptyArray); + // assert.notEqual(response, null); + // assert.notEqual(response, undefined); + // // console.log("Plex Seasons"); + // // console.log(response); + // }); + // it("Get Plex Episodes", async function () { + // this.timeout(20000); + // let response = await PlexSession.GetPlexEpisodes({ + // "X-Plex-Container-Start": 0, + // "X-Plex-Container-Size": 2, + // }); + // assert.notEqual(response, emptyArray); + // assert.notEqual(response, null); + // assert.notEqual(response, undefined); + // // console.log("Plex Episodes"); + // // console.log(response); + // }); + // it("Get Plex Artists", async function () { + // this.timeout(10000); + // let response = await PlexSession.GetPlexArtists({ + // "X-Plex-Container-Start": 0, + // "X-Plex-Container-Size": 2, + // }); + // assert.notEqual(response, emptyArray); + // assert.notEqual(response, null); + // assert.notEqual(response, undefined); + // // console.log("Plex Artists"); + // // console.log(response); + // }); + // it("Get Plex Albums", async function () { + // this.timeout(10000); + // let response = await PlexSession.GetPlexAlbums({ + // "X-Plex-Container-Start": 0, + // "X-Plex-Container-Size": 2, + // }); + // assert.notEqual(response, emptyArray); + // assert.notEqual(response, null); + // assert.notEqual(response, undefined); + // // console.log("Plex Albums"); + // // console.log(response); + // }); + // it("Get Plex Songs", async function () { + // this.timeout(20000); + // let response = await PlexSession.GetPlexSongs({ + // "X-Plex-Container-Start": 0, + // "X-Plex-Container-Size": 2, + // }); + // assert.notEqual(response, emptyArray); + // assert.notEqual(response, null); + // assert.notEqual(response, undefined); + // // console.log("Plex Songs"); + // // console.log(response); + // }); + // it("Get Plex Songs Paged", async function () { + // this.timeout(20000); + // let response = GetLibraryPages(PlexSession, "songs"); + // assert.notEqual(response, emptyArray); + // assert.notEqual(response, null); + // assert.notEqual(response, undefined); + // console.log("Plex Songs Paged"); + // console.log(response); + // }); }); - it("Get Plex Artists", async function () { - this.timeout(10000); - let response = await PlexSession.GetPlexArtists({ - "X-Plex-Container-Start": 0, - "X-Plex-Container-Size": 2, - }); - assert.notEqual(response, emptyArray); - assert.notEqual(response, null); - assert.notEqual(response, undefined); - // console.log("Plex Artists"); - // console.log(response); - }); - it("Get Plex Albums", async function () { - this.timeout(10000); - let response = await PlexSession.GetPlexAlbums({ - "X-Plex-Container-Start": 0, - "X-Plex-Container-Size": 2, - }); - assert.notEqual(response, emptyArray); - assert.notEqual(response, null); - assert.notEqual(response, undefined); - // console.log("Plex Albums"); - // console.log(response); - }); - it("Get Plex Songs", async function () { - this.timeout(20000); - let response = await PlexSession.GetPlexSongs({ - "X-Plex-Container-Start": 0, - "X-Plex-Container-Size": 2, - }); - assert.notEqual(response, emptyArray); - assert.notEqual(response, null); - assert.notEqual(response, undefined); - // console.log("Plex Songs"); - // console.log(response); - }); - it("Get Plex Songs Paged", async function () { - this.timeout(20000); - let response = PlexSession.GetLibraryPages("songs"); - assert.notEqual(response, emptyArray); - assert.notEqual(response, null); - assert.notEqual(response, undefined); - //console.log("Plex Songs Paged"); - //console.log(response); - }); -}); +} + +UnitTests();