1
0
Fork 0
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:
Bill Thornton 2023-04-18 20:50:21 -04:00 committed by GitHub
commit 23c3df7feb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 83 additions and 4 deletions

View 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);
}