vanseleem commited on
Commit
8024151
Β·
verified Β·
1 Parent(s): d592eec

Update index.js

Browse files
Files changed (1) hide show
  1. index.js +67 -10
index.js CHANGED
@@ -15,6 +15,7 @@ app.use((req, res, next) => {
15
  });
16
 
17
  const TMDB_KEY = '83d364331c40bfbe29858aeed82f45cc';
 
18
  const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36';
19
  const TORRENTIO_BASE = 'https://torrentio.strem.fun';
20
 
@@ -32,11 +33,12 @@ const QUALITY_RANK = {
32
  '4k': 5, '2160p': 5, 'webrip': 6, 'webdl': 6,
33
  };
34
 
35
- const PRIORITY_PROVIDERS = ['yts', 'knaben', 'torrentsdb', 'eztv', 'nyaasi', 'thepiratebay'];
36
 
37
  const ALLOWED_PROVIDERS = [
38
  'yts',
39
  'knaben',
 
40
  'thepiratesbay',
41
  'thepiratebay',
42
  'eztv',
@@ -258,6 +260,53 @@ async function scrapeYTS(imdbId) {
258
  } catch (e) { console.error('[YTS]', e.message); return []; }
259
  }
260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  async function scrapeKnaben(title, year, isSeries, season, episode) {
262
  if (!title) return [];
263
  try {
@@ -356,19 +405,21 @@ app.get('/stream/:type/:id.json', async (req, res) => {
356
  const title = meta?.title || '';
357
  const year = meta?.year || '';
358
 
359
- const [ytsR, knabenR, torrentioR] = await Promise.allSettled([
360
  isSeries ? Promise.resolve([]) : scrapeYTS(imdbId),
 
361
  scrapeKnaben(title, year, isSeries, season, episode),
362
  fetchTorrentio(type, id, title, year),
363
  ]);
364
 
365
  const yts = ytsR.status === 'fulfilled' ? (ytsR.value || []) : [];
 
366
  const knaben = knabenR.status === 'fulfilled' ? (knabenR.value || []) : [];
367
  const torrentio = torrentioR.status === 'fulfilled' ? (torrentioR.value || []) : [];
368
 
369
- const streams = processStreams([...yts, ...knaben, ...torrentio], type);
370
 
371
- console.log(`[stream] ${type}/${id} β†’ yts:${yts.length} knaben:${knaben.length} torrentio:${torrentio.length} final:${streams.length}`);
372
  res.json({ streams });
373
  });
374
 
@@ -378,8 +429,9 @@ app.get('/diag/:type/:id', async (req, res) => {
378
  const isSeries = type === 'series';
379
  const [imdbId, season = '', episode = ''] = id.split(':');
380
  const meta = await tmdbLookup(imdbId);
381
- const [ytsR, knabenR, torrentioR] = await Promise.allSettled([
382
  isSeries ? Promise.resolve([]) : scrapeYTS(imdbId),
 
383
  scrapeKnaben(meta?.title || '', meta?.year || '', isSeries, season, episode),
384
  fetchTorrentio(type, id, meta?.title || '', meta?.year || ''),
385
  ]);
@@ -387,6 +439,7 @@ app.get('/diag/:type/:id', async (req, res) => {
387
  imdbId, title: meta?.title, year: meta?.year, isSeries,
388
  tmdb: meta ? `OK: ${meta.title} (${meta.year})` : 'FAILED',
389
  yts: { count: (ytsR.value || []).length, err: ytsR.reason?.message || null },
 
390
  knaben: { count: (knabenR.value || []).length, err: knabenR.reason?.message || null },
391
  torrentio: { count: (torrentioR.value || []).length, err: torrentioR.reason?.message || null },
392
  });
@@ -497,14 +550,18 @@ app.get('/', (req, res) => {
497
  </div>
498
  </div>
499
  <div class="stats">
500
- <div class="stat"><div class="stat-val">100K+</div><div class="stat-lbl">Movies</div></div>
501
- <div class="stat"><div class="stat-val">40K+</div><div class="stat-lbl">Series</div></div>
502
- <div class="stat"><div class="stat-val">20K+</div><div class="stat-lbl">Anime</div></div>
503
  </div>
504
- <div class="made-by">Made With 🀍 By Van</div>
505
  </div>
506
  </body>
507
  </html>`);
508
  });
509
 
510
- app.listen(PORT, '0.0.0.0', () => console.log('VanStreams+ 🎬 v7.0.5 on :' + PORT));
 
 
 
 
 
15
  });
16
 
17
  const TMDB_KEY = '83d364331c40bfbe29858aeed82f45cc';
18
+ const TORBOX_KEY = process.env.TORBOX_KEY || '424b91b9-a79f-4817-96c1-d4c720b95983';
19
  const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36';
20
  const TORRENTIO_BASE = 'https://torrentio.strem.fun';
21
 
 
33
  '4k': 5, '2160p': 5, 'webrip': 6, 'webdl': 6,
34
  };
35
 
36
+ const PRIORITY_PROVIDERS = ['yts', 'knaben', 'torbox', 'torrentsdb', 'eztv', 'nyaasi', 'thepiratebay'];
37
 
38
  const ALLOWED_PROVIDERS = [
39
  'yts',
40
  'knaben',
41
+ 'torbox',
42
  'thepiratesbay',
43
  'thepiratebay',
44
  'eztv',
 
260
  } catch (e) { console.error('[YTS]', e.message); return []; }
261
  }
262
 
263
+ async function scrapeTorbox(title, year, isSeries, season, episode) {
264
+ if (!title || !TORBOX_KEY) return [];
265
+ try {
266
+ let query = title;
267
+ if (year && !isSeries) query += ' ' + year;
268
+ if (isSeries && season && episode)
269
+ query += ` S${String(season).padStart(2, '0')}E${String(episode).padStart(2, '0')}`;
270
+
271
+ const { data } = await axios.get(
272
+ `https://api.torbox.app/v1/api/search`,
273
+ {
274
+ params: { query, token: TORBOX_KEY, limit: 40 },
275
+ timeout: 14000,
276
+ headers: { 'User-Agent': UA }
277
+ }
278
+ );
279
+
280
+ if (!data?.data?.length) return [];
281
+ const streams = [];
282
+
283
+ for (const result of data.data) {
284
+ if (!result.hash) continue;
285
+
286
+ const name = result.title || result.name || '';
287
+ const sizeGB = result.size ? result.size / 1073741824 : null;
288
+ const sizeStr = sizeGB ? sizeGB.toFixed(2) + ' GB' : '';
289
+ const seeders = result.seeders || 0;
290
+ const langLine = getLangLine(name);
291
+
292
+ streams.push({
293
+ infoHash: result.hash.toLowerCase(),
294
+ name: name,
295
+ title: `β˜€οΈ ${title}${year ? ' (' + year + ')' : ''}\n🌱 ${seeders}\nπŸ’Ύ ${sizeStr}\nπŸ… Torbox${langLine ? '\nπŸ”Š ' + langLine : ''}`,
296
+ sources: [],
297
+ _quality: getQuality(name),
298
+ _seeders: seeders,
299
+ _sizeGB: sizeGB,
300
+ _source: 'torbox',
301
+ _provider: 'torbox',
302
+ });
303
+ }
304
+
305
+ console.log(`[Torbox] ${streams.length} for "${query}"`);
306
+ return streams;
307
+ } catch (e) { console.error('[Torbox]', e.message); return []; }
308
+ }
309
+
310
  async function scrapeKnaben(title, year, isSeries, season, episode) {
311
  if (!title) return [];
312
  try {
 
405
  const title = meta?.title || '';
406
  const year = meta?.year || '';
407
 
408
+ const [ytsR, torboxR, knabenR, torrentioR] = await Promise.allSettled([
409
  isSeries ? Promise.resolve([]) : scrapeYTS(imdbId),
410
+ scrapeTorbox(title, year, isSeries, season, episode),
411
  scrapeKnaben(title, year, isSeries, season, episode),
412
  fetchTorrentio(type, id, title, year),
413
  ]);
414
 
415
  const yts = ytsR.status === 'fulfilled' ? (ytsR.value || []) : [];
416
+ const torbox = torboxR.status === 'fulfilled' ? (torboxR.value || []) : [];
417
  const knaben = knabenR.status === 'fulfilled' ? (knabenR.value || []) : [];
418
  const torrentio = torrentioR.status === 'fulfilled' ? (torrentioR.value || []) : [];
419
 
420
+ const streams = processStreams([...yts, ...torbox, ...knaben, ...torrentio], type);
421
 
422
+ console.log(`[stream] ${type}/${id} β†’ yts:${yts.length} torbox:${torbox.length} knaben:${knaben.length} torrentio:${torrentio.length} final:${streams.length}`);
423
  res.json({ streams });
424
  });
425
 
 
429
  const isSeries = type === 'series';
430
  const [imdbId, season = '', episode = ''] = id.split(':');
431
  const meta = await tmdbLookup(imdbId);
432
+ const [ytsR, torboxR, knabenR, torrentioR] = await Promise.allSettled([
433
  isSeries ? Promise.resolve([]) : scrapeYTS(imdbId),
434
+ scrapeTorbox(meta?.title || '', meta?.year || '', isSeries, season, episode),
435
  scrapeKnaben(meta?.title || '', meta?.year || '', isSeries, season, episode),
436
  fetchTorrentio(type, id, meta?.title || '', meta?.year || ''),
437
  ]);
 
439
  imdbId, title: meta?.title, year: meta?.year, isSeries,
440
  tmdb: meta ? `OK: ${meta.title} (${meta.year})` : 'FAILED',
441
  yts: { count: (ytsR.value || []).length, err: ytsR.reason?.message || null },
442
+ torbox: { count: (torboxR.value || []).length, err: torboxR.reason?.message || null },
443
  knaben: { count: (knabenR.value || []).length, err: knabenR.reason?.message || null },
444
  torrentio: { count: (torrentioR.value || []).length, err: torrentioR.reason?.message || null },
445
  });
 
550
  </div>
551
  </div>
552
  <div class="stats">
553
+ <div class="stat"><div class="stat-val">100K+</div><div class="stat-lbl">Torrents</div></div>
554
+ <div class="stat"><div class="stat-val">4</div><div class="stat-lbl">Sources</div></div>
555
+ <div class="stat"><div class="stat-val">24/7</div><div class="stat-lbl">Online</div></div>
556
  </div>
557
+ <div class="made-by">Made with 🀍 by Van</div>
558
  </div>
559
  </body>
560
  </html>`);
561
  });
562
 
563
+ // ─── Server startup ────────────────────────────────────────────────
564
+ app.listen(PORT, () => {
565
+ console.log(`🎬 VanStreams+ running on port ${PORT}`);
566
+ console.log(`API Key configured: ${TORBOX_KEY ? 'YES' : 'NO'}`);
567
+ });