All checks were successful
Release / Scraper / Test (push) Successful in 10s
Release / UI / Build (push) Successful in 26s
Release / v2 / Build ui-v2 (push) Successful in 17s
Release / Scraper / Docker (push) Successful in 47s
Release / UI / Docker (push) Successful in 56s
CI / Scraper / Lint (pull_request) Successful in 7s
CI / Scraper / Test (pull_request) Successful in 8s
CI / UI / Build (pull_request) Successful in 16s
CI / Scraper / Docker Push (pull_request) Has been skipped
CI / UI / Docker Push (pull_request) Has been skipped
Release / v2 / Docker / ui-v2 (push) Successful in 56s
Release / v2 / Test backend (push) Successful in 4m35s
iOS CI / Build (pull_request) Successful in 4m28s
Release / v2 / Docker / backend (push) Successful in 1m29s
Release / v2 / Docker / runner (push) Successful in 1m39s
iOS CI / Test (pull_request) Successful in 9m51s
- backend/: Go API server and runner binaries with PocketBase + MinIO storage - ui-v2/: SvelteKit frontend rewrite - docker-compose-new.yml: compose file for the v2 stack - .gitea/workflows/release-v2.yaml: CI/CD for backend, runner, and ui-v2 Docker Hub images - scripts/pb-init.sh: migrate from wget to curl, add superuser bootstrap for fresh installs - .env.example: document DOCKER_BUILDKIT=1 for Colima users
59 lines
1.8 KiB
Go
59 lines
1.8 KiB
Go
// Package scraper defines the NovelScraper interface and its sub-interfaces.
|
|
// Domain types live in internal/domain — this package only defines the scraping
|
|
// contract so that novelfire and any future scrapers can be swapped freely.
|
|
package scraper
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/libnovel/backend/internal/domain"
|
|
)
|
|
|
|
// CatalogueProvider can enumerate every novel available on a source site.
|
|
type CatalogueProvider interface {
|
|
ScrapeCatalogue(ctx context.Context) (<-chan domain.CatalogueEntry, <-chan error)
|
|
}
|
|
|
|
// MetadataProvider can extract structured book metadata from a novel's landing page.
|
|
type MetadataProvider interface {
|
|
ScrapeMetadata(ctx context.Context, bookURL string) (domain.BookMeta, error)
|
|
}
|
|
|
|
// ChapterListProvider can enumerate all chapters of a book.
|
|
type ChapterListProvider interface {
|
|
ScrapeChapterList(ctx context.Context, bookURL string) ([]domain.ChapterRef, error)
|
|
}
|
|
|
|
// ChapterTextProvider can extract the readable text from a single chapter page.
|
|
type ChapterTextProvider interface {
|
|
ScrapeChapterText(ctx context.Context, ref domain.ChapterRef) (domain.Chapter, error)
|
|
}
|
|
|
|
// RankingProvider can enumerate novels from a ranking page.
|
|
type RankingProvider interface {
|
|
// ScrapeRanking pages through up to maxPages ranking pages.
|
|
// maxPages <= 0 means all pages.
|
|
ScrapeRanking(ctx context.Context, maxPages int) (<-chan domain.BookMeta, <-chan error)
|
|
}
|
|
|
|
// NovelScraper is the full interface a concrete novel source must implement.
|
|
type NovelScraper interface {
|
|
CatalogueProvider
|
|
MetadataProvider
|
|
ChapterListProvider
|
|
ChapterTextProvider
|
|
RankingProvider
|
|
|
|
// SourceName returns the human-readable name of this scraper, e.g. "novelfire.net".
|
|
SourceName() string
|
|
}
|
|
|
|
// Selector describes how to locate an element in an HTML document.
|
|
type Selector struct {
|
|
Tag string
|
|
Class string
|
|
ID string
|
|
Attr string
|
|
Multiple bool
|
|
}
|