@ctrl/plex 3.12.1 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/dist/src/alert.js +1 -1
- package/dist/src/audio.d.ts +3 -1
- package/dist/src/audio.js +8 -6
- package/dist/src/base/partialPlexObject.d.ts +26 -22
- package/dist/src/base/partialPlexObject.js +36 -39
- package/dist/src/base/plexObject.js +2 -2
- package/dist/src/baseFunctionality.js +2 -2
- package/dist/src/client.d.ts +4 -2
- package/dist/src/client.js +2 -2
- package/dist/src/library.d.ts +23 -6
- package/dist/src/library.js +25 -25
- package/dist/src/media.js +7 -7
- package/dist/src/myplex.d.ts +26 -19
- package/dist/src/myplex.js +28 -26
- package/dist/src/playlist.js +6 -6
- package/dist/src/playqueue.js +8 -8
- package/dist/src/server.d.ts +32 -23
- package/dist/src/server.js +42 -34
- package/dist/src/server.types.d.ts +12 -0
- package/dist/src/settings.js +1 -1
- package/dist/src/util.d.ts +5 -4
- package/dist/src/util.js +2 -4
- package/dist/src/video.d.ts +4 -1
- package/dist/src/video.js +11 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,11 @@ Create a plex connection
|
|
|
19
19
|
```ts
|
|
20
20
|
import { MyPlexAccount } from '@ctrl/plex';
|
|
21
21
|
|
|
22
|
-
const account = await new MyPlexAccount(
|
|
22
|
+
const account = await new MyPlexAccount({
|
|
23
|
+
baseUrl: 'http://localhost:32400',
|
|
24
|
+
username: 'username',
|
|
25
|
+
password: 'password',
|
|
26
|
+
}).connect();
|
|
23
27
|
const resource = await account.resource('<SERVERNAME>');
|
|
24
28
|
const plex = await resource.connect();
|
|
25
29
|
const library = await plex.library();
|
package/dist/src/alert.js
CHANGED
|
@@ -8,7 +8,7 @@ export class AlertListener {
|
|
|
8
8
|
this.callback = callback;
|
|
9
9
|
}
|
|
10
10
|
async run() {
|
|
11
|
-
const url = this.server.url(this.key, true).toString().replace('http', 'ws');
|
|
11
|
+
const url = this.server.url(this.key, { includeToken: true }).toString().replace('http', 'ws');
|
|
12
12
|
this._ws = new WebSocket(url);
|
|
13
13
|
this._ws.on('message', (buffer) => {
|
|
14
14
|
try {
|
package/dist/src/audio.d.ts
CHANGED
|
@@ -155,7 +155,9 @@ export declare class Track extends Audio {
|
|
|
155
155
|
/**
|
|
156
156
|
* Returns the Plex Web URL pointing to the album details page for this track.
|
|
157
157
|
*/
|
|
158
|
-
getWebURL(base?:
|
|
158
|
+
getWebURL({ base }?: {
|
|
159
|
+
base?: string;
|
|
160
|
+
}): string;
|
|
159
161
|
/**
|
|
160
162
|
* Returns a sonic adventure from the current track to the specified track.
|
|
161
163
|
* @param to The target track for the sonic adventure.
|
package/dist/src/audio.js
CHANGED
|
@@ -37,7 +37,7 @@ export class Audio extends Playable {
|
|
|
37
37
|
// or it might be used for things like `/tree`? The python `url` method seems rarely used directly.
|
|
38
38
|
// For now, mirroring the python seems safest. If `part` is meant to be appended to `this.key`,
|
|
39
39
|
// the logic would need changing.
|
|
40
|
-
return part ? this.server.url(part, true)?.toString() : undefined;
|
|
40
|
+
return part ? this.server.url(part, { includeToken: true })?.toString() : undefined;
|
|
41
41
|
}
|
|
42
42
|
/** Indicates if the audio item has undergone sonic analysis. */
|
|
43
43
|
get hasSonicAnalysis() {
|
|
@@ -86,7 +86,7 @@ export class Audio extends Playable {
|
|
|
86
86
|
this._data = data;
|
|
87
87
|
const addedAtTimestamp = data.addedAt ? Number.parseInt(data.addedAt, 10) : Number.NaN;
|
|
88
88
|
this.addedAt = Number.isNaN(addedAtTimestamp) ? undefined : new Date(addedAtTimestamp * 1000);
|
|
89
|
-
this.art = data.art ? this.server.url(data.art, true)?.toString() : undefined;
|
|
89
|
+
this.art = data.art ? this.server.url(data.art, { includeToken: true })?.toString() : undefined;
|
|
90
90
|
this.artBlurHash = data.artBlurHash;
|
|
91
91
|
const distanceFloat = data.distance ? Number.parseFloat(data.distance) : Number.NaN;
|
|
92
92
|
this.distance = Number.isNaN(distanceFloat) ? undefined : distanceFloat;
|
|
@@ -126,7 +126,9 @@ export class Audio extends Playable {
|
|
|
126
126
|
const ratingKeyInt = data.ratingKey ? Number.parseInt(data.ratingKey, 10) : Number.NaN;
|
|
127
127
|
this.ratingKey = Number.isNaN(ratingKeyInt) ? this.ratingKey : ratingKeyInt.toString();
|
|
128
128
|
this.summary = data.summary;
|
|
129
|
-
this.thumb = data.thumb
|
|
129
|
+
this.thumb = data.thumb
|
|
130
|
+
? this.server.url(data.thumb, { includeToken: true })?.toString()
|
|
131
|
+
: undefined;
|
|
130
132
|
this.thumbBlurHash = data.thumbBlurHash;
|
|
131
133
|
this.title = data.title ?? this.title;
|
|
132
134
|
this.titleSort = data.titleSort ?? this.title;
|
|
@@ -230,13 +232,13 @@ export class Track extends Audio {
|
|
|
230
232
|
/**
|
|
231
233
|
* Returns the Plex Web URL pointing to the album details page for this track.
|
|
232
234
|
*/
|
|
233
|
-
getWebURL(base) {
|
|
235
|
+
getWebURL({ base } = {}) {
|
|
234
236
|
if (this.parentKey) {
|
|
235
237
|
const params = new URLSearchParams();
|
|
236
238
|
params.append('key', this.parentKey);
|
|
237
|
-
return this.server._buildWebURL(base, 'details', params);
|
|
239
|
+
return this.server._buildWebURL({ base, endpoint: 'details', params });
|
|
238
240
|
}
|
|
239
|
-
return super.getWebURL(base);
|
|
241
|
+
return super.getWebURL({ base });
|
|
240
242
|
}
|
|
241
243
|
// metadataDirectory property requires Path module and filesystem access, which is
|
|
242
244
|
// complex in node/browser. Omitting for now, might need specific implementation.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Section } from '../library.js';
|
|
2
2
|
import { SearchResult } from '../search.js';
|
|
3
|
+
import type { HistoryOptions } from '../server.types.js';
|
|
3
4
|
import { PlexObject } from './plexObject.js';
|
|
4
5
|
export declare abstract class PartialPlexObject extends PlexObject {
|
|
5
6
|
_INCLUDES: {
|
|
@@ -61,26 +62,24 @@ export declare abstract class PartialPlexObject extends PlexObject {
|
|
|
61
62
|
get isFullObject(): boolean;
|
|
62
63
|
/**
|
|
63
64
|
* Use match result to update show metadata.
|
|
64
|
-
* @param
|
|
65
|
-
* @param auto True uses first match from matches, False allows user to provide the match
|
|
66
|
-
* @param agent (str): Agent name to be used (imdb, thetvdb, themoviedb, etc.)
|
|
65
|
+
* @param options Match options.
|
|
67
66
|
*/
|
|
68
|
-
fixMatch(searchResult
|
|
67
|
+
fixMatch({ searchResult, auto, agent, }?: {
|
|
68
|
+
searchResult?: SearchResult;
|
|
69
|
+
auto?: boolean;
|
|
70
|
+
agent?: string;
|
|
71
|
+
}): Promise<void>;
|
|
69
72
|
/**
|
|
70
|
-
*
|
|
71
|
-
* @param agent Agent name to be used (imdb, thetvdb, themoviedb, etc.)
|
|
72
|
-
* @param title Title of item to search for
|
|
73
|
-
* @param year Year of item to search in
|
|
74
|
-
* @param language Language of item to search in
|
|
73
|
+
* @param options Match options.
|
|
75
74
|
*
|
|
76
75
|
* Examples:
|
|
77
76
|
* 1. video.matches()
|
|
78
|
-
* 2. video.matches(title
|
|
79
|
-
* 3. video.matches(title
|
|
80
|
-
* 4. video.matches(year
|
|
81
|
-
* 5. video.matches(title
|
|
82
|
-
* 6. video.matches(title
|
|
83
|
-
* 7. video.matches(title
|
|
77
|
+
* 2. video.matches({ title: "something", year: "2020" })
|
|
78
|
+
* 3. video.matches({ title: "something" })
|
|
79
|
+
* 4. video.matches({ year: "2020" })
|
|
80
|
+
* 5. video.matches({ title: "something", year: "" })
|
|
81
|
+
* 6. video.matches({ title: "", year: "2020" })
|
|
82
|
+
* 7. video.matches({ title: "", year: "" })
|
|
84
83
|
*
|
|
85
84
|
* 1. The default behaviour in Plex Web = no params in plexapi
|
|
86
85
|
* 2. Both title and year specified by user
|
|
@@ -92,15 +91,19 @@ export declare abstract class PartialPlexObject extends PlexObject {
|
|
|
92
91
|
*
|
|
93
92
|
* For 2 to 7, the agent and language is automatically filled in
|
|
94
93
|
*/
|
|
95
|
-
matches(agent
|
|
94
|
+
matches({ agent, title, year, language, }?: {
|
|
95
|
+
agent?: string;
|
|
96
|
+
title?: string;
|
|
97
|
+
year?: string;
|
|
98
|
+
language?: string;
|
|
99
|
+
}): Promise<SearchResult[]>;
|
|
96
100
|
/** Unmatches metadata match from object. */
|
|
97
101
|
unmatch(): Promise<any>;
|
|
98
102
|
/**
|
|
99
103
|
* Get Play History for a media item.
|
|
100
|
-
* @param
|
|
101
|
-
* @param mindate Min datetime to return results from.
|
|
104
|
+
* @param options Filter and paging options.
|
|
102
105
|
*/
|
|
103
|
-
history(
|
|
106
|
+
history(options?: Omit<HistoryOptions, 'ratingKey'>): Promise<import("../server.types.js").HistoryResult[]>;
|
|
104
107
|
section(): Promise<Section>;
|
|
105
108
|
/**
|
|
106
109
|
* Delete a media element. This has to be enabled under settings > server > library in plex webui.
|
|
@@ -118,7 +121,9 @@ export declare abstract class PartialPlexObject extends PlexObject {
|
|
|
118
121
|
addGenre(genres: string[]): Promise<void>;
|
|
119
122
|
/** Remove a genre(s). */
|
|
120
123
|
removeGenre(genres: string[]): Promise<void>;
|
|
121
|
-
getWebURL(base?:
|
|
124
|
+
getWebURL({ base }?: {
|
|
125
|
+
base?: string;
|
|
126
|
+
}): string;
|
|
122
127
|
/**
|
|
123
128
|
* Edit an object.
|
|
124
129
|
* @param changeObj Obj of settings to edit.
|
|
@@ -140,8 +145,7 @@ export declare abstract class PartialPlexObject extends PlexObject {
|
|
|
140
145
|
* Helper to edit and refresh a tags.
|
|
141
146
|
* @param tag tag name
|
|
142
147
|
* @param items list of tags to add
|
|
143
|
-
* @param
|
|
144
|
-
* @param remove If this is active remove the tags in items.
|
|
148
|
+
* @param options
|
|
145
149
|
*/
|
|
146
150
|
private _editTags;
|
|
147
151
|
}
|
|
@@ -45,7 +45,7 @@ export class PartialPlexObject extends PlexObject {
|
|
|
45
45
|
*/
|
|
46
46
|
async analyze() {
|
|
47
47
|
const key = `/${ltrim(this.key, ['/'])}/analyze`;
|
|
48
|
-
await this.server.query(key, 'put');
|
|
48
|
+
await this.server.query({ path: key, method: 'put' });
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
51
51
|
* load full data / reload the data for this object from this.key.
|
|
@@ -57,7 +57,7 @@ export class PartialPlexObject extends PlexObject {
|
|
|
57
57
|
throw new Error('Cannot reload an object not built from a URL');
|
|
58
58
|
}
|
|
59
59
|
this.initpath = key;
|
|
60
|
-
const data = await this.server.query(key);
|
|
60
|
+
const data = await this.server.query({ path: key });
|
|
61
61
|
const innerData = data.MediaContainer ?? data;
|
|
62
62
|
this._loadFullData(innerData);
|
|
63
63
|
}
|
|
@@ -72,11 +72,9 @@ export class PartialPlexObject extends PlexObject {
|
|
|
72
72
|
}
|
|
73
73
|
/**
|
|
74
74
|
* Use match result to update show metadata.
|
|
75
|
-
* @param
|
|
76
|
-
* @param auto True uses first match from matches, False allows user to provide the match
|
|
77
|
-
* @param agent (str): Agent name to be used (imdb, thetvdb, themoviedb, etc.)
|
|
75
|
+
* @param options Match options.
|
|
78
76
|
*/
|
|
79
|
-
async fixMatch(searchResult, auto = false, agent = '') {
|
|
77
|
+
async fixMatch({ searchResult, auto = false, agent = '', } = {}) {
|
|
80
78
|
const key = `/library/metadata/${this.ratingKey}/match`;
|
|
81
79
|
if (auto) {
|
|
82
80
|
const autoMatch = await this.matches();
|
|
@@ -92,23 +90,19 @@ export class PartialPlexObject extends PlexObject {
|
|
|
92
90
|
}
|
|
93
91
|
const params = new URLSearchParams({ guid: searchResult.guid, name: searchResult.name });
|
|
94
92
|
const url = `${key}?${params.toString()}`;
|
|
95
|
-
await this.server.query(url, 'put');
|
|
93
|
+
await this.server.query({ path: url, method: 'put' });
|
|
96
94
|
}
|
|
97
95
|
/**
|
|
98
|
-
*
|
|
99
|
-
* @param agent Agent name to be used (imdb, thetvdb, themoviedb, etc.)
|
|
100
|
-
* @param title Title of item to search for
|
|
101
|
-
* @param year Year of item to search in
|
|
102
|
-
* @param language Language of item to search in
|
|
96
|
+
* @param options Match options.
|
|
103
97
|
*
|
|
104
98
|
* Examples:
|
|
105
99
|
* 1. video.matches()
|
|
106
|
-
* 2. video.matches(title
|
|
107
|
-
* 3. video.matches(title
|
|
108
|
-
* 4. video.matches(year
|
|
109
|
-
* 5. video.matches(title
|
|
110
|
-
* 6. video.matches(title
|
|
111
|
-
* 7. video.matches(title
|
|
100
|
+
* 2. video.matches({ title: "something", year: "2020" })
|
|
101
|
+
* 3. video.matches({ title: "something" })
|
|
102
|
+
* 4. video.matches({ year: "2020" })
|
|
103
|
+
* 5. video.matches({ title: "something", year: "" })
|
|
104
|
+
* 6. video.matches({ title: "", year: "2020" })
|
|
105
|
+
* 7. video.matches({ title: "", year: "" })
|
|
112
106
|
*
|
|
113
107
|
* 1. The default behaviour in Plex Web = no params in plexapi
|
|
114
108
|
* 2. Both title and year specified by user
|
|
@@ -120,7 +114,7 @@ export class PartialPlexObject extends PlexObject {
|
|
|
120
114
|
*
|
|
121
115
|
* For 2 to 7, the agent and language is automatically filled in
|
|
122
116
|
*/
|
|
123
|
-
async matches(agent, title, year, language) {
|
|
117
|
+
async matches({ agent, title, year, language, } = {}) {
|
|
124
118
|
const key = `/library/metadata/${this.ratingKey}/matches`;
|
|
125
119
|
const params = new URLSearchParams({ manual: '1' });
|
|
126
120
|
if (agent && [title, year, language].some(x => x)) {
|
|
@@ -157,21 +151,22 @@ export class PartialPlexObject extends PlexObject {
|
|
|
157
151
|
params.append('agent', section.agent);
|
|
158
152
|
}
|
|
159
153
|
}
|
|
160
|
-
const data = await this.server.query(
|
|
154
|
+
const data = await this.server.query({
|
|
155
|
+
path: `${key}?${params.toString()}`,
|
|
156
|
+
});
|
|
161
157
|
return data.MediaContainer.SearchResult.map(r => new SearchResult(this.server, r));
|
|
162
158
|
}
|
|
163
159
|
/** Unmatches metadata match from object. */
|
|
164
160
|
async unmatch() {
|
|
165
161
|
const key = `/library/metadata/${this.ratingKey}/unmatch`;
|
|
166
|
-
return this.server.query(key, 'put');
|
|
162
|
+
return this.server.query({ path: key, method: 'put' });
|
|
167
163
|
}
|
|
168
164
|
/**
|
|
169
165
|
* Get Play History for a media item.
|
|
170
|
-
* @param
|
|
171
|
-
* @param mindate Min datetime to return results from.
|
|
166
|
+
* @param options Filter and paging options.
|
|
172
167
|
*/
|
|
173
|
-
async history(
|
|
174
|
-
return this.server.history(
|
|
168
|
+
async history(options = {}) {
|
|
169
|
+
return this.server.history({ ...options, ratingKey: this.ratingKey });
|
|
175
170
|
}
|
|
176
171
|
async section() {
|
|
177
172
|
return (await this.server.library()).sectionByID(this.librarySectionID);
|
|
@@ -180,7 +175,7 @@ export class PartialPlexObject extends PlexObject {
|
|
|
180
175
|
* Delete a media element. This has to be enabled under settings > server > library in plex webui.
|
|
181
176
|
*/
|
|
182
177
|
async delete() {
|
|
183
|
-
return this.server.query(this.key, 'delete');
|
|
178
|
+
return this.server.query({ path: this.key, method: 'delete' });
|
|
184
179
|
}
|
|
185
180
|
/** Add a collection(s). */
|
|
186
181
|
async addCollection(collections) {
|
|
@@ -188,7 +183,7 @@ export class PartialPlexObject extends PlexObject {
|
|
|
188
183
|
}
|
|
189
184
|
/** Remove a collection(s). */
|
|
190
185
|
async removeCollection(collections) {
|
|
191
|
-
await this._editTags('collection', collections,
|
|
186
|
+
await this._editTags('collection', collections, { remove: true });
|
|
192
187
|
}
|
|
193
188
|
/** Add a label(s). */
|
|
194
189
|
async addLabel(labels) {
|
|
@@ -196,7 +191,7 @@ export class PartialPlexObject extends PlexObject {
|
|
|
196
191
|
}
|
|
197
192
|
/** Remove a label(s). */
|
|
198
193
|
async removeLabel(labels) {
|
|
199
|
-
await this._editTags('label', labels,
|
|
194
|
+
await this._editTags('label', labels, { remove: true });
|
|
200
195
|
}
|
|
201
196
|
/** Add a genre(s). */
|
|
202
197
|
async addGenre(genres) {
|
|
@@ -204,10 +199,10 @@ export class PartialPlexObject extends PlexObject {
|
|
|
204
199
|
}
|
|
205
200
|
/** Remove a genre(s). */
|
|
206
201
|
async removeGenre(genres) {
|
|
207
|
-
await this._editTags('genre', genres,
|
|
202
|
+
await this._editTags('genre', genres, { remove: true });
|
|
208
203
|
}
|
|
209
|
-
getWebURL(base) {
|
|
210
|
-
return this._getWebURL(base);
|
|
204
|
+
getWebURL({ base } = {}) {
|
|
205
|
+
return this._getWebURL({ base });
|
|
211
206
|
}
|
|
212
207
|
/**
|
|
213
208
|
* Edit an object.
|
|
@@ -237,29 +232,31 @@ export class PartialPlexObject extends PlexObject {
|
|
|
237
232
|
}
|
|
238
233
|
const strObj = Object.fromEntries(Object.entries(changeObj).map(([key, value]) => [key, value.toString()]));
|
|
239
234
|
const params = new URLSearchParams(strObj);
|
|
240
|
-
const url = this.server.url(`/library/sections/${this.librarySectionID}/all`,
|
|
241
|
-
|
|
235
|
+
const url = this.server.url(`/library/sections/${this.librarySectionID}/all`, {
|
|
236
|
+
includeToken: true,
|
|
237
|
+
params,
|
|
238
|
+
});
|
|
239
|
+
await this.server.query({ path: url.toString(), method: 'put' });
|
|
242
240
|
}
|
|
243
241
|
/**
|
|
244
242
|
* Get the Plex Web URL with the correct parameters.
|
|
245
243
|
* Private method to allow overriding parameters from subclasses.
|
|
246
244
|
*/
|
|
247
|
-
_getWebURL(base) {
|
|
245
|
+
_getWebURL({ base } = {}) {
|
|
248
246
|
const params = new URLSearchParams();
|
|
249
247
|
params.append('key', this.key);
|
|
250
|
-
return this.server._buildWebURL(base, 'details', params);
|
|
248
|
+
return this.server._buildWebURL({ base, endpoint: 'details', params });
|
|
251
249
|
}
|
|
252
250
|
/**
|
|
253
251
|
* Helper to edit and refresh a tags.
|
|
254
252
|
* @param tag tag name
|
|
255
253
|
* @param items list of tags to add
|
|
256
|
-
* @param
|
|
257
|
-
* @param remove If this is active remove the tags in items.
|
|
254
|
+
* @param options
|
|
258
255
|
*/
|
|
259
|
-
async _editTags(tag, items, locked = true, remove = false) {
|
|
256
|
+
async _editTags(tag, items, { locked = true, remove = false } = {}) {
|
|
260
257
|
const value = this[`${tag}s`];
|
|
261
258
|
const existingCols = value?.filter((x) => x && remove).map((x) => x.tag) ?? [];
|
|
262
|
-
const d = tagHelper(tag, [...existingCols, ...items], locked, remove);
|
|
259
|
+
const d = tagHelper(tag, [...existingCols, ...items], { locked, remove });
|
|
263
260
|
await this.edit(d);
|
|
264
261
|
await this.reload();
|
|
265
262
|
}
|
|
@@ -30,7 +30,7 @@ export class PlexObject {
|
|
|
30
30
|
if (!key) {
|
|
31
31
|
throw new Error('Cannot reload an object not built from a URL');
|
|
32
32
|
}
|
|
33
|
-
const data = await this.server.query(key);
|
|
33
|
+
const data = await this.server.query({ path: key });
|
|
34
34
|
const innerData = data.MediaContainer ? data.MediaContainer : data;
|
|
35
35
|
this._loadData(innerData);
|
|
36
36
|
}
|
|
@@ -42,7 +42,7 @@ export class PlexObject {
|
|
|
42
42
|
*/
|
|
43
43
|
async refresh() {
|
|
44
44
|
const key = `${this.key}/refresh`;
|
|
45
|
-
await this.server.query(key, 'put');
|
|
45
|
+
await this.server.query({ path: key, method: 'put' });
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
48
48
|
* Returns True if this object is a child of the given class.
|
|
@@ -28,7 +28,7 @@ export const OPERATORS = {
|
|
|
28
28
|
*/
|
|
29
29
|
export async function fetchItem(server, ekey, options, cls) {
|
|
30
30
|
const key = typeof ekey === 'number' ? `/library/metadata/${ekey.toString()}` : ekey;
|
|
31
|
-
const response = await server.query(key);
|
|
31
|
+
const response = await server.query({ path: key });
|
|
32
32
|
const containerKey = cls?.TAG ?? 'Metadata';
|
|
33
33
|
const elems = response.MediaContainer[containerKey] ?? [];
|
|
34
34
|
for (const elem of elems) {
|
|
@@ -44,7 +44,7 @@ export async function fetchItem(server, ekey, options, cls) {
|
|
|
44
44
|
* on how this is used.
|
|
45
45
|
*/
|
|
46
46
|
export async function fetchItems(server, ekey, options, Cls, parent) {
|
|
47
|
-
const response = await server.query(ekey);
|
|
47
|
+
const response = await server.query({ path: ekey });
|
|
48
48
|
const { MediaContainer } = response;
|
|
49
49
|
const elems = MediaContainer[Cls?.TAG] ?? MediaContainer.Metadata ?? [];
|
|
50
50
|
const items = findItems(elems, options, Cls, server, parent);
|
package/dist/src/client.d.ts
CHANGED
|
@@ -94,9 +94,11 @@ export declare class PlexClient {
|
|
|
94
94
|
* Build a URL string with proper token argument. Token will be appended to the URL
|
|
95
95
|
* if either includeToken is True or TODO: CONFIG.log.show_secrets is 'true'.
|
|
96
96
|
* @param key
|
|
97
|
-
* @param
|
|
97
|
+
* @param options
|
|
98
98
|
*/
|
|
99
|
-
url(key: string, includeToken?:
|
|
99
|
+
url(key: string, { includeToken }?: {
|
|
100
|
+
includeToken?: boolean;
|
|
101
|
+
}): URL;
|
|
100
102
|
protected _loadData(data: Player): void;
|
|
101
103
|
/**
|
|
102
104
|
* Returns a dict of all default headers for Client requests.
|
package/dist/src/client.js
CHANGED
|
@@ -97,9 +97,9 @@ export class PlexClient {
|
|
|
97
97
|
* Build a URL string with proper token argument. Token will be appended to the URL
|
|
98
98
|
* if either includeToken is True or TODO: CONFIG.log.show_secrets is 'true'.
|
|
99
99
|
* @param key
|
|
100
|
-
* @param
|
|
100
|
+
* @param options
|
|
101
101
|
*/
|
|
102
|
-
url(key, includeToken = false) {
|
|
102
|
+
url(key, { includeToken = false } = {}) {
|
|
103
103
|
if (!this._baseurl) {
|
|
104
104
|
throw new Error('PlexClient object missing baseurl.');
|
|
105
105
|
}
|
package/dist/src/library.d.ts
CHANGED
|
@@ -309,7 +309,14 @@ export declare abstract class LibrarySection<SType = SectionType> extends PlexOb
|
|
|
309
309
|
* @param tab The library tab (recommended, library, collections, playlists, timeline).
|
|
310
310
|
* @param key A hub key.
|
|
311
311
|
*/
|
|
312
|
-
getWebURL(base
|
|
312
|
+
getWebURL({ base, tab, key, }?: {
|
|
313
|
+
/** The base URL before the fragment (``#!``). Default is https://app.plex.tv/desktop. */
|
|
314
|
+
base?: string;
|
|
315
|
+
/** The library tab (recommended, library, collections, playlists, timeline). */
|
|
316
|
+
tab?: string;
|
|
317
|
+
/** A hub key. */
|
|
318
|
+
key?: string;
|
|
319
|
+
}): string;
|
|
313
320
|
/**
|
|
314
321
|
* Search the library. The http requests will be batched in container_size. If you are only looking for the
|
|
315
322
|
* first <num> results, it would be wise to set the maxresults option to that amount so the search doesn't iterate
|
|
@@ -422,9 +429,13 @@ export declare class ShowSection extends LibrarySection<Show> {
|
|
|
422
429
|
/**
|
|
423
430
|
* Returns a list of recently added episodes from this library section.
|
|
424
431
|
*
|
|
425
|
-
* @param
|
|
432
|
+
* @param options Filter and paging options.
|
|
426
433
|
*/
|
|
427
|
-
recentlyAdded(args
|
|
434
|
+
recentlyAdded({ args, libtype, maxResults, }?: {
|
|
435
|
+
args?: any;
|
|
436
|
+
libtype?: string;
|
|
437
|
+
maxResults?: number;
|
|
438
|
+
}): Promise<Show[]>;
|
|
428
439
|
}
|
|
429
440
|
export declare class MusicSection extends LibrarySection<Track> {
|
|
430
441
|
static TYPE: string;
|
|
@@ -446,11 +457,17 @@ export declare class MusicSection extends LibrarySection<Track> {
|
|
|
446
457
|
/** Search for a track. */
|
|
447
458
|
searchTracks(args?: Partial<SearchArgs>): Promise<Track[]>;
|
|
448
459
|
/** Returns a list of recently added artists from this library section. */
|
|
449
|
-
recentlyAddedArtists(
|
|
460
|
+
recentlyAddedArtists({ maxResults }?: {
|
|
461
|
+
maxResults?: number;
|
|
462
|
+
}): Promise<Artist[]>;
|
|
450
463
|
/** Returns a list of recently added albums from this library section. */
|
|
451
|
-
recentlyAddedAlbums(
|
|
464
|
+
recentlyAddedAlbums({ maxResults }?: {
|
|
465
|
+
maxResults?: number;
|
|
466
|
+
}): Promise<Album[]>;
|
|
452
467
|
/** Returns a list of recently added tracks from this library section. */
|
|
453
|
-
recentlyAddedTracks(
|
|
468
|
+
recentlyAddedTracks({ maxResults }?: {
|
|
469
|
+
maxResults?: number;
|
|
470
|
+
}): Promise<Track[]>;
|
|
454
471
|
/**
|
|
455
472
|
* Returns a list of tracks from this library section that are part of a sonic adventure.
|
|
456
473
|
* IDs should be of a track; other IDs will return an empty list or an error.
|
package/dist/src/library.js
CHANGED
|
@@ -19,7 +19,7 @@ export class Library {
|
|
|
19
19
|
*/
|
|
20
20
|
async sections() {
|
|
21
21
|
const key = '/library/sections';
|
|
22
|
-
const elems = await this.server.query(key);
|
|
22
|
+
const elems = await this.server.query({ path: key });
|
|
23
23
|
const sections = [];
|
|
24
24
|
if (!elems.MediaContainer.Directory) {
|
|
25
25
|
return sections;
|
|
@@ -207,7 +207,7 @@ export class Library {
|
|
|
207
207
|
...extra,
|
|
208
208
|
});
|
|
209
209
|
const url = `/library/sections?${search.toString()}`;
|
|
210
|
-
return this.server.query(url, 'post');
|
|
210
|
+
return this.server.query({ path: url, method: 'post' });
|
|
211
211
|
}
|
|
212
212
|
/**
|
|
213
213
|
* Returns a list of all media from all library sections.
|
|
@@ -239,7 +239,7 @@ export class Library {
|
|
|
239
239
|
* library, you may like to optimize the database.
|
|
240
240
|
*/
|
|
241
241
|
async optimize() {
|
|
242
|
-
await this.server.query('/library/optimize?async=1', 'put');
|
|
242
|
+
await this.server.query({ path: '/library/optimize?async=1', method: 'put' });
|
|
243
243
|
}
|
|
244
244
|
/**
|
|
245
245
|
* Validates a filter field and values are available as a custom filter for the library.
|
|
@@ -338,7 +338,7 @@ export class LibrarySection extends PlexObject {
|
|
|
338
338
|
* @param tab The library tab (recommended, library, collections, playlists, timeline).
|
|
339
339
|
* @param key A hub key.
|
|
340
340
|
*/
|
|
341
|
-
getWebURL(base, tab, key) {
|
|
341
|
+
getWebURL({ base, tab, key, } = {}) {
|
|
342
342
|
const params = new URLSearchParams();
|
|
343
343
|
params.append('source', this.key);
|
|
344
344
|
if (tab) {
|
|
@@ -348,7 +348,7 @@ export class LibrarySection extends PlexObject {
|
|
|
348
348
|
params.append('key', key);
|
|
349
349
|
params.append('pageType', 'list');
|
|
350
350
|
}
|
|
351
|
-
return this.server._buildWebURL(base,
|
|
351
|
+
return this.server._buildWebURL({ base, params });
|
|
352
352
|
}
|
|
353
353
|
/**
|
|
354
354
|
* Search the library. The http requests will be batched in container_size. If you are only looking for the
|
|
@@ -389,14 +389,14 @@ export class LibrarySection extends PlexObject {
|
|
|
389
389
|
*/
|
|
390
390
|
async analyze() {
|
|
391
391
|
const key = `/library/sections/${this.key}/analyze`;
|
|
392
|
-
await this.server.query(key, 'post');
|
|
392
|
+
await this.server.query({ path: key, method: 'post' });
|
|
393
393
|
}
|
|
394
394
|
/**
|
|
395
395
|
* If a section has items in the Trash, use this option to empty the Trash
|
|
396
396
|
*/
|
|
397
397
|
async emptyTrash() {
|
|
398
398
|
const key = `/library/sections/${this.key}/emptyTrash`;
|
|
399
|
-
await this.server.query(key, 'put');
|
|
399
|
+
await this.server.query({ path: key, method: 'put' });
|
|
400
400
|
}
|
|
401
401
|
/**
|
|
402
402
|
* Get Play History for this library Section for the owner.
|
|
@@ -404,21 +404,21 @@ export class LibrarySection extends PlexObject {
|
|
|
404
404
|
* @param mindate (datetime): Min datetime to return results from.
|
|
405
405
|
*/
|
|
406
406
|
// async history(maxresults=9999999, mindate?: Date): Promise<any> {
|
|
407
|
-
// return this.server.history(
|
|
407
|
+
// return this.server.history({ maxResults, minDate, librarySectionId: this.key, accountId: 1 })
|
|
408
408
|
// }
|
|
409
409
|
/**
|
|
410
410
|
* Scan this section for new media.
|
|
411
411
|
*/
|
|
412
412
|
async update() {
|
|
413
413
|
const key = `/library/sections/${this.key}/refresh`;
|
|
414
|
-
await this.server.query(key);
|
|
414
|
+
await this.server.query({ path: key });
|
|
415
415
|
}
|
|
416
416
|
/**
|
|
417
417
|
* Cancel update of this Library Section.
|
|
418
418
|
*/
|
|
419
419
|
async cancelUpdate() {
|
|
420
420
|
const key = `/library/sections/${this.key}/refresh`;
|
|
421
|
-
await this.server.query(key, 'delete');
|
|
421
|
+
await this.server.query({ path: key, method: 'delete' });
|
|
422
422
|
}
|
|
423
423
|
/**
|
|
424
424
|
* Forces a download of fresh media information from the internet.
|
|
@@ -426,7 +426,7 @@ export class LibrarySection extends PlexObject {
|
|
|
426
426
|
*/
|
|
427
427
|
async refresh() {
|
|
428
428
|
const key = `/library/sections/${this.key}/refresh?force=1`;
|
|
429
|
-
await this.server.query(key);
|
|
429
|
+
await this.server.query({ path: key });
|
|
430
430
|
}
|
|
431
431
|
/**
|
|
432
432
|
* Delete the preview thumbnails for items in this library. This cannot
|
|
@@ -434,12 +434,12 @@ export class LibrarySection extends PlexObject {
|
|
|
434
434
|
*/
|
|
435
435
|
async deleteMediaPreviews() {
|
|
436
436
|
const key = `/library/sections/${this.key}/indexes`;
|
|
437
|
-
await this.server.query(key, 'delete');
|
|
437
|
+
await this.server.query({ path: key, method: 'delete' });
|
|
438
438
|
}
|
|
439
439
|
/** Delete a library section. */
|
|
440
440
|
async delete() {
|
|
441
441
|
const key = `/library/sections/${this.key}`;
|
|
442
|
-
await this.server.query(key, 'delete');
|
|
442
|
+
await this.server.query({ path: key, method: 'delete' });
|
|
443
443
|
}
|
|
444
444
|
/**
|
|
445
445
|
* Edit a library
|
|
@@ -448,7 +448,7 @@ export class LibrarySection extends PlexObject {
|
|
|
448
448
|
async edit(kwargs) {
|
|
449
449
|
const params = new URLSearchParams(kwargs);
|
|
450
450
|
const part = `/library/sections/${this.key}?${params.toString()}`;
|
|
451
|
-
await this.server.query(part, 'put');
|
|
451
|
+
await this.server.query({ path: part, method: 'put' });
|
|
452
452
|
const library = await this.server.library();
|
|
453
453
|
const sections = await library.sections();
|
|
454
454
|
for (const section of sections) {
|
|
@@ -569,7 +569,7 @@ export class LibrarySection extends PlexObject {
|
|
|
569
569
|
}
|
|
570
570
|
async _loadFilters() {
|
|
571
571
|
const key = `/library/sections/${this.key}/all?includeMeta=1&includeAdvanced=1&X-Plex-Container-Start=0&X-Plex-Container-Size=0`;
|
|
572
|
-
const data = await this.server.query(key);
|
|
572
|
+
const data = await this.server.query({ path: key });
|
|
573
573
|
// rtag='Meta'
|
|
574
574
|
this._filterTypes = findItems(data, undefined, FilteringType);
|
|
575
575
|
}
|
|
@@ -664,10 +664,10 @@ export class ShowSection extends LibrarySection {
|
|
|
664
664
|
/**
|
|
665
665
|
* Returns a list of recently added episodes from this library section.
|
|
666
666
|
*
|
|
667
|
-
* @param
|
|
667
|
+
* @param options Filter and paging options.
|
|
668
668
|
*/
|
|
669
|
-
async recentlyAdded(args, libtype = 'episode',
|
|
670
|
-
return this.search({ libtype, maxresults, sort: 'episode.addedAt:desc', ...args });
|
|
669
|
+
async recentlyAdded({ args, libtype = 'episode', maxResults = 50, } = {}) {
|
|
670
|
+
return this.search({ libtype, maxresults: maxResults, sort: 'episode.addedAt:desc', ...args });
|
|
671
671
|
}
|
|
672
672
|
}
|
|
673
673
|
export class MusicSection extends LibrarySection {
|
|
@@ -702,16 +702,16 @@ export class MusicSection extends LibrarySection {
|
|
|
702
702
|
return this.search({ ...args, libtype: 'track' }, Track);
|
|
703
703
|
}
|
|
704
704
|
/** Returns a list of recently added artists from this library section. */
|
|
705
|
-
async recentlyAddedArtists(
|
|
706
|
-
return this.search({ maxresults, sort: 'addedAt:desc', libtype: 'artist' }, Artist);
|
|
705
|
+
async recentlyAddedArtists({ maxResults = 50 } = {}) {
|
|
706
|
+
return this.search({ maxresults: maxResults, sort: 'addedAt:desc', libtype: 'artist' }, Artist);
|
|
707
707
|
}
|
|
708
708
|
/** Returns a list of recently added albums from this library section. */
|
|
709
|
-
async recentlyAddedAlbums(
|
|
710
|
-
return this.search({ maxresults, sort: 'addedAt:desc', libtype: 'album' }, Album);
|
|
709
|
+
async recentlyAddedAlbums({ maxResults = 50 } = {}) {
|
|
710
|
+
return this.search({ maxresults: maxResults, sort: 'addedAt:desc', libtype: 'album' }, Album);
|
|
711
711
|
}
|
|
712
712
|
/** Returns a list of recently added tracks from this library section. */
|
|
713
|
-
async recentlyAddedTracks(
|
|
714
|
-
return this.search({ maxresults, sort: 'addedAt:desc', libtype: 'track' }, Track);
|
|
713
|
+
async recentlyAddedTracks({ maxResults = 50 } = {}) {
|
|
714
|
+
return this.search({ maxresults: maxResults, sort: 'addedAt:desc', libtype: 'track' }, Track);
|
|
715
715
|
}
|
|
716
716
|
/**
|
|
717
717
|
* Returns a list of tracks from this library section that are part of a sonic adventure.
|
|
@@ -770,7 +770,7 @@ export class Collections extends PartialPlexObject {
|
|
|
770
770
|
*/
|
|
771
771
|
async items() {
|
|
772
772
|
const key = `/library/metadata/${this.ratingKey}/children`;
|
|
773
|
-
const data = await this.server.query(key);
|
|
773
|
+
const data = await this.server.query({ path: key });
|
|
774
774
|
return (data.MediaContainer.Metadata?.map(d => new this.VIDEO_TYPE(this.server, d, undefined, this)) ?? []);
|
|
775
775
|
}
|
|
776
776
|
_loadFullData(data) {
|