68 lines
1.8 KiB
Go
68 lines
1.8 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type huangdouDetailEntry struct {
|
|
row map[string]any
|
|
expiresAt time.Time
|
|
}
|
|
|
|
type huangdouDetailCall struct {
|
|
done chan struct{}
|
|
row map[string]any
|
|
err error
|
|
}
|
|
|
|
func (d *Downloader) huangdouDetail(ctx context.Context, id string) (map[string]any, error) {
|
|
if !rankingSourceID.MatchString(id) {
|
|
return nil, errors.New("无效的黄豆剧集 ID")
|
|
}
|
|
d.providerMu.Lock()
|
|
if cached, found := d.huangdouDetails[id]; found && time.Now().Before(cached.expiresAt) {
|
|
d.providerMu.Unlock()
|
|
return cached.row, nil
|
|
}
|
|
if pending := d.huangdouDetailPending[id]; pending != nil {
|
|
d.providerMu.Unlock()
|
|
select {
|
|
case <-ctx.Done():
|
|
return nil, ctx.Err()
|
|
case <-pending.done:
|
|
if (errors.Is(pending.err, context.Canceled) || errors.Is(pending.err, context.DeadlineExceeded)) && ctx.Err() == nil {
|
|
return d.huangdouDetail(ctx, id)
|
|
}
|
|
return pending.row, pending.err
|
|
}
|
|
}
|
|
if d.huangdouDetailPending == nil {
|
|
d.huangdouDetailPending = make(map[string]*huangdouDetailCall)
|
|
}
|
|
call := &huangdouDetailCall{done: make(chan struct{})}
|
|
d.huangdouDetailPending[id] = call
|
|
d.providerMu.Unlock()
|
|
var decoded any
|
|
err := newHuangdouAPIClient(d).call(ctx, "/drama/detail", map[string]any{"id": id}, &decoded)
|
|
row := huangdouDataMap(decoded)
|
|
if err == nil && strings.TrimPrefix(mapString(row, "id", "drama_id"), "rp_") != id {
|
|
row = nil
|
|
err = errors.New("黄豆详情返回了其他剧集")
|
|
}
|
|
d.providerMu.Lock()
|
|
if err == nil {
|
|
if d.huangdouDetails == nil || len(d.huangdouDetails) >= 128 {
|
|
d.huangdouDetails = make(map[string]huangdouDetailEntry)
|
|
}
|
|
d.huangdouDetails[id] = huangdouDetailEntry{row: row, expiresAt: time.Now().Add(dramaRefreshRetryDelay)}
|
|
}
|
|
call.row, call.err = row, err
|
|
delete(d.huangdouDetailPending, id)
|
|
close(call.done)
|
|
d.providerMu.Unlock()
|
|
return row, err
|
|
}
|