mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Merge pull request #4221 from dann-merlin/fix_long_getItems_request_URL
This commit is contained in:
commit
23c3df7feb
6 changed files with 83 additions and 4 deletions
|
@ -61,6 +61,7 @@
|
|||
- [Rob Farraher](https://github.com/farraherbg)
|
||||
- [Pier-Luc Ducharme](https://github.com/pl-ducharme)
|
||||
- [Anantharaju S](https://github.com/Anantharajus)
|
||||
- [Merlin Sievers](https://github.com/dann-merlin)
|
||||
|
||||
# Emby Contributors
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import serverNotifications from '../../scripts/serverNotifications';
|
|||
import { playbackManager } from '../playback/playbackmanager';
|
||||
import Events from '../../utils/events.ts';
|
||||
import globalize from '../../scripts/globalize';
|
||||
import { getItems } from '../../utils/jellyfin-apiclient/getItems.ts';
|
||||
|
||||
import NotificationIcon from './notificationicon.png';
|
||||
|
||||
|
@ -130,7 +131,7 @@ function onLibraryChanged(data, apiClient) {
|
|||
newItems.length = 12;
|
||||
}
|
||||
|
||||
apiClient.getItems(apiClient.getCurrentUserId(), {
|
||||
getItems(apiClient, apiClient.getCurrentUserId(), {
|
||||
|
||||
Recursive: true,
|
||||
Limit: 3,
|
||||
|
|
|
@ -13,6 +13,7 @@ import ServerConnections from '../ServerConnections';
|
|||
import alert from '../alert';
|
||||
import { PluginType } from '../../types/plugin.ts';
|
||||
import { includesAny } from '../../utils/container.ts';
|
||||
import { getItems } from '../../utils/jellyfin-apiclient/getItems.ts';
|
||||
|
||||
const UNLIMITED_ITEMS = -1;
|
||||
|
||||
|
@ -127,7 +128,7 @@ function getItemsForPlayback(serverId, query) {
|
|||
query.EnableTotalRecordCount = false;
|
||||
query.CollapseBoxSetItems = false;
|
||||
|
||||
return apiClient.getItems(apiClient.getCurrentUserId(), query);
|
||||
return getItems(apiClient, apiClient.getCurrentUserId(), query);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import ServerConnections from '../../components/ServerConnections';
|
|||
import alert from '../../components/alert';
|
||||
import { PluginType } from '../../types/plugin.ts';
|
||||
import Events from '../../utils/events.ts';
|
||||
import { getItems } from '../../utils/jellyfin-apiclient/getItems.ts';
|
||||
|
||||
// Based on https://github.com/googlecast/CastVideos-chrome/blob/master/CastVideos.js
|
||||
|
||||
|
@ -482,7 +483,7 @@ function getItemsForPlayback(apiClient, query) {
|
|||
query.ExcludeLocationTypes = 'Virtual';
|
||||
query.EnableTotalRecordCount = false;
|
||||
|
||||
return apiClient.getItems(userId, query);
|
||||
return getItems(apiClient, userId, query);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
import Events from '../../../utils/events.ts';
|
||||
import { getItems } from '../../../utils/jellyfin-apiclient/getItems.ts';
|
||||
|
||||
/**
|
||||
* Constants
|
||||
|
@ -88,7 +89,7 @@ export function getItemsForPlayback(apiClient, query) {
|
|||
query.EnableTotalRecordCount = false;
|
||||
query.CollapseBoxSetItems = false;
|
||||
|
||||
return apiClient.getItems(apiClient.getCurrentUserId(), query);
|
||||
return getItems(apiClient, apiClient.getCurrentUserId(), query);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
74
src/utils/jellyfin-apiclient/getItems.ts
Normal file
74
src/utils/jellyfin-apiclient/getItems.ts
Normal file
|
@ -0,0 +1,74 @@
|
|||
import type { BaseItemDtoQueryResult } from '@jellyfin/sdk/lib/generated-client';
|
||||
import { ApiClient } from 'jellyfin-apiclient';
|
||||
|
||||
interface GetItemsRequest {
|
||||
Ids?: string;
|
||||
Limit?: number;
|
||||
}
|
||||
|
||||
const ITEMS_PER_REQUEST_LIMIT = 40;
|
||||
|
||||
function getItemsSplit(apiClient: ApiClient, userId: string, options: GetItemsRequest) {
|
||||
const optionsTemplate = { ...options };
|
||||
const ids = options.Ids?.split(',') || [];
|
||||
const results = [];
|
||||
const limit = options.Limit ?? Infinity;
|
||||
|
||||
let end;
|
||||
for (let start = 0; start < ids.length && start < limit; start = end) {
|
||||
end = start + ITEMS_PER_REQUEST_LIMIT;
|
||||
if (end > limit) {
|
||||
end = limit;
|
||||
}
|
||||
const idsSlice = ids.slice(start, end);
|
||||
optionsTemplate.Ids = idsSlice.join(',');
|
||||
results.push(apiClient.getItems(userId, optionsTemplate));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
function mergeResults(results: BaseItemDtoQueryResult[]) {
|
||||
const merged: BaseItemDtoQueryResult = {
|
||||
Items: [],
|
||||
TotalRecordCount: 0,
|
||||
StartIndex: 0
|
||||
};
|
||||
|
||||
for (const result of results) {
|
||||
if (result.Items == null) {
|
||||
console.log('[getItems] Retrieved Items array is invalid', result.Items);
|
||||
continue;
|
||||
}
|
||||
if (result.TotalRecordCount == null) {
|
||||
console.log('[getItems] Retrieved TotalRecordCount is invalid', result.TotalRecordCount);
|
||||
continue;
|
||||
}
|
||||
if (result.StartIndex == null) {
|
||||
console.log('[getItems] Retrieved StartIndex is invalid', result.StartIndex);
|
||||
continue;
|
||||
}
|
||||
merged.Items = merged.Items?.concat(result.Items);
|
||||
merged.TotalRecordCount! += result.TotalRecordCount;
|
||||
merged.StartIndex = Math.min(merged.StartIndex || 0, result.StartIndex);
|
||||
}
|
||||
return merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transparently handles the call to apiClient.getItems splitting the
|
||||
* call into multiple ones if the URL might get too long.
|
||||
* @param apiClient The ApiClient to use
|
||||
* @param userId User id to pass to actual getItems call
|
||||
* @param options Options object to specify getItems option. This includes a possibly long Items list that will be split up.
|
||||
* @returns A promise that resolves to the merged result of all getItems calls
|
||||
*/
|
||||
export function getItems(apiClient: ApiClient, userId: string, options?: GetItemsRequest) {
|
||||
const ids = options?.Ids?.split(',');
|
||||
if (!options || !ids || ids.length <= ITEMS_PER_REQUEST_LIMIT) {
|
||||
return apiClient.getItems(apiClient.getCurrentUserId(), options);
|
||||
}
|
||||
const results = getItemsSplit(apiClient, userId, options);
|
||||
|
||||
return Promise.all(results).then(mergeResults);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue