Spaces:
Running
Running
Upload index.html
Browse files- index.html +43 -4
index.html
CHANGED
|
@@ -1498,6 +1498,18 @@ const TRANSLATED_KEY = JM_CONFIG.TRANSLATED_KEY;
|
|
| 1498 |
// Id zake zinaanza na 'n2-' ili zisigongane na za chanzo cha zamani.
|
| 1499 |
const TRANSLATED2_BASE = JM_CONFIG.CONTENT_URL + '/functions/v1/movie-zilizotafsriwa2';
|
| 1500 |
const TR2_PREFIX = 'n2-';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1501 |
const TR_DJ_NOISE = /\b(movies?|filamu|zote|zilizotafsiriwa|zilizotafsiri|imetafsiriwa|iliyotafsiriwa|tafsiriwa|kiswahili|swahili|kwa|mpya|kali|translated|new|all|series|full)\b/gi;
|
| 1502 |
function normDj(raw) { // jina safi la DJ (bila maneno ya ziada na bila tofauti za herufi kubwa/ndogo)
|
| 1503 |
const s = String(raw || '').replace(/\(.*?\)|\[.*?\]/g, ' ').replace(TR_DJ_NOISE, ' ').replace(/[|_\-\u2013\u2014:,.]+/g, ' ').replace(/\s+/g, ' ').trim();
|
|
@@ -1512,7 +1524,7 @@ function loadTrModel() {
|
|
| 1512 |
return trModelP;
|
| 1513 |
}
|
| 1514 |
function logTrPlay(id) { // rekodi uchezaji bila kuzuia player; kitambulisho cha kifaa ni cha nasibu (hakuna jina/email)
|
| 1515 |
-
if (!id) return;
|
| 1516 |
let dev = '';
|
| 1517 |
try { dev = localStorage.getItem('jm_dev') || ''; if (!dev) { dev = (crypto.randomUUID && crypto.randomUUID()) || (Date.now() + '-' + Math.random().toString(36).slice(2)); localStorage.setItem('jm_dev', dev); } } catch (_) {}
|
| 1518 |
fetch(TRANSLATED2_BASE + '?action=play', { method: 'POST', keepalive: true,
|
|
@@ -1541,7 +1553,17 @@ function buildTranslatedSections(items, model) {
|
|
| 1541 |
if (more.length) sections.push({ title: t('tr_more'), items: more.slice(0, 40) });
|
| 1542 |
return sections;
|
| 1543 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1544 |
async function fetchTranslatedMovie(id) { // -> { ok, error?, movie } kutoka chanzo sahihi
|
|
|
|
| 1545 |
const isNew = String(id).startsWith(TR2_PREFIX);
|
| 1546 |
const url = isNew ? TRANSLATED2_BASE + '?id=' + encodeURIComponent(String(id).slice(TR2_PREFIX.length))
|
| 1547 |
: TRANSLATED_BASE + '?id=' + encodeURIComponent(id);
|
|
@@ -3795,9 +3817,26 @@ async function fetchTranslatedList() {
|
|
| 3795 |
const d = await r.json();
|
| 3796 |
return (Array.isArray(d) ? d : []).map(m => card(m, TR2_PREFIX));
|
| 3797 |
})();
|
| 3798 |
-
const
|
| 3799 |
-
|
| 3800 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3801 |
const seen = new Set(fresh.map(x => String(x.title || '').trim().toLowerCase()));
|
| 3802 |
return fresh.concat(older.filter(x => !seen.has(String(x.title || '').trim().toLowerCase())));
|
| 3803 |
}
|
|
|
|
| 1498 |
// Id zake zinaanza na 'n2-' ili zisigongane na za chanzo cha zamani.
|
| 1499 |
const TRANSLATED2_BASE = JM_CONFIG.CONTENT_URL + '/functions/v1/movie-zilizotafsriwa2';
|
| 1500 |
const TR2_PREFIX = 'n2-';
|
| 1501 |
+
// movie-public2 — Absalom Family (Season Zilizotafsiriwa). Project ile ile ya CONTENT_URL. Id zake zinaanza na 'ab-'.
|
| 1502 |
+
const ABSALOM_BASE = JM_CONFIG.CONTENT_URL + '/functions/v1/movie-public2';
|
| 1503 |
+
const AB_PREFIX = 'ab-';
|
| 1504 |
+
const AB_MAX_POSTS = 1000; // posts zisizozidi 1000 kwenye orodha
|
| 1505 |
+
// Jina la kipindi: "EP1" / "Episode 1" / "1" -> "1" (ili ionekane kama Episode 1 na download iwe na namba); vinginevyo jina kamili
|
| 1506 |
+
function abEpKey(label, used) {
|
| 1507 |
+
const m = String(label || '').match(/^\s*(?:ep|episode|ep\.)?\s*(\d+)\s*$/i);
|
| 1508 |
+
let k = m ? m[1] : (String(label || '').trim() || 'EP');
|
| 1509 |
+
if (used.has(k)) { let n = 2; while (used.has(k + ' (' + n + ')')) n++; k = k + ' (' + n + ')'; }
|
| 1510 |
+
used.add(k);
|
| 1511 |
+
return k;
|
| 1512 |
+
}
|
| 1513 |
const TR_DJ_NOISE = /\b(movies?|filamu|zote|zilizotafsiriwa|zilizotafsiri|imetafsiriwa|iliyotafsiriwa|tafsiriwa|kiswahili|swahili|kwa|mpya|kali|translated|new|all|series|full)\b/gi;
|
| 1514 |
function normDj(raw) { // jina safi la DJ (bila maneno ya ziada na bila tofauti za herufi kubwa/ndogo)
|
| 1515 |
const s = String(raw || '').replace(/\(.*?\)|\[.*?\]/g, ' ').replace(TR_DJ_NOISE, ' ').replace(/[|_\-\u2013\u2014:,.]+/g, ' ').replace(/\s+/g, ' ').trim();
|
|
|
|
| 1524 |
return trModelP;
|
| 1525 |
}
|
| 1526 |
function logTrPlay(id) { // rekodi uchezaji bila kuzuia player; kitambulisho cha kifaa ni cha nasibu (hakuna jina/email)
|
| 1527 |
+
if (!id || String(id).startsWith(AB_PREFIX)) return;
|
| 1528 |
let dev = '';
|
| 1529 |
try { dev = localStorage.getItem('jm_dev') || ''; if (!dev) { dev = (crypto.randomUUID && crypto.randomUUID()) || (Date.now() + '-' + Math.random().toString(36).slice(2)); localStorage.setItem('jm_dev', dev); } } catch (_) {}
|
| 1530 |
fetch(TRANSLATED2_BASE + '?action=play', { method: 'POST', keepalive: true,
|
|
|
|
| 1553 |
if (more.length) sections.push({ title: t('tr_more'), items: more.slice(0, 40) });
|
| 1554 |
return sections;
|
| 1555 |
}
|
| 1556 |
+
async function fetchAbsalomMovie(slug) { // -> { ok, error?, movie } ikiwa na video_urls kama series nyingine
|
| 1557 |
+
const r = await fetch(ABSALOM_BASE + '?slug=' + encodeURIComponent(slug), { headers: { apikey: SUPABASE_ANON_KEY } });
|
| 1558 |
+
const d = await r.json().catch(() => ({}));
|
| 1559 |
+
const p = (d.posts || [])[0];
|
| 1560 |
+
if (!r.ok || !d.ok || !p) return { ok: false, error: d.error || 'Haipatikani' };
|
| 1561 |
+
const used = new Set(), eps = {};
|
| 1562 |
+
(p.episodes || []).forEach(e => { if (e && e.mp4_url) eps[abEpKey(e.label, used)] = e.mp4_url; });
|
| 1563 |
+
return { ok: true, movie: { title: p.title, dj: p.dj, poster_url: p.poster, video_urls: { 'Season 1': eps } } };
|
| 1564 |
+
}
|
| 1565 |
async function fetchTranslatedMovie(id) { // -> { ok, error?, movie } kutoka chanzo sahihi
|
| 1566 |
+
if (String(id).startsWith(AB_PREFIX)) return fetchAbsalomMovie(String(id).slice(AB_PREFIX.length));
|
| 1567 |
const isNew = String(id).startsWith(TR2_PREFIX);
|
| 1568 |
const url = isNew ? TRANSLATED2_BASE + '?id=' + encodeURIComponent(String(id).slice(TR2_PREFIX.length))
|
| 1569 |
: TRANSLATED_BASE + '?id=' + encodeURIComponent(id);
|
|
|
|
| 3817 |
const d = await r.json();
|
| 3818 |
return (Array.isArray(d) ? d : []).map(m => card(m, TR2_PREFIX));
|
| 3819 |
})();
|
| 3820 |
+
const absP = (async () => { // movie-public2 (Absalom): posts zenye angalau MP4 moja, kwa kurasa 50
|
| 3821 |
+
const out = [];
|
| 3822 |
+
for (let off = 0; off < AB_MAX_POSTS; off += 50) {
|
| 3823 |
+
const r = await fetch(ABSALOM_BASE + '?limit=50&offset=' + off, { headers: { apikey: SUPABASE_ANON_KEY } });
|
| 3824 |
+
if (!r.ok) throw new Error(T('err_generic') + ' ' + r.status);
|
| 3825 |
+
const d = await r.json();
|
| 3826 |
+
if (!d.ok) throw new Error(d.error || 'Absalom imekataa ombi.');
|
| 3827 |
+
(d.posts || []).forEach(p => {
|
| 3828 |
+
if (!(p.episodes || []).some(e => e && e.mp4_url)) return;
|
| 3829 |
+
out.push(card({ id: String(p.slug || '').replace(/^absalom-/, ''), title: p.title, dj: p.dj,
|
| 3830 |
+
poster_url: p.poster, category: p.kind === 'series' ? 'series' : 'movie' }, AB_PREFIX));
|
| 3831 |
+
});
|
| 3832 |
+
if (d.done || !d.count) break;
|
| 3833 |
+
}
|
| 3834 |
+
return out;
|
| 3835 |
+
})();
|
| 3836 |
+
const [a, b, c] = await Promise.allSettled([oldP, newP, absP]);
|
| 3837 |
+
if (a.status === 'rejected' && b.status === 'rejected' && c.status === 'rejected') throw a.reason;
|
| 3838 |
+
const fresh = (b.status === 'fulfilled' ? b.value : []).concat(c.status === 'fulfilled' ? c.value : []),
|
| 3839 |
+
older = a.status === 'fulfilled' ? a.value : [];
|
| 3840 |
const seen = new Set(fresh.map(x => String(x.title || '').trim().toLowerCase()));
|
| 3841 |
return fresh.concat(older.filter(x => !seen.has(String(x.title || '').trim().toLowerCase())));
|
| 3842 |
}
|