Compare commits
5 Commits
v1.7.1.5
...
22a7eb8dcb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22a7eb8dcb | ||
|
|
07658f4fbc | ||
|
|
25ee5b73b4 | ||
|
|
8f8e251054 | ||
|
|
05529e5627 |
@@ -15,6 +15,8 @@ namespace Jellyfin.Plugin.MediaBarEnhanced.Configuration
|
||||
public int MaxMovies { get; set; } = 15;
|
||||
public int MaxTvShows { get; set; } = 15;
|
||||
public int MaxItems { get; set; } = 500;
|
||||
public int MaxParentalRating { get; set; } = 0;
|
||||
public int MaxDaysRecent { get; set; } = 0;
|
||||
public int PreloadCount { get; set; } = 3;
|
||||
public int FadeTransitionDuration { get; set; } = 500;
|
||||
public int MaxPaginationDots { get; set; } = 15;
|
||||
@@ -38,6 +40,7 @@ namespace Jellyfin.Plugin.MediaBarEnhanced.Configuration
|
||||
public bool EnableCustomMediaIds { get; set; } = true;
|
||||
public string PreferredVideoQuality { get; set; } = "Auto";
|
||||
public bool EnableSeasonalContent { get; set; } = false;
|
||||
public bool ExcludeSeasonalContent { get; set; } = true;
|
||||
public string SeasonalSections { get; set; } = "[]";
|
||||
public bool IsEnabled { get; set; } = true;
|
||||
public bool EnableClientSideSettings { get; set; } = false;
|
||||
|
||||
@@ -183,6 +183,14 @@
|
||||
during their active date ranges. If no season matches the current date, the default
|
||||
Custom Media IDs above or random selection are used as fallback.</div>
|
||||
</div>
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label>
|
||||
<input is="emby-checkbox" type="checkbox" id="ExcludeSeasonalContent"
|
||||
name="ExcludeSeasonalContent" />
|
||||
<span>Exclude Seasonal Content from Random Lists</span>
|
||||
</label>
|
||||
<div class="fieldDescription">When enabled, any items defined in your Seasonal Sections below will be explicitly excluded from being shown when the plugin pulls random items from your library.</div>
|
||||
</div>
|
||||
<div id="seasonalContentContainer" style="display: none;">
|
||||
|
||||
<div
|
||||
@@ -356,7 +364,7 @@
|
||||
mobile).</div>
|
||||
</div>
|
||||
|
||||
<h2 class="sectionTitle">Content Sorting</h2>
|
||||
<h2 class="sectionTitle">Content Sorting and Filtering</h2>
|
||||
<div class="selectContainer">
|
||||
<label class="selectLabel" for="SortBy">Sort By</label>
|
||||
<select is="emby-select" id="SortBy" name="SortBy"
|
||||
@@ -387,6 +395,16 @@
|
||||
<b>Note:</b> Sorting settings apply to both Server content and Custom IDs. 'Original'
|
||||
preserves Custom List order.
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel inputLabelUnfocused" for="MaxParentalRating">Max Parental Rating (Age Limit)</label>
|
||||
<input is="emby-input" type="number" id="MaxParentalRating" name="MaxParentalRating" />
|
||||
<div class="fieldDescription">Items exceeding this age rating will not be shown. Leave blank or set to 0 for no limit. Examples: 12, 16, 18.</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel inputLabelUnfocused" for="MaxDaysRecent">Max Days Recent</label>
|
||||
<input is="emby-input" type="number" id="MaxDaysRecent" name="MaxDaysRecent" />
|
||||
<div class="fieldDescription">Only show items added in the last X days. Leave blank or set to 0 for no limit. Example: 30.</div>
|
||||
</div>
|
||||
|
||||
<h2 class="sectionTitle">Content Limits</h2>
|
||||
<p>Leave a setting blank to use the default value.</p>
|
||||
@@ -505,7 +523,8 @@
|
||||
'EnableSeasonalContent', 'EnableClientSideSettings', 'SortBy', 'SortOrder',
|
||||
'PreferLocalTrailers', 'ApplyLimitsToCustomIds', 'SeasonalSections',
|
||||
'PreferLocalBackdrops', 'RandomizeThemeVideos', 'RandomizeLocalTrailers',
|
||||
'IncludeWatchedContent', 'ShowPaginationDots'
|
||||
'IncludeWatchedContent', 'ShowPaginationDots', 'MaxParentalRating',
|
||||
'MaxDaysRecent', 'ExcludeSeasonalContent'
|
||||
];
|
||||
|
||||
// Manual mapping for MediaBarIsEnabled -> IsEnabled, to avoid conflicts with other plugins
|
||||
@@ -609,7 +628,8 @@
|
||||
'EnableSeasonalContent', 'EnableClientSideSettings', 'SortBy', 'SortOrder',
|
||||
'PreferLocalTrailers', 'ApplyLimitsToCustomIds', 'SeasonalSections',
|
||||
'PreferLocalBackdrops', 'RandomizeThemeVideos', 'RandomizeLocalTrailers',
|
||||
'IncludeWatchedContent', 'ShowPaginationDots'
|
||||
'IncludeWatchedContent', 'ShowPaginationDots', 'MaxParentalRating',
|
||||
'MaxDaysRecent', 'ExcludeSeasonalContent'
|
||||
];
|
||||
|
||||
keys.forEach(function (key) {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<!-- <TreatWarningsAsErrors>false</TreatWarningsAsErrors> -->
|
||||
<Title>Jellyfin Media Bar Enhanced Plugin</Title>
|
||||
<Authors>CodeDevMLH</Authors>
|
||||
<Version>1.7.1.5</Version>
|
||||
<Version>1.7.1.6</Version>
|
||||
<RepositoryUrl>https://github.com/CodeDevMLH/jellyfin-plugin-media-bar-enhanced</RepositoryUrl>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -814,7 +814,6 @@
|
||||
@media (max-width: 400px) {
|
||||
.button-container {
|
||||
gap: 10px;
|
||||
/* top: calc(50% + 27vh); */
|
||||
}
|
||||
|
||||
.play-button,
|
||||
|
||||
@@ -39,6 +39,8 @@ const CONFIG = {
|
||||
fadeTransitionDuration: 500,
|
||||
maxPaginationDots: 15,
|
||||
showPaginationDots: true,
|
||||
maxParentalRating: null,
|
||||
maxDaysRecent: null,
|
||||
slideAnimationEnabled: true,
|
||||
enableVideoBackdrop: true,
|
||||
useSponsorBlock: true,
|
||||
@@ -64,6 +66,7 @@ const CONFIG = {
|
||||
sortOrder: "Ascending",
|
||||
applyLimitsToCustomIds: false,
|
||||
seasonalSections: "[]",
|
||||
excludeSeasonalContent: true,
|
||||
isEnabled: true,
|
||||
};
|
||||
|
||||
@@ -1111,13 +1114,60 @@ const ApiUtils = {
|
||||
|
||||
// Filter by isPlayed=False unless IncludeWatchedContent is enabled
|
||||
const playedFilter = CONFIG.includeWatchedContent ? '' : '&isPlayed=False';
|
||||
|
||||
let parentalFilter = '';
|
||||
if (CONFIG.maxParentalRating) {
|
||||
parentalFilter = `&MaxOfficialRating=${CONFIG.maxParentalRating}`;
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`${STATE.jellyfinData.serverAddress}/Items?IncludeItemTypes=Movie,Series&Recursive=true&hasOverview=true&imageTypes=Logo,Backdrop&${sortParams}${playedFilter}&enableUserData=true&Limit=${CONFIG.maxItems}&fields=Id`,
|
||||
{
|
||||
headers: this.getAuthHeaders(),
|
||||
let dateFilter = '';
|
||||
if (CONFIG.maxDaysRecent) {
|
||||
const pastDate = new Date();
|
||||
pastDate.setDate(pastDate.getDate() - CONFIG.maxDaysRecent);
|
||||
dateFilter = `&minDateLastSaved=${pastDate.toISOString()}`;
|
||||
}
|
||||
|
||||
// Exclude seasonal content from random lists
|
||||
let excludeFilter = '';
|
||||
if (CONFIG.excludeSeasonalContent && CONFIG.seasonalSections) {
|
||||
try {
|
||||
const sections = JSON.parse(CONFIG.seasonalSections || "[]");
|
||||
let allExcludedIds = [];
|
||||
|
||||
for (const section of sections) {
|
||||
if (section.MediaIds) {
|
||||
const idsInThisSection = section.MediaIds.split(/[\n,]/)
|
||||
.map((line) => {
|
||||
const urlMatch = line.match(/\[(.*?)\]/);
|
||||
let id = line;
|
||||
if (urlMatch) {
|
||||
id = line.replace(/\[.*?\]/, '').trim();
|
||||
const guidMatch = id.match(/([0-9a-f]{32})/i);
|
||||
if (guidMatch) { id = guidMatch[1]; } else { id = id.split('|')[0].trim(); }
|
||||
}
|
||||
return id.trim();
|
||||
})
|
||||
.filter((id) => id);
|
||||
|
||||
allExcludedIds.push(...idsInThisSection);
|
||||
}
|
||||
}
|
||||
|
||||
if (allExcludedIds.length > 0) {
|
||||
excludeFilter = `&ExcludeItemIds=${allExcludedIds.join(',')}`;
|
||||
}
|
||||
} catch(e) {
|
||||
console.error("🎬 Media Bar:", "Error extracting seasonal IDs for exclusion:", e);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const fetchItems = async (currentDateFilter) => {
|
||||
const url = `${STATE.jellyfinData.serverAddress}/Items?IncludeItemTypes=Movie,Series&Recursive=true&hasOverview=true&imageTypes=Logo,Backdrop&${sortParams}${playedFilter}${parentalFilter}${currentDateFilter}${excludeFilter}&enableUserData=true&Limit=${CONFIG.maxItems}&fields=Id,DateCreated`;
|
||||
const resp = await fetch(url, { headers: this.getAuthHeaders() });
|
||||
return resp;
|
||||
};
|
||||
|
||||
let response = await fetchItems(dateFilter);
|
||||
|
||||
if (!response.ok) {
|
||||
console.error("🎬 Media Bar:",
|
||||
@@ -1126,12 +1176,32 @@ const ApiUtils = {
|
||||
return [];
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const items = data.Items || [];
|
||||
let data = await response.json();
|
||||
let items = data.Items || [];
|
||||
|
||||
console.log("🎬 Media Bar:",
|
||||
`Successfully fetched ${items.length} random items from server`
|
||||
);
|
||||
// Local exact DateCreated filter: minDateLastSaved pulls items that were merely modified recently (e.g. metadata updates)
|
||||
// explicitly discard them if their actual DateCreated is older than X days
|
||||
if (CONFIG.maxDaysRecent && dateFilter !== '') {
|
||||
const pastDate = new Date();
|
||||
pastDate.setDate(pastDate.getDate() - CONFIG.maxDaysRecent);
|
||||
items = items.filter(item => {
|
||||
if (!item.DateCreated) return true;
|
||||
return new Date(item.DateCreated) >= pastDate;
|
||||
});
|
||||
}
|
||||
|
||||
// Fallback: If we have a date filter but no items are returned, try again without it
|
||||
if (items.length === 0 && dateFilter !== '') {
|
||||
console.warn("🎬 Media Bar:", `No items found within the last ${CONFIG.maxDaysRecent} days. Falling back to random fetching.`);
|
||||
response = await fetchItems('');
|
||||
|
||||
if (response.ok) {
|
||||
data = await response.json();
|
||||
items = data.Items || [];
|
||||
}
|
||||
}
|
||||
|
||||
console.log("🎬 Media Bar:", `Successfully fetched ${items.length} random items from server`);
|
||||
|
||||
return items.map((item) => item.Id);
|
||||
} catch (error) {
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
"imageUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/raw/branch/main/logo.png",
|
||||
"versions": [
|
||||
{
|
||||
"version": "1.7.1.5",
|
||||
"changelog": "- feat: add option to disable pagination dots/counter\n- fix button issue on mobile when using ElegantFin Theme",
|
||||
"version": "1.7.1.6",
|
||||
"changelog": "- feat: add option to disable pagination dots/counter\n- feat: add exclude seasonal content from random fetching option\n- fix button issue on mobile when using ElegantFin Theme",
|
||||
"targetAbi": "10.11.0.0",
|
||||
"sourceUrl": "https://git.mahom03-spacecloud.de/CodeDevMLH/jellyfin-plugin-media-bar-enhanced/releases/download/v1.7.1.5/Jellyfin.Plugin.MediaBarEnhanced.zip",
|
||||
"checksum": "f9a18cb5f38a7a8e54a45e13e5e39bd8",
|
||||
|
||||
73
test_scripts/test_direct_date_created.js
Normal file
73
test_scripts/test_direct_date_created.js
Normal file
@@ -0,0 +1,73 @@
|
||||
(async () => {
|
||||
const apiClient = window.ApiClient;
|
||||
if (!apiClient) {
|
||||
console.error("ApiClient not found. Are you logged in?");
|
||||
return;
|
||||
}
|
||||
|
||||
const userId = apiClient.getCurrentUserId();
|
||||
const serverAddress = apiClient.serverAddress();
|
||||
|
||||
const maxDaysRecent = 30; // 30 Tage Limit
|
||||
const pastDate = new Date();
|
||||
pastDate.setDate(pastDate.getDate() - maxDaysRecent);
|
||||
const dateStr = pastDate.toISOString();
|
||||
|
||||
console.log(`\n%c=== TEST: DateCreated Direkt-Abfrage ===`, "color: #00a4dc; font-weight: bold; font-size: 14px;");
|
||||
console.log(`Wir suchen Filme, die nach dem ${dateStr} hinzugefügt wurden.\n`);
|
||||
|
||||
// Wir probieren alle denkbaren Parameter-Schreibweisen aus,
|
||||
// die Jellyfin historisch oder in Forks für "DateCreated" akzeptieren könnte.
|
||||
const testCases = [
|
||||
{ name: "MinDateCreated (PascalCase)", param: `MinDateCreated=${dateStr}` },
|
||||
{ name: "minDateCreated (camelCase)", param: `minDateCreated=${dateStr}` },
|
||||
{ name: "DateCreatedMin", param: `DateCreatedMin=${dateStr}` },
|
||||
{ name: "dateCreatedMin", param: `dateCreatedMin=${dateStr}` },
|
||||
{ name: "StartDate", param: `StartDate=${dateStr}` },
|
||||
{ name: "startDate", param: `startDate=${dateStr}` }
|
||||
];
|
||||
|
||||
try {
|
||||
for (let i = 0; i < testCases.length; i++) {
|
||||
const test = testCases[i];
|
||||
const apiUrl = `${serverAddress}/Items?IncludeItemTypes=Movie,Series&Recursive=true&enableUserData=true&Limit=5&fields=Id,DateCreated&userId=${userId}&${test.param}`;
|
||||
|
||||
console.log(`%cTest ${i+1}: ${test.name}`, "color: yellow;");
|
||||
console.log(`URL: ${apiUrl}`);
|
||||
|
||||
const response = await fetch(apiUrl, {
|
||||
headers: {
|
||||
Authorization: `MediaBrowser Client="${apiClient.appName()}", Device="${apiClient.deviceName()}", DeviceId="${apiClient.deviceId()}", Version="${apiClient.appVersion()}", Token="${apiClient.accessToken()}"`
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
console.error(`-> ❌ HTTP Fehler: ${response.status}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const items = data.Items || [];
|
||||
|
||||
// Zur Auswertung: Wenn die Abfrage ignoriert wird, liefert er oft ALLE (hier max 5) zurück.
|
||||
// Filtert er wirklich, sollten es WENIGER als 5, und zwar im besten Fall genau die RICHTIGEN sein.
|
||||
console.log(`-> Ergebnis: ${items.length} Items zurückgeliefert.`);
|
||||
|
||||
if (items.length > 0) {
|
||||
// Wir checken, ob die zurückgelieferten Items WIRKLICH neu sind
|
||||
const oldItems = items.filter(item => new Date(item.DateCreated) < pastDate);
|
||||
if (oldItems.length > 0) {
|
||||
console.log(` ❌ Filter FEHLGESCHLAGEN: Es wurden ${oldItems.length} "alte" Filme zurückgegeben (z.B. ${oldItems[0].Name}). Er ignoriert also den Parameter.`);
|
||||
} else {
|
||||
console.log(` ✅ Filter KÖNNTE funktionieren: Alle zurückgegebenen Filme sind neuer als unser Datum! (Erster: ${items[0].Name})`);
|
||||
}
|
||||
} else {
|
||||
console.log(` ❓ Keine Items gefunden (entweder strenger Filter oder gar keine neuen Filme vorhanden).`);
|
||||
}
|
||||
console.log("\n");
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Abruf:", error);
|
||||
}
|
||||
})();
|
||||
56
test_scripts/test_filters_dates.js
Normal file
56
test_scripts/test_filters_dates.js
Normal file
@@ -0,0 +1,56 @@
|
||||
(async () => {
|
||||
const apiClient = window.ApiClient;
|
||||
if (!apiClient) {
|
||||
console.error("ApiClient not found. Are you logged in?");
|
||||
return;
|
||||
}
|
||||
|
||||
const userId = apiClient.getCurrentUserId();
|
||||
const serverAddress = apiClient.serverAddress();
|
||||
|
||||
const maxDaysRecent = 30; // Test: Added in last 30 days
|
||||
const pastDate = new Date();
|
||||
pastDate.setDate(pastDate.getDate() - maxDaysRecent);
|
||||
const dateStr = pastDate.toISOString();
|
||||
|
||||
console.log(`Searching for items added after: ${dateStr}`);
|
||||
|
||||
const testUrls = [
|
||||
// Test 1: minDateCreated (CamelCase)
|
||||
`${serverAddress}/Items?IncludeItemTypes=Movie,Series&Recursive=true&enableUserData=true&Limit=5&fields=Id,DateCreated&userId=${userId}&minDateCreated=${dateStr}`,
|
||||
// Test 2: minDateLastSaved
|
||||
`${serverAddress}/Items?IncludeItemTypes=Movie,Series&Recursive=true&enableUserData=true&Limit=5&fields=Id,DateCreated&userId=${userId}&minDateLastSaved=${dateStr}`,
|
||||
];
|
||||
|
||||
try {
|
||||
for (let i = 0; i < testUrls.length; i++) {
|
||||
const apiUrl = testUrls[i];
|
||||
console.log(`\n%cTest ${i+1}: Testing URL:\n${apiUrl}`, "color: yellow;");
|
||||
|
||||
const response = await fetch(apiUrl, {
|
||||
headers: {
|
||||
Authorization: `MediaBrowser Client="${apiClient.appName()}", Device="${apiClient.deviceName()}", DeviceId="${apiClient.deviceId()}", Version="${apiClient.appVersion()}", Token="${apiClient.accessToken()}"`
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
console.error(`Failed to fetch items: ${response.status} ${response.statusText}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const items = data.Items || [];
|
||||
|
||||
console.log(`%cErgebnis: ${items.length} Items gefunden!`, "color: #00a4dc; font-weight: bold;");
|
||||
|
||||
if(items.length > 0) {
|
||||
console.log("Gefundene Items:");
|
||||
items.forEach(item => {
|
||||
console.log(`- Name: ${item.Name}, DateCreated: ${item.DateCreated}, Art: ${item.Type}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Abrufen der URL:", error);
|
||||
}
|
||||
})();
|
||||
72
test_scripts/test_filters_dates_final.js
Normal file
72
test_scripts/test_filters_dates_final.js
Normal file
@@ -0,0 +1,72 @@
|
||||
(async () => {
|
||||
const apiClient = window.ApiClient;
|
||||
if (!apiClient) {
|
||||
console.error("ApiClient not found. Are you logged in?");
|
||||
return;
|
||||
}
|
||||
|
||||
const userId = apiClient.getCurrentUserId();
|
||||
const serverAddress = apiClient.serverAddress();
|
||||
|
||||
const maxDaysRecent = 30; // Test: Added in last 30 days
|
||||
|
||||
// 1. Calculate the cutoff date
|
||||
const pastDate = new Date();
|
||||
pastDate.setDate(pastDate.getDate() - maxDaysRecent);
|
||||
const dateStr = pastDate.toISOString();
|
||||
|
||||
console.log(`\n%c=== TEST: 2-Stufen "Zuletzt Hinzugefügt" Filter ===`, "color: #00a4dc; font-weight: bold; font-size: 14px;");
|
||||
console.log(`Suche Items neuer als: ${dateStr} (${maxDaysRecent} Tage alt)\n`);
|
||||
|
||||
const apiUrl = `${serverAddress}/Items?IncludeItemTypes=Movie,Series&Recursive=true&enableUserData=true&Limit=50&fields=Id,DateCreated&userId=${userId}&minDateLastSaved=${dateStr}`;
|
||||
|
||||
try {
|
||||
console.log(`%cSchritt 1: API Call mit minDateLastSaved...`, "color: yellow;");
|
||||
console.log(`URL: ${apiUrl}`);
|
||||
|
||||
const response = await fetch(apiUrl, {
|
||||
headers: {
|
||||
Authorization: `MediaBrowser Client="${apiClient.appName()}", Device="${apiClient.deviceName()}", DeviceId="${apiClient.deviceId()}", Version="${apiClient.appVersion()}", Token="${apiClient.accessToken()}"`
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch items: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
let items = data.Items || [];
|
||||
|
||||
console.log(`-> API lieferte ${items.length} potenziell neue/geänderte Items zurück.\n`);
|
||||
if (items.length > 0) {
|
||||
console.log("Die API hielt diese Items für neu/aktuell:");
|
||||
items.forEach(item => console.log(` - ${item.Name} (DateCreated: ${item.DateCreated})`));
|
||||
}
|
||||
|
||||
console.log(`\n%cSchritt 2: Lokaler DateCreated Filter (Wie das Plugin ihn jetzt nutzt)...`, "color: yellow;");
|
||||
|
||||
// Exakt dieser Filter-Block ist jetzt auch so in mediaBarEnhanced.js
|
||||
const finalItems = items.filter(item => {
|
||||
if (!item.DateCreated) return true; // Fallback falls Jellyfin kein Datum schickt
|
||||
const dCreated = new Date(item.DateCreated);
|
||||
return dCreated >= pastDate;
|
||||
});
|
||||
|
||||
console.log(`%c-> FINALES ERGEBNIS: ${finalItems.length} echte Neuzugänge bleiben übrig!`, "color: #00ff00; font-weight: bold; font-size: 14px;");
|
||||
|
||||
if(finalItems.length > 0) {
|
||||
console.log("Diese Items schaffen es in die Slideshow:");
|
||||
finalItems.forEach(item => {
|
||||
console.log(` 🎬 Name: ${item.Name}, DateCreated: ${item.DateCreated}`);
|
||||
});
|
||||
}
|
||||
|
||||
// Teste den Fallback
|
||||
if(finalItems.length === 0 && items.length > 0) {
|
||||
console.log("\n%c💡 HINWEIS: Da nach Filterung 0 Items übrig bleiben, greift in der Slideshow jetzt automatisch unser Fallback und zeigt zufällige Filme aller Jahre!", "color: orange;");
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Abruf:", error);
|
||||
}
|
||||
})();
|
||||
62
test_scripts/test_filters_url.js
Normal file
62
test_scripts/test_filters_url.js
Normal file
@@ -0,0 +1,62 @@
|
||||
(async () => {
|
||||
const apiClient = window.ApiClient;
|
||||
if (!apiClient) {
|
||||
console.error("ApiClient not found. Are you logged in?");
|
||||
return;
|
||||
}
|
||||
|
||||
const userId = apiClient.getCurrentUserId();
|
||||
const serverAddress = apiClient.serverAddress();
|
||||
|
||||
// Example test configuration flags
|
||||
const maxItems = 50;
|
||||
const includeWatchedContent = false; // set to false to ONLY show unplayed (newly watched)
|
||||
const maxParentalRating = 12; // Test age limit
|
||||
const maxDaysRecent = 30; // Test recency limit
|
||||
|
||||
// Build the query parameters just like in mediaBarEnhanced.js
|
||||
const sortParams = "sortBy=Random";
|
||||
const playedFilter = includeWatchedContent ? '' : '&isPlayed=False';
|
||||
|
||||
let parentalFilter = '';
|
||||
if (maxParentalRating) {
|
||||
parentalFilter = `&MaxOfficialRating=${maxParentalRating}`;
|
||||
}
|
||||
|
||||
let dateFilter = '';
|
||||
if (maxDaysRecent) {
|
||||
const pastDate = new Date();
|
||||
pastDate.setDate(pastDate.getDate() - maxDaysRecent);
|
||||
dateFilter = `&MinDateCreated=${pastDate.toISOString()}`;
|
||||
}
|
||||
|
||||
const apiUrl = `${serverAddress}/Items?IncludeItemTypes=Movie,Series&Recursive=true&hasOverview=true&imageTypes=Logo,Backdrop&${sortParams}${playedFilter}${parentalFilter}${dateFilter}&enableUserData=true&Limit=${maxItems}&fields=Id&userId=${userId}`;
|
||||
|
||||
try {
|
||||
console.log(`Testing generated URL with filters:\n%c${apiUrl}`, "color: yellow;");
|
||||
|
||||
// Execute the fetch
|
||||
const response = await fetch(apiUrl, {
|
||||
headers: {
|
||||
Authorization: `MediaBrowser Client="${apiClient.appName()}", Device="${apiClient.deviceName()}", DeviceId="${apiClient.deviceId()}", Version="${apiClient.appVersion()}", Token="${apiClient.accessToken()}"`
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch items: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const items = data.Items || [];
|
||||
|
||||
console.log(`%cErgebnis: ${items.length} Items gefunden!`, "color: #00a4dc; font-weight: bold;");
|
||||
|
||||
if(items.length > 0) {
|
||||
console.log("Erstes Item als Beispiel:");
|
||||
console.dir(items[0]);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error("Fehler beim Abrufen der URL:", error);
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user