Spotnet (CONCEPT D29): - Index free.pt fully and import spots with their descriptions, categories and NZBs; a spot renames its release, since Spotnet names are more trustworthy than names derived from subjects. - Find passwords in spot descriptions too, and tell "needs a password we have" from "needs a password we don't have". Content inspection: - List the contents of 7z (.7z.001) archives, SFV sets, nicovideo uploads and other archive-like files; mark yEncBin .bin containers as encrypted. - Take real names from yEnc headers for randomly named files, and merge uploads that were split across posts. Storage (D31, D32): - Store segment lists zstd-compressed behind the FileStore accessor. - group:backfill indexes older headers at low priority and pauses when the NVMe or HDD part of the database gets too large. Grouping (D35, D36): - Lone header segments wait in staged_segments until a second segment of their file arrives, which drops the per-article junk binaries. - Counter grouping joins random-subject uploads by poster, [i/M] counter, part count and day. Search and maintenance (D33, D34): - A trigram-indexed search_text column, smaller indexes, estimated stats. - Passes that clean up nonsense names; weekly index maintenance; GC budgets per kind. - Web UI: grey out stale results while a search runs and cancel superseded requests. Count only up to 1,000 matches for the page, which made filter clicks take seconds (Newznab keeps the 10,000 cap). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
51 lines
1.7 KiB
TypeScript
51 lines
1.7 KiB
TypeScript
/*
|
|
|--------------------------------------------------------------------------
|
|
| Routes file
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| The routes file is used for defining the HTTP routes.
|
|
|
|
|
*/
|
|
|
|
import { middleware } from '#start/kernel'
|
|
import router from '@adonisjs/core/services/router'
|
|
import { controllers } from '#generated/controllers'
|
|
|
|
const ReleasesController = () => import('#controllers/releases_controller')
|
|
const NewznabController = () => import('#controllers/newznab_controller')
|
|
|
|
// Newznab API for Prowlarr / Sonarr / Radarr ("Generic Newznab", API path /api).
|
|
router.get('/api', [NewznabController, 'handle'])
|
|
|
|
// Web interface: public/index.html is served by the static middleware at "/".
|
|
router
|
|
.group(() => {
|
|
router.get('releases', [ReleasesController, 'index'])
|
|
router.get('releases/:id', [ReleasesController, 'show']).where('id', router.matchers.number())
|
|
router.get('releases/:id/nzb', [ReleasesController, 'nzb']).where('id', router.matchers.number())
|
|
router.get('releases/:id/image', [ReleasesController, 'image']).where('id', router.matchers.number())
|
|
router.get('stats', [ReleasesController, 'stats'])
|
|
})
|
|
.prefix('/api/v1')
|
|
|
|
router
|
|
.group(() => {
|
|
router
|
|
.group(() => {
|
|
router.post('signup', [controllers.NewAccount, 'store'])
|
|
router.post('login', [controllers.AccessTokens, 'store'])
|
|
})
|
|
.prefix('auth')
|
|
.as('auth')
|
|
|
|
router
|
|
.group(() => {
|
|
router.get('profile', [controllers.Profile, 'show'])
|
|
router.post('logout', [controllers.AccessTokens, 'destroy'])
|
|
})
|
|
.prefix('account')
|
|
.as('profile')
|
|
.use(middleware.auth())
|
|
})
|
|
.prefix('/api/v1')
|