add auto seasonal lists

This commit is contained in:
CodeDevMLH
2025-09-27 02:19:09 +02:00
parent 1748a8ab3d
commit 1b05d4f863
3 changed files with 142 additions and 3 deletions

52
SEASONAL_LISTS.md Normal file
View File

@@ -0,0 +1,52 @@
# Seasonal Lists Documentation
This document explains how to use seasonal lists with the Jellyfin Spotlight system.
## Configuration
To enable seasonal lists, set `useSeasonalLists = true` in the main script.js file.
## Seasonal Periods
The system automatically detects the following periods:
### Special Events (take precedence over seasons)
- **New Year**: January 1-7 → `newyear_list.txt`
- **Valentine's day**: February 10-20 → `valentine_list.txt`
- **Easter**: 1 week around Easter Sunday → `easter_list.txt`
- **Halloween**: October 20-31 → `halloween_list.txt`
### Regular Seasons
- **Spring**: March-May → `spring_list.txt`
- **Summer**: June-August → `summer_list.txt`
- **Autumn**: September-November → `autumn_list.txt`
- **Winter**: December-February → `winter_list.txt`
## List Files
Create the following files in your `featured` directory:
- `spring_list.txt` - Spring movies/shows
- `summer_list.txt` - Summer movies/shows
- `autumn_list.txt` - Autumn movies/shows
- `winter_list.txt` - Winter movies/shows
- `newyear_list.txt` - New Year themed content
- `valentine_list.txt` - Romance/Valentine themed content
- `easter_list.txt` - Easter/Family themed content
- `halloween_list.txt` - Horror/Halloween themed content
## File Format
Each seasonal list file follows the same format as the main `list.txt`:
```
Title of List [muteon/muteoff]
movie_id_1
movie_id_2
series_id_1
...
```
## Fallback
If seasonal lists are disabled or a seasonal file doesn't exist, the system will fall back to using the default `list.txt` file.

View File

@@ -1,4 +1,4 @@
Spotlight MuteOn
Title of List [muteon/muteoff]
f81c9b854e3edc62fb049e252c488115 Hunger Games
7d515072462d6cedd74de8e2df71888f Interstellar
df4f3da3066455404e6b874d22ba86aa Fast X

View File

@@ -15,6 +15,19 @@ let plotMaxLength = 550; // Maximum number of characters in the plot
let trailerMaxLength = 0; // Default value 0; length measured in ms, set to 0 to disable, could be used instead of SponsorBlock
let startTrailerMuted = true; // Default value true; set to false to start the video unmuted
// Seasonal lists configuration
let useSeasonalLists = false; // Set to true to enable automatic seasonal list switching
const seasonalLists = {
spring: 'spring_list.txt', // spring (march-may)
summer: 'summer_list.txt', // summer (june-august)
autumn: 'autumn_list.txt', // autumn (september-november)
winter: 'winter_list.txt', // winter (december-february)
newyear: 'newyear_list.txt', // new year (1.-7. januar)
valentine: 'valentine_list.txt', // valentines day (10.-20. februar)
easter: 'easter_list.txt', // easter (variable dates, March-April)
halloween: 'halloween_list.txt' // halloween (20.-31. october)
};
// Language specific strings
// currently implemented: en, de, fr, es, it, pl, nl
@@ -91,6 +104,78 @@ const setLanguage = (language) => {
const languageIndex = setLanguage(browserLanguage);
// Seasonal list detection
const getCurrentSeason = () => {
if (!useSeasonalLists) {
return null;
}
const now = new Date();
const month = now.getMonth() + 1; // 1-12
const day = now.getDate();
// Special events (take precedence over seasons)
// new year: 1-7 january
if (month === 1 && day <= 7) return 'newyear';
// valentines day: 10-20 february
if (month === 2 && day >= 10 && day <= 20) return 'valentine';
// halloween: 20-31 cotober
if (month === 10 && day >= 20) return 'halloween';
// Easter calculation (simplified - around March-April)
const easterStart = getEasterPeriod(now.getFullYear());
if (isInEasterPeriod(now, easterStart)) return 'easter';
// Regular seasons
if (month >= 3 && month <= 5) return 'spring'; // march-may
if (month >= 6 && month <= 8) return 'summer'; // june-august
if (month >= 9 && month <= 11) return 'autumn'; // september-november
if (month === 12 || month <= 2) return 'winter'; // december-february
return null;
};
// Simplified Easter calculation (Western Easter)
const getEasterPeriod = (year) => {
const a = year % 19;
const b = Math.floor(year / 100);
const c = year % 100;
const d = Math.floor(b / 4);
const e = b % 4;
const f = Math.floor((b + 8) / 25);
const g = Math.floor((b - f + 1) / 3);
const h = (19 * a + b - d - g + 15) % 30;
const i = Math.floor(c / 4);
const k = c % 4;
const l = (32 + 2 * e + 2 * i - h - k) % 7;
const m = Math.floor((a + 11 * h + 22 * l) / 451);
const month = Math.floor((h + l - 7 * m + 114) / 31);
const day = ((h + l - 7 * m + 114) % 31) + 1;
return { month, day };
};
// Check if current date is in Easter period (2 weeks around Easter)
const isInEasterPeriod = (currentDate, easter) => {
const easterDate = new Date(currentDate.getFullYear(), easter.month - 1, easter.day);
const timeDiff = Math.abs(currentDate.getTime() - easterDate.getTime());
const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24));
return daysDiff <= 7; // 1 week before and after Easter
};
// Get the appropriate list filename based on season
const getSeasonalListFileName = () => {
const season = getCurrentSeason();
if (!season || !seasonalLists[season]) {
console.log('Using default list:', listFileName);
return listFileName;
}
console.log(`Using seasonal list for ${season}:`, seasonalLists[season]);
return seasonalLists[season];
};
// Get SponsorBlock-Data for the outro/intro segment of the trailer
const fetchSponsorBlockData = async (videoId) => {
try {
@@ -679,8 +764,9 @@ const checkBackdropAndLogo = movie => {
).catch(() => fetchRandomMovie());
};
const readCustomList = () =>
fetch(listFileName + '?' + new Date().getTime())
const readCustomList = () => {
const currentListFile = getSeasonalListFileName();
return fetch(currentListFile + '?' + new Date().getTime())
.then(response => response.ok ? response.text() : null)
.then(text => {
if (!text || !text.trim()) {
@@ -723,6 +809,7 @@ const readCustomList = () =>
console.error('Error reading List.txt. Falling back to random selection.');
return null;
});
};
const fetchRandomMovie = () => {