Add gated cover byte fetcher
This commit is contained in:
@@ -16,8 +16,8 @@ type Fetcher interface {
|
||||
Get(ctx context.Context, url string) (body string, status int, err error)
|
||||
}
|
||||
|
||||
// CoverFetcher retrieves one kagane cover through the browser-backed path.
|
||||
type CoverFetcher interface {
|
||||
// BrowserCoverFetcher retrieves one kagane cover through the browser-backed path.
|
||||
type BrowserCoverFetcher interface {
|
||||
Image(ctx context.Context, imageID string) (body []byte, contentType string, err error)
|
||||
}
|
||||
|
||||
@@ -42,9 +42,11 @@ type Poller struct {
|
||||
// cannot clear. Nil disables those sites entirely rather than falling back
|
||||
// to Fetch, which would only ever retrieve a challenge page.
|
||||
BrowserFetch Fetcher
|
||||
// CoverFetch is optional: it prefetches kagane covers without changing the
|
||||
// chapter poll's result when the browser or persistence fails.
|
||||
CoverFetch CoverFetcher
|
||||
// CoverFetch is optional; failures are logged and never affect the chapter poll.
|
||||
CoverFetch BrowserCoverFetcher
|
||||
// CoverBytesFetch is optional; it handles non-kagane sources through the same
|
||||
// failure-isolated prefetch path.
|
||||
CoverBytesFetch CoverBytesFetcher
|
||||
Now func() time.Time // injected so tests can freeze it
|
||||
Cooldown time.Duration
|
||||
BrowserCooldown time.Duration
|
||||
@@ -56,14 +58,39 @@ type Poller struct {
|
||||
var browserBackedSites = []string{"kagane", "novelfull"}
|
||||
|
||||
func (p *Poller) prefetchCover(ctx context.Context, sr store.Series) {
|
||||
if sr.Site != "kagane" || p.CoverFetch == nil {
|
||||
if sr.Cover == "" {
|
||||
return
|
||||
}
|
||||
imageID, ok := store.KaganeImageID(sr.Cover)
|
||||
if !ok {
|
||||
if sr.Site == "kagane" {
|
||||
if p.CoverFetch == nil {
|
||||
return
|
||||
}
|
||||
imageID, ok := store.KaganeImageID(sr.Cover)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
_, _, found, err := p.Store.GetKaganeCover(imageID)
|
||||
if err != nil {
|
||||
log.Printf("latest poll %q: read cover: %v", sr.Key(), err)
|
||||
return
|
||||
}
|
||||
if found {
|
||||
return
|
||||
}
|
||||
body, contentType, err := p.CoverFetch.Image(ctx, imageID)
|
||||
if err != nil {
|
||||
log.Printf("latest poll %q: fetch cover: %v", sr.Key(), err)
|
||||
return
|
||||
}
|
||||
if err := p.Store.PutKaganeCover(imageID, body, contentType); err != nil {
|
||||
log.Printf("latest poll %q: persist cover: %v", sr.Key(), err)
|
||||
}
|
||||
return
|
||||
}
|
||||
_, _, found, err := p.Store.GetKaganeCover(imageID)
|
||||
if p.CoverBytesFetch == nil {
|
||||
return
|
||||
}
|
||||
_, _, found, err := p.Store.GetCover(sr.Cover)
|
||||
if err != nil {
|
||||
log.Printf("latest poll %q: read cover: %v", sr.Key(), err)
|
||||
return
|
||||
@@ -71,12 +98,12 @@ func (p *Poller) prefetchCover(ctx context.Context, sr store.Series) {
|
||||
if found {
|
||||
return
|
||||
}
|
||||
body, contentType, err := p.CoverFetch.Image(ctx, imageID)
|
||||
body, contentType, err := p.CoverBytesFetch.Fetch(ctx, sr.Cover)
|
||||
if err != nil {
|
||||
log.Printf("latest poll %q: fetch cover: %v", sr.Key(), err)
|
||||
return
|
||||
}
|
||||
if err := p.Store.PutKaganeCover(imageID, body, contentType); err != nil {
|
||||
if err := p.Store.PutCover(sr.Cover, body, contentType); err != nil {
|
||||
log.Printf("latest poll %q: persist cover: %v", sr.Key(), err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user