Add new providers for streaming services and utility functions

- Implement StreamFlix provider for fetching movie and episode streams.
- Add VaPlayer provider to retrieve streaming URLs for movies and TV shows.
- Introduce ZXCStreams provider for accessing various streaming links.
- Create utility functions for fetching episode counts from Cinemeta.
- Develop a title matching system for improved search results.
- Implement TMDB title to IMDB ID resolution for better integration with TMDB API.
This commit is contained in:
Inside4ndroid
2026-08-19 23:35:13 +01:00
parent 01f06f807e
commit 2c9a2cabbf
30 changed files with 2791 additions and 516 deletions
+7
View File
@@ -48,6 +48,13 @@
</div>
<div class="status-block">
<h2>Providers</h2>
<div class="field" style="margin-bottom:.75rem;">
<label>Provider check TMDB ID<p class="hint">Title used by "Run Provider Functional Checks" (e.g. 278 = Shawshank Redemption).</p></label>
<div style="display:flex; align-items:center; gap:.5rem;">
<input type="text" id="providerCheckTmdbId" placeholder="278" style="width:7rem;" />
<button id="saveProviderCheckTmdbBtn" type="button">Save</button>
</div>
</div>
<button style="margin-bottom: 1rem;" id="runProviderChecksBtn" type="button">Run Provider Functional Checks</button>
<span style="margin-left: .5rem; margin-bottom: 1rem;" id="providerCheckSummary" class="hint"></span>
<div id="statusProvidersEnhanced" class="providers-table" aria-live="polite"></div>
+20 -2
View File
@@ -337,7 +337,8 @@ async function clearAll(){
enablePStreamApi: true,
disableUrlValidation: false,
disable4khdhubUrlValidation: false,
showboxCacheDir: null
showboxCacheDir: null,
providerCheckTmdbId: null
};
try {
const r = await fetch('/api/config',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(payload)});
@@ -411,6 +412,8 @@ async function loadServerStatus(){
const j = await r.json();
if(!j.success) throw new Error('Status error');
metricsEl.textContent = JSON.stringify(j.metrics, null, 2);
const checkTmdbEl = document.getElementById('providerCheckTmdbId');
if(checkTmdbEl) checkTmdbEl.value = j.providerCheckTmdbId || '278';
if(endpointsEl) endpointsEl.textContent = (j.endpoints||[]).join('\n');
if(provEnhanced){
provEnhanced.innerHTML = '';
@@ -438,7 +441,8 @@ async function loadServerStatus(){
}
}
async function runProviderFunctionalChecks(){
const targetTmdb = '550'; // TMDB ID provided
const checkTmdbEl = document.getElementById('providerCheckTmdbId');
const targetTmdb = (checkTmdbEl && checkTmdbEl.value.trim()) || '278'; // TMDB ID (editable on status page)
const provEnhanced = document.getElementById('statusProvidersEnhanced');
const summary = document.getElementById('providerCheckSummary');
if(!provEnhanced) return;
@@ -478,6 +482,18 @@ async function runProviderFunctionalChecks(){
}
summary.textContent = `Checks complete: ${passed}/${rows.length} passed`;
}
async function saveProviderCheckTmdbId(){
const input = document.getElementById('providerCheckTmdbId');
const val = (input ? input.value : '').trim();
if(!val){ setStatus('Enter a TMDB ID to save', true); return; }
if(!/^\d+$/.test(val)){ setStatus('TMDB ID must be numeric', true); return; }
try {
const r = await fetch('/api/config',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({ providerCheckTmdbId: val })});
const js = await r.json();
if(!js.success) throw new Error(js.error||'Save failed');
setStatus('Provider check TMDB ID saved: '+val);
} catch(e){ setStatus(e.message, true); }
}
document.addEventListener('DOMContentLoaded', ()=> {
initTheme();
attachCoreListeners();
@@ -533,6 +549,8 @@ document.addEventListener('DOMContentLoaded', ()=> {
if(rsb) rsb.addEventListener('click', loadServerStatus);
const rpc = document.getElementById('runProviderChecksBtn');
if(rpc) rpc.addEventListener('click', runProviderFunctionalChecks);
const spc = document.getElementById('saveProviderCheckTmdbBtn');
if(spc) spc.addEventListener('click', saveProviderCheckTmdbId);
});
function toggleSidebar(force){
const sb = document.getElementById('sidebar');