# Pull Request Template
## Branch
- [x] I branched off beta (not master) to develop this feature/fix
## Description
Adds optional GitHub Personal Access Token (PAT) authentication to avoid
API rate limiting when fetching releases. The token is resolved from
three sources in priority order:
1. App settings (`GitHubToken`)
2. `GITHUB_TOKEN` environment variable
3. GitHub CLI (`gh auth token`)
Also improves the rate limit error message with hints on how to
configure a PAT, and adds trace logging so users can see which token
source was used in the debug log.
Related issues (all closed, this PR provides a proper long-term fix via
authenticated requests):
- Relates to #287 — Custom WGT option missing when GitHub rate limit is
reached
- Relates to #235 — Initialization failed due to rate limiting
- Relates to #236 — Catch rate limit exception during initialization
- Relates to #170 — Fix Rate Limit
---
## Type of Change
- [ ] Bug fix (non-breaking change)
- [x] New feature (non-breaking change)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
- [ ] Other (please describe):
---
## Checklist
- [x] My code follows the existing project structure and style
- [x] I have tested my changes manually
- [ ] I have added necessary documentation (if applicable)
- [x] I have verified that the installer still works with the underlying
CLI
---
## Additional Notes
- Token is only attached to requests targeting `api.github.com`,
`raw.githubusercontent.com`, and `github.com`
- When no token is configured, the app continues to work with
unauthenticated requests (existing behavior)
- Debug logs now show `[GitHubAuth]` entries indicating which token
source was used
Extracts the inline DDG language map from FixYouTube.cs into a dedicated TrailerLanguageMap.cs file
and expands coverage from 22 languages to all 93 Jellyfin-supported locales.
## Changes
- New file: TrailerLanguageMap.cs — static class with all Jellyfin language codes mapped to
DDG search keywords (English name + native name per language)
- FixYouTube.cs: inline langMap replaced with __LANG_MAP__ placeholder, injected via .Replace()
from TrailerLanguageMap.JsObject at build time
## Why
Previously, if a user had a language not in the 22-entry inline map (e.g., Hindi, Bengali, Georgian,
Kazakh, etc.), the DDG search would fall back to an empty string — searching just "{title} Trailer
site:youtube.com" with no language qualifier. This made language matching impossible for those users.
Now every Jellyfin-supported language resolves to proper search keywords. For example:
- hi -> "Hindi हिन्दी"
- ka -> "Georgian ქართული"
- bn -> "Bengali বাংলা"
- kk -> "Kazakh Қазақша"
Fixes a long-standing Jellyfin upstream bug (jellyfin/jellyfin#12817) where movies configured with
non-English metadata languages (German, Spanish, French, etc.) show no trailer button because TMDB
returns empty video data for non-English language queries.
## Problem
When Jellyfin fetches metadata with e.g. language=de, TMDB returns 0 trailers even though English
trailers exist in their database. Jellyfin makes no fallback to English. The issue was closed upstream
as "not planned" — unfixed for 2-3 years, affecting every non-English Jellyfin user.
## Solution
Client-side trailer fallback system built into the existing YouTube fix (V16 -> V17). No Jellyfin
server changes required.
When a movie detail page has no trailer button:
1. TMDB: search for trailer in user's language (via include_video_language parameter)
2. DuckDuckGo Lite: search "{title} Trailer {language} site:youtube.com", match by title
3. TMDB: English trailer (cached from step 1, no extra API call)
4. DuckDuckGo Lite: English fallback (cached from step 2, no extra API call)
Max 2 external HTTP requests (1x TMDB + 1x DDG). Steps 3+4 use cached results.
## Why DuckDuckGo Lite instead of Google/YouTube search
Google and YouTube aggressively block automated requests with CAPTCHAs, rate limiting, and bot
detection. DuckDuckGo Lite (lite.duckduckgo.com) returns plain HTML with no JavaScript, no API key
required, no CAPTCHAs, and no bot blocking. DDG Lite has been stable for years with minimal changes
to its HTML structure, making it a reliable fallback for trailer discovery.
## Technical details
- Language detected from Jellyfin user settings (document.documentElement.lang), not TV system language
- TMDB API key extracted at runtime from Jellyfin server plugin configuration (GET /Plugins -> GET
/Plugins/{id}/Configuration), falls back to Jellyfin's default key from TmdbUtils.cs
- DDG results parsed with title extraction: language-matched results prioritized, non-matched results
cached as English fallback
- Trailer button injected as native Jellyfin UI element (same CSS classes, Material Icons)
- Fullscreen overlay player reuses existing player.html bridge
- Closable via Tizen back button, Escape, Backspace, or video end
- httpsGet helper with 8s timeout and double-callback guard
- 22 non-English languages supported in DDG language map
## Fallback flow
```
Movie detail page loaded
|
+-- Trailer button exists? -> Yes -> normal existing fix (CustomPlayer)
|
+-- No -> Service: /trailer?tmdbId=X&lang={Jellyfin language}&tmdbKey={runtime key}
|
+-- 1. TMDB: trailer in user's language?
| -> Found -> play with CustomPlayer
|
+-- 2. DDG Lite: "{title} Trailer {language} site:youtube.com"
| -> Language matched in title? -> play with CustomPlayer
|
+-- 3. TMDB: English trailer (cached from step 1, no extra call)
| -> Found -> play with CustomPlayer
|
+-- 4. DDG Lite: English fallback (cached from step 2, no extra call)
| -> Found -> play with CustomPlayer
|
+-- Nothing found -> no trailer available
```
# Pull Request Template
## Branch
- [ ] I branched off beta (not master) to develop this feature/fix
## Description
Please include a summary of the change and which issue is fixed. Also
include relevant motivation and context.
Fixes # (issue number, if applicable)
---
## Type of Change
- [ ] Bug fix (non-breaking change)
- [ ] New feature (non-breaking change)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
- [ ] Other (please describe):
---
## Checklist
- [ ] My code follows the existing project structure and style
- [ ] I have tested my changes manually
- [ ] I have added necessary documentation (if applicable)
- [ ] I have verified that the installer still works with the underlying
CLI
---
## Additional Notes
Any other information that reviewers should know, including limitations,
concerns, or context about the change.
# Pull Request Template
## Branch
- [x] I branched off beta (not master) to develop this feature/fix
## Description
This includes LiteFin as a new package.
---
## Type of Change
- [ ] Bug fix (non-breaking change)
- [x] New feature (non-breaking change)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [x] Documentation update
- [ ] Other (please describe):
---
## Checklist
- [x] My code follows the existing project structure and style
- [x] I have tested my changes manually
- [x] I have added necessary documentation (if applicable)
- [x] I have verified that the installer still works with the underlying
CLI
---