From 566c9b64ff1f8f8ac9dae72cd5a40c2df3d0b03d Mon Sep 17 00:00:00 2001 From: luke-hagar-sp <98849695+luke-hagar-sp@users.noreply.github.com> Date: Wed, 27 Jul 2022 20:30:54 -0500 Subject: [PATCH] Switching computers --- package.json | 2 +- src/PlexAPIOAuth/PlexAPIOAuth.js | 394 ++++++++++++++++++++++++++++--- test/index.test.js | 66 +++++- 3 files changed, 421 insertions(+), 41 deletions(-) diff --git a/package.json b/package.json index 8165838..d556c84 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "plex-api-oauth", - "version": "1.0.135", + "version": "1.1.1", "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 3713f28..158e12f 100644 --- a/src/PlexAPIOAuth/PlexAPIOAuth.js +++ b/src/PlexAPIOAuth/PlexAPIOAuth.js @@ -15,6 +15,9 @@ export class PlexAPIOAuth { plexTVUserData; plexServers; plexLibraries; + plexArtistLibraries; + plexAlbumLibraries; + plexSongLibraries; plexMusicLibraries; plexMovieLibraries; plexTVShowLibraries; @@ -30,9 +33,15 @@ export class PlexAPIOAuth { plexTVUserData = {}, plexServers = [], plexLibraries = [], + plexArtistLibraries = [], + plexAlbumLibraries = [], + plexSongLibraries = [], plexMusicLibraries = [], plexMovieLibraries = [], plexTVShowLibraries = [], + plexLibraryContent = [], + plexMovieLibraryContent = [], + plexTVShowLibraryContent = [], plexDevices = [] ) { this.clientId = clientId; @@ -41,14 +50,19 @@ export class PlexAPIOAuth { this.version = version; this.forwardUrl = forwardUrl; this.platform = platform; - this.plexTVAuthToken = plexTVAuthToken; this.plexTVUserData = plexTVUserData; this.plexServers = plexServers; this.plexLibraries = plexLibraries; + this.plexArtistLibraries = plexArtistLibraries; + this.plexAlbumLibraries = plexAlbumLibraries; + this.plexSongLibraries = plexSongLibraries; this.plexMusicLibraries = plexMusicLibraries; this.plexMovieLibraries = plexMovieLibraries; this.plexTVShowLibraries = plexTVShowLibraries; + this.plexLibraryContent = plexLibraryContent; + this.plexMovieLibraryContent = plexMovieLibraryContent; + this.plexTVShowLibraryContent = plexTVShowLibraryContent; this.plexDevices = plexDevices; this.plexClientInformation = { @@ -72,9 +86,15 @@ export class PlexAPIOAuth { this.plexTVUserData = {}; this.plexServers = []; this.plexLibraries = []; + this.plexArtistLibraries = []; + this.plexAlbumLibraries = []; + this.plexSongLibraries = []; this.plexMusicLibraries = []; this.plexMovieLibraries = []; this.plexTVShowLibraries = []; + this.plexLibraryContent = []; + this.plexMovieLibraryContent = []; + this.plexTVShowLibraryContent = []; 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 @@ -97,9 +117,15 @@ export class PlexAPIOAuth { plexTVUserData = {}, plexServers = [], plexLibraries = [], + plexLibraryContent = [], + plexArtistLibraries = [], + plexAlbumLibraries = [], + plexSongLibraries = [], plexMusicLibraries = [], plexMovieLibraries = [], plexTVShowLibraries = [], + plexMovieLibraryContent = [], + plexTVShowLibraryContent = [], plexDevices = [], }) { this.plexTVAuthToken = plexTVAuthToken; @@ -112,11 +138,16 @@ export class PlexAPIOAuth { this.platform = platform; this.plexServers = plexServers; this.plexLibraries = plexLibraries; + this.plexArtistLibraries = plexArtistLibraries; + this.plexAlbumLibraries = plexAlbumLibraries; + this.plexSongLibraries = plexSongLibraries; this.plexMusicLibraries = plexMusicLibraries; this.plexMovieLibraries = plexMovieLibraries; this.plexTVShowLibraries = plexTVShowLibraries; + this.plexLibraryContent = plexLibraryContent; + this.plexMovieLibraryContent = plexMovieLibraryContent; + this.plexTVShowLibraryContent = plexTVShowLibraryContent; this.plexDevices = 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 @@ -141,8 +172,16 @@ export class PlexAPIOAuth { plexServers: this.plexServers, plexLibraries: this.plexLibraries, plexMusicLibraries: this.plexMusicLibraries, + plexArtistLibraries: this.plexArtistLibraries, + plexAlbumLibraries: this.plexAlbumLibraries, + plexSongLibraries: this.plexSongLibraries, + plexSeasonLibraries: this.plexSeasonLibraries, + plexEpisodeLibraries: this.plexEpisodeLibraries, plexMovieLibraries: this.plexMovieLibraries, plexTVShowLibraries: this.plexTVShowLibraries, + plexLibraryContent: this.plexLibraryContent, + plexMovieLibraryContent: this.plexMovieLibraryContent, + plexTVShowLibraryContent: this.plexTVShowLibraryContent, plexDevices: this.plexDevices, plexClientInformation: this.plexClientInformation, }; @@ -249,7 +288,7 @@ export class PlexAPIOAuth { //console.log("Authentican Token Validated Successfully"); this.plexTVUserData = response.data; //console.log("Populated User Data Successfully"); - return response.data; + return this.plexTVUserData; } if (response.status === 401) { //console.log("Authentican Token Failed Validation"); @@ -332,7 +371,7 @@ export class PlexAPIOAuth { }); for (const library of response.data.MediaContainer.Directory) { libraryArray.push({ - server: server.clientIdentifier, + server: server, allowSync: library.allowSync, art: library.art, composite: library.composite, @@ -356,14 +395,7 @@ export class PlexAPIOAuth { Location: library.Location, }); } - // console.log(libraryArray); - // this.plexLibraries = libraryArray; - // return await response?.data?.MediaContainer?.Directory.map((entry) => { - // }); } - // Promise.all(response).then((results) => { - // this.plexLibraries = results; - // }); this.plexLibraries = libraryArray; this.plexMusicLibraries = libraryArray.filter( (Obj) => Obj.type === "artist" @@ -374,24 +406,328 @@ export class PlexAPIOAuth { this.plexTVShowLibraries = libraryArray.filter( (Obj) => Obj.type === "show" ); + return this.plexLibraries; } - // async PopulateLibraryContent(server: PlexServer, library: PlexLibrary) { - // let response = await axios({ - // method: "GET", - // url: - // server?.relayConnections[0].uri + - // "/library/sections/" + - // library?.uuid + - // "?" + - // qs.stringify({ - // "X-Plex-Token": server?.accessToken, - // }), - // headers: { accept: "application/json" }, - // }).catch((err) => { - // throw err; - // }); - // console.log(response.data); - // return response.data; - // } + async GetPlexMovieLibraryContent() { + let movieLibraryContent = []; + for (const server of this.plexServers) { + for (const library of this.plexLibraries.filter( + (Obj) => + Obj.server.clientIdentifier === server.clientIdentifier && + Obj.type === "movie" + )) { + let response = await axios({ + method: "GET", + url: + server?.relayConnections[0].uri + + "/library/sections/" + + library?.key + + "/all?" + + qs.stringify({ + type: 1, + "X-Plex-Token": server?.accessToken, + }), + headers: { accept: "application/json" }, + }).catch((err) => { + throw err; + }); + 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, + }); + } + } + } + this.plexMovieLibraryContent = movieLibraryContent; + return movieLibraryContent; + } + async GetPlexMusicLibraryContent() { + let artistLibraryContent = []; + let albumLibraryContent = []; + let songLibraryContent = []; + for (const server of this.plexServers) { + for (const library of this.plexLibraries.filter( + (Obj) => + Obj.server.clientIdentifier === server.clientIdentifier && + Obj.type === "artist" + )) { + let response = await axios({ + method: "GET", + url: + server?.relayConnections[0].uri + + "/library/sections/" + + library?.key + + "/all?" + + qs.stringify({ + "X-Plex-Token": server?.accessToken, + }), + headers: { accept: "application/json" }, + }).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, + }); + } + } + for (const musicLibrary of this.plexMusicLibraries.filter( + (Obj) => Obj.server.clientIdentifier === server.clientIdentifier + )) { + let response = await axios({ + method: "GET", + url: + server?.relayConnections[0].uri + + "/library/sections/" + + musicLibrary?.key + + "/all?" + + qs.stringify({ + type: 9, + "X-Plex-Token": server?.accessToken, + }), + headers: { accept: "application/json" }, + }).catch((err) => { + throw err; + }); + for (const data of response.data.MediaContainer.Metadata) { + let tempObject = data; + albumLibraryContent.push(tempObject); + } + response = await axios({ + method: "GET", + url: + server?.relayConnections[0].uri + + "/library/sections/" + + musicLibrary?.key + + "/all?" + + qs.stringify({ + type: 10, + "X-Plex-Token": server?.accessToken, + }), + headers: { accept: "application/json" }, + }).catch((err) => { + throw err; + }); + for (const data of response.data.MediaContainer.Metadata) { + let tempObject = { + server: server, + library: musicLibrary, + 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, + }; + songLibraryContent.push(tempObject); + } + } + } + this.plexArtistLibraries = artistLibraryContent; + this.plexAlbumLibraries = albumLibraryContent; + this.plexSongLibraries = songLibraryContent; + return artistLibraryContent; + } + async GetPlexTVShowLibraryContent() { + let tvShowLibraryContent = []; + let seasonLibraryContent = []; + let episodeLibraryContent = []; + for (const server of this.plexServers) { + for (const showLibrary of this.plexTVShowLibraries.filter( + (Obj) => Obj.server.clientIdentifier === server.clientIdentifier + )) { + let response = await axios({ + method: "GET", + url: + server?.relayConnections[0].uri + + "/library/sections/" + + showLibrary?.key + + "/all?" + + qs.stringify({ + type: 2, + "X-Plex-Token": server?.accessToken, + }), + headers: { accept: "application/json" }, + }).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, + }); + } + + response = await axios({ + method: "GET", + url: + server?.relayConnections[0].uri + + "/library/sections/" + + showLibrary?.key + + "/all?" + + qs.stringify({ + type: 3, + "X-Plex-Token": server?.accessToken, + }), + headers: { accept: "application/json" }, + }).catch((err) => { + throw err; + }); + for (const data of response.data.MediaContainer.Metadata) { + let tempObject = data; + seasonLibraryContent.push(tempObject); + } + + response = await axios({ + method: "GET", + url: + server?.relayConnections[0].uri + + "/library/sections/" + + showLibrary?.key + + "/all?" + + qs.stringify({ + type: 4, + "X-Plex-Token": server?.accessToken, + }), + headers: { accept: "application/json" }, + }).catch((err) => { + throw err; + }); + for (const data of response.data.MediaContainer.Metadata) { + let tempObject = data; + episodeLibraryContent.push(tempObject); + } + } + } + this.plexTVShowLibraryContent = tvShowLibraryContent; + this.plexSeasonLibraries = seasonLibraryContent; + this.episodeLibraryContent = episodeLibraryContent; + return tvShowLibraryContent; + } + + async GetPlexTVShowSeasons(server, searchString) { + let responseArray = []; + let queryArray = this.plexServers; + if (server) { + queryArray = this.plexServers.filter((Obj) => (Obj = server)); + } + if (searchString) { + } + for (const server of queryArray) { + for (const showLibrary of this.plexTVShowLibraries.filter( + (Obj) => Obj.server.clientIdentifier === server.clientIdentifier + )) { + let response = await axios({ + method: "GET", + url: + server?.relayConnections[0].uri + + "/library/sections/" + + showLibrary?.key + + "/all?" + + qs.stringify({ + title: searchString || null, + type: 3, + "X-Plex-Token": server?.accessToken, + }), + headers: { accept: "application/json" }, + }).catch((err) => { + throw err; + }); + responseArray.push(...response.data.MediaContainer.Metadata); + } + } + return responseArray; + } } diff --git a/test/index.test.js b/test/index.test.js index 4da7517..ff1db7a 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -1,31 +1,31 @@ import { PlexAPIOAuth } from "../src/index.js"; import { strict as assert } from "assert"; -describe("Login Test", function () { +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); + // 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); + // 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); + // console.log("User Data"); + // console.log(PlexSession.plexTVUserData); }); it("Get Plex Servers", async function () { this.timeout(10000); @@ -35,8 +35,8 @@ describe("Login Test", function () { assert.notEqual(PlexSession.plexServers, undefined); assert.notEqual(PlexSession.plexDevices, emptyArray); assert.notEqual(response, null); - console.log("Plex Servers"); - console.log(PlexSession.plexServers); + // console.log("Plex Servers"); + // console.log(PlexSession.plexServers); }); it("Get Plex Libraries", async function () { this.timeout(10000); @@ -53,7 +53,51 @@ describe("Login Test", function () { assert.notEqual(PlexSession.plexTVShowLibraries, null); assert.notEqual(PlexSession.plexTVShowLibraries, undefined); assert.notEqual(PlexSession.plexTVShowLibraries, emptyArray); - console.log("Plex Libraries"); - console.log(PlexSession.plexLibraries); + // console.log("Plex Libraries"); + // console.log(PlexSession.plexLibraries); + }); + // it("Get Plex Movie Library Contents", async function () { + // this.timeout(10000); + // let response = await PlexSession.GetPlexMovieLibraryContent(); + // assert.notEqual(PlexSession.plexMovieLibraryContent, null); + // assert.notEqual(PlexSession.plexMovieLibraryContent, undefined); + // assert.notEqual(PlexSession.plexMovieLibraryContent, emptyArray); + // // console.log("Plex Movie Library Content"); + // // console.log(PlexSession.plexMovieLibraryContent); + // }); + // it("Get Plex Music Library Contents", async function () { + // this.timeout(10000); + // let response = await PlexSession.GetPlexMusicLibraryContent(); + // assert.notEqual(PlexSession.plexArtistLibraries, null); + // assert.notEqual(PlexSession.plexArtistLibraries, undefined); + // assert.notEqual(PlexSession.plexArtistLibraries, emptyArray); + // assert.notEqual(PlexSession.plexAlbumLibraries, null); + // assert.notEqual(PlexSession.plexAlbumLibraries, undefined); + // assert.notEqual(PlexSession.plexAlbumLibraries, emptyArray); + // assert.notEqual(PlexSession.plexSongLibraries, null); + // assert.notEqual(PlexSession.plexSongLibraries, undefined); + // assert.notEqual(PlexSession.plexSongLibraries, emptyArray); + // // console.log("Plex Library Content"); + // // console.log(PlexSession.plexAlbumLibraries); + // }); + // it("Get Plex TV Library Contents", async function () { + // this.timeout(30000); + // let response = await PlexSession.GetPlexTVShowLibraryContent(); + // assert.notEqual(PlexSession.plexTVShowLibraryContent, null); + // assert.notEqual(PlexSession.plexTVShowLibraryContent, undefined); + // assert.notEqual(PlexSession.plexTVShowLibraryContent, emptyArray); + // assert.notEqual(PlexSession.plexSeasonLibraries, null); + // assert.notEqual(PlexSession.plexSeasonLibraries, undefined); + // assert.notEqual(PlexSession.plexSeasonLibraries, emptyArray); + // assert.notEqual(PlexSession.episodeLibraryContent, null); + // assert.notEqual(PlexSession.episodeLibraryContent, undefined); + // assert.notEqual(PlexSession.episodeLibraryContent, emptyArray); + // //console.log("Plex TV Library Content"); + // //console.log(PlexSession.plexSeasonLibraries); + // }); + it("Get Plex TV Show Seasons - Stateless", async function () { + this.timeout(4000); + let response = await PlexSession.GetPlexTVShowSeasons(); + //console.log(response); }); });