Harden auth, add AI smart-search and post-download organization #11

Merged
wmantly merged 5 commits from llm into master 2026-07-19 04:26:53 +00:00
2 changed files with 17 additions and 2 deletions
Showing only changes of commit 2046e5080b - Show all commits
+16 -1
View File
@@ -100,9 +100,16 @@ async function tpbSearch(title){
return parseTPBHtml(await res.text());
}
// Low-quality source tags we never want to recommend( token match to avoid false hits
// like "GHOSTS" matching "TS").
const JUNK = new Set(['cam', 'hdcam', 'camrip', 'ts', 'hdts', 'telesync', 'tc', 'telecine', 'scr', 'screener', 'dvdscr', 'workprint']);
function isJunk(name){
return String(name).toLowerCase().split(/[.\s_\-\[\]()]+/).some(tok => JUNK.has(tok));
}
// Deterministic pre-filter before the torrents ever reach the LLM.
function prefilter(torrents, imdbId){
let out = torrents.filter(t => videoKind(t.category) && Number(t.seeders) > 0);
let out = torrents.filter(t => videoKind(t.category) && Number(t.seeders) > 0 && !isJunk(t.name));
// If we can positively identify the title by IMDB id, trust it and drop the rest.
if(imdbId){
@@ -244,6 +251,13 @@ async function findReleases(tmdbId, mediaType){
let torrents = await tpbSearch(meta.title);
let candidates = prefilter(torrents, meta.imdbId);
// For movies, require the confirmed release year in the name. TPB search is fuzzy
// (a "Toy Story 5" query returns Toy Story 4/3/…), and without this the fallback can
// cross to the wrong movie. If nothing matches, we genuinely have no good copy yet.
if(mediaType !== 'tv' && meta.year){
candidates = candidates.filter(t => t.name.includes(meta.year));
}
if(!candidates.length){
return { title: meta.title, year: meta.year, options: [] };
}
@@ -345,4 +359,5 @@ module.exports = {
tpbSearch,
parseTPBHtml,
sizeToBytes,
isJunk,
};
+1 -1
View File
@@ -396,7 +396,7 @@
// Step 3: render the release cards; a tap feeds the existing add dialog.
function tbpRenderReleases(data){
if(!data.options.length){ tbpSearchBody('<p>No good torrents found for '+ tbpEsc(data.title) +'.</p>'); return; }
if(!data.options.length){ tbpSearchBody('<p>No good-quality copy of <b>'+ tbpEsc(data.title) +'</b> found — it may not be released yet, or only low-quality (CAM) copies exist.</p>'); return; }
var header = '<h3>'+ tbpEsc(data.title +' ('+ (data.year || '?') +')') +'</h3>';
if(data.library && data.library.owned) header += '<p style="color:#2a2">✓ Already in your library ('+ tbpEsc(data.library.quality) +') — only upgrades are offered.</p>';
tbpSearchBody(header);