Files
usenet-indexer/lib/newznab/categories.ts
T
Daan MeijerandClaude Opus 5.5 8e52bff213 Rebuild: the catalog API and Newznab, from voyager 1
- /api (Newznab: caps, search, tvsearch, movie, music, book, get) for
  Prowlarr, Sonarr and Radarr: voyager 1's controller and XML on the new
  catalog; readable releases not known to miss files; NEWZNAB_API_KEY.
- /api/v1/releases (q, cat, readable, complete, source, poster, size,
  sort, paging), /api/v1/releases/:id with its files (decoded from the
  chunks; NzbService.files, shared with the NZB), /api/v1/stats
  (estimates, plus history and tail progress), /health. Open, as voyager
  1's catalog; the web interface uses it.
- release_category(name): voyager 1's categorizer without the archive
  contents, a generated column with a (category, posted_at) index.
- @adonisjs/static for the web interface (next).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:45:47 +02:00

41 lines
1.6 KiB
TypeScript

/** Newznab categories this indexer assigns (release_category() in SQL, migration …1200). */
export const CATEGORIES: { id: number; name: string; subcats: { id: number; name: string }[] }[] = [
{ id: 2000, name: 'Movies', subcats: [{ id: 2030, name: 'SD' }, { id: 2040, name: 'HD' }, { id: 2045, name: 'UHD' }] },
{ id: 3000, name: 'Audio', subcats: [{ id: 3010, name: 'MP3' }, { id: 3040, name: 'Lossless' }] },
{ id: 4000, name: 'PC', subcats: [] },
{ id: 5000, name: 'TV', subcats: [{ id: 5030, name: 'SD' }, { id: 5040, name: 'HD' }, { id: 5045, name: 'UHD' }] },
{ id: 7000, name: 'Books', subcats: [{ id: 7020, name: 'Ebook' }] },
{ id: 8000, name: 'Other', subcats: [{ id: 8010, name: 'Misc' }] },
]
/** Parent category of a (sub)category, e.g. 5040 → 5000. */
export function parentCategory(id: number): number {
return Math.floor(id / 1000) * 1000
}
/** "TV > HD" style label. */
export function categoryLabel(id: number): string {
const parent = CATEGORIES.find((c) => c.id === parentCategory(id))
if (!parent) return 'Other'
const sub = parent.subcats.find((s) => s.id === id)
return sub ? `${parent.name} > ${sub.name}` : parent.name
}
/**
* Expands requested categories (`cat=5000,2040`) to the concrete ones to
* match: a parent includes all of its subcategories.
*/
export function expandCategories(requested: number[]): number[] {
const result = new Set<number>()
for (const id of requested) {
const parent = CATEGORIES.find((c) => c.id === id)
if (parent) {
result.add(parent.id)
for (const sub of parent.subcats) result.add(sub.id)
} else {
result.add(id)
}
}
return [...result]
}