From 90bfac3b0994c8cd90ec755ebee983e5ec3d0895 Mon Sep 17 00:00:00 2001 From: truewhile <62226914+truewhile@users.noreply.github.com> Date: Mon, 19 Oct 2026 22:23:06 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=81=E7=A7=BB=20TheIntroDB=20=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=88=B0=20v4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v1 已删除、v2/v3 已弃用,仅保留只读的 GET /media。本次把 base URL 切到 v4,并适配响应以 tvdb_id 为身份(tmdb_id 字段已移除)。请求仍用 tmdb_id 寻址,v4 仍接受并由服务端解析季集映射。 --- internal/service/introdb.go | 9 ++++++--- internal/service/introdb_test.go | 17 +++++++++-------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/internal/service/introdb.go b/internal/service/introdb.go index 1cfb4f4..b777105 100644 --- a/internal/service/introdb.go +++ b/internal/service/introdb.go @@ -22,8 +22,9 @@ import ( const ( // IntroDBBaseURL is the public read endpoint. Overridable on the service - // for tests and for pointing at a mirror. - IntroDBBaseURL = "https://api.theintrodb.org/v3" + // for tests and for pointing at a mirror. v1 已删除,v2/v3 冻结在只读的 + // GET /media 上并被官方标记为弃用,所以这里直接跟 v4。 + IntroDBBaseURL = "https://api.theintrodb.org/v4" // IntroDBSource tags rows that came from this provider. IntroDBSource = "theintrodb" @@ -92,8 +93,10 @@ type introDBRange struct { EndMs *int64 `json:"end_ms"` } +// introDBResponse 对应 v4 的 MediaResponse。v4 以 TVDB 为身份,响应只带 +// tvdb_id —— tmdb_id 字段已被官方移除,需要 tmdb_id 只能从请求侧自己记。 type introDBResponse struct { - TMDbID int `json:"tmdb_id"` + TVDBID int `json:"tvdb_id"` Type string `json:"type"` Intro []introDBRange `json:"intro"` Recap []introDBRange `json:"recap"` diff --git a/internal/service/introdb_test.go b/internal/service/introdb_test.go index 9333b49..e775ff4 100644 --- a/internal/service/introdb_test.go +++ b/internal/service/introdb_test.go @@ -11,11 +11,12 @@ import ( "go.uber.org/zap" ) -// 这两段响应是从 api.theintrodb.org/v3/media 实测抓下来的原文, -// 用来锁住 null 语义:start_ms: null = 从片头开始,end_ms: null = 一直到片尾。 +// 这两段响应是从 api.theintrodb.org/v4/media 实测抓下来的原文(v4 以 TVDB 为身份, +// 响应里只有 tvdb_id),用来锁住 null 语义:start_ms: null = 从片头开始, +// end_ms: null = 一直到片尾。 const ( - introDBTVPayload = `{"tmdb_id":1396,"type":"tv","season":1,"episode":1,"intro":[{"start_ms":228664,"end_ms":246143}],"credits":[{"start_ms":3431000,"end_ms":null}]}` - introDBMoviePayload = `{"tmdb_id":27205,"type":"movie","intro":[{"start_ms":null,"end_ms":38000}]}` + introDBTVPayload = `{"tvdb_id":81189,"type":"tv","season":1,"episode":1,"intro":[{"start_ms":228664,"end_ms":246143}],"credits":[{"start_ms":3431000,"end_ms":null}]}` + introDBMoviePayload = `{"tvdb_id":113,"type":"movie","intro":[{"start_ms":null,"end_ms":38000}]}` ) func TestParseIntroDBResponseResolvesNullBounds(t *testing.T) { @@ -48,7 +49,7 @@ func TestParseIntroDBResponseResolvesNullBounds(t *testing.T) { } func TestParseIntroDBResponseDropsEmptyRanges(t *testing.T) { - body := `{"tmdb_id":1,"type":"movie", + body := `{"tvdb_id":1,"type":"movie", "intro":[{"start_ms":5000,"end_ms":5000},{"start_ms":9000,"end_ms":8000},{"start_ms":1000,"end_ms":2000}], "recap":[],"credits":[],"preview":[]}` spans, err := parseIntroDBResponse([]byte(body)) @@ -62,7 +63,7 @@ func TestParseIntroDBResponseDropsEmptyRanges(t *testing.T) { } func TestParseIntroDBResponseOrdersByType(t *testing.T) { - body := `{"tmdb_id":1,"type":"tv","credits":[{"start_ms":900,"end_ms":1000}], + body := `{"tvdb_id":1,"type":"tv","credits":[{"start_ms":900,"end_ms":1000}], "intro":[{"start_ms":100,"end_ms":200}],"recap":[{"start_ms":50,"end_ms":60}]}` spans, err := parseIntroDBResponse([]byte(body)) if err != nil { @@ -82,12 +83,12 @@ func TestParseIntroDBResponseOrdersByType(t *testing.T) { func TestIntroDBMediaURLOnlyAddsSeasonEpisodeForTV(t *testing.T) { svc := NewIntroDBService(zap.NewNop()) if got, want := svc.mediaURL(1396, 1, 1), - "https://api.theintrodb.org/v3/media?tmdb_id=1396&season=1&episode=1"; got != want { + "https://api.theintrodb.org/v4/media?tmdb_id=1396&season=1&episode=1"; got != want { t.Fatalf("tv url = %q, want %q", got, want) } // 电影(season/episode 为 0)不能带季集参数,否则会被当成剧集查不到。 if got, want := svc.mediaURL(27205, 0, 0), - "https://api.theintrodb.org/v3/media?tmdb_id=27205"; got != want { + "https://api.theintrodb.org/v4/media?tmdb_id=27205"; got != want { t.Fatalf("movie url = %q, want %q", got, want) } }