登録番組の定期確認を追加(24 時間ごと、予告の除外、確認エラーの記録)
This commit is contained in:
@@ -14,8 +14,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
previewMaxSeconds = 180
|
||||
newerCacheTTL = 10 * time.Minute
|
||||
newerCacheTTL = 10 * time.Minute
|
||||
)
|
||||
|
||||
var platformTokenPattern = regexp.MustCompile(`(?i)(platform_token=)[^&\s]+`)
|
||||
@@ -137,7 +136,7 @@ func (s *server) newerView(ctx context.Context, options newerOptions) newerView
|
||||
}
|
||||
visible := make([]tver.Episode, 0, len(episodes))
|
||||
for _, episode := range episodes {
|
||||
if options.hidePreviews && episode.Duration <= previewMaxSeconds {
|
||||
if options.hidePreviews && episode.Duration <= tver.PreviewMaxSeconds {
|
||||
continue
|
||||
}
|
||||
visible = append(visible, episode)
|
||||
|
||||
@@ -15,6 +15,7 @@ type subscriptionActionView struct {
|
||||
|
||||
type subscriptionView struct {
|
||||
ID, Title, CreatedAtText, LastCheckedText string
|
||||
CheckErrorAtText, CheckErrorText string
|
||||
Enabled bool
|
||||
Jobs int64
|
||||
}
|
||||
@@ -136,6 +137,10 @@ func (s *server) loadSubscriptions(ctx context.Context) (subscriptionsView, erro
|
||||
if sub.LastCheckedAt != nil {
|
||||
item.LastCheckedText = sub.LastCheckedAt.In(s.zone).Format("2006-01-02 15:04 MST")
|
||||
}
|
||||
if sub.LastCheckErrorAt != nil && sub.LastCheckError != nil {
|
||||
item.CheckErrorAtText = sub.LastCheckErrorAt.In(s.zone).Format("2006-01-02 15:04 MST")
|
||||
item.CheckErrorText = *sub.LastCheckError
|
||||
}
|
||||
view.Items = append(view.Items, item)
|
||||
}
|
||||
return view, nil
|
||||
|
||||
@@ -159,9 +159,12 @@ func TestSubscriptionMutationsWithoutHtmxRedirect(t *testing.T) {
|
||||
|
||||
func TestSubscriptionsPagePauseResumeDeleteAndEscaping(t *testing.T) {
|
||||
checked := time.Date(2026, 10, 4, 2, 30, 0, 0, time.UTC)
|
||||
failedAt := time.Date(2026, 10, 4, 3, 45, 0, 0, time.UTC)
|
||||
checkError := `<script>alert("error")</script> token=[REDACTED]`
|
||||
jobs := &fakeJobStore{subscriptions: map[string]store.Subscription{
|
||||
"sr1": {SeriesID: "sr1", SeriesTitle: `<script>alert(1)</script>`, Enabled: true,
|
||||
CreatedAt: time.Date(2026, 10, 3, 0, 0, 0, 0, time.UTC), LastCheckedAt: &checked, JobCount: 3},
|
||||
CreatedAt: time.Date(2026, 10, 3, 0, 0, 0, 0, time.UTC), LastCheckedAt: &checked,
|
||||
LastCheckErrorAt: &failedAt, LastCheckError: &checkError, JobCount: 3},
|
||||
"sr2": {SeriesID: "sr2", SeriesTitle: "別番組", Enabled: false, JobCount: 0},
|
||||
}}
|
||||
handler := newTestHandlerWithStore(&fakeFetcher{}, jobs, nil)
|
||||
@@ -170,13 +173,13 @@ func TestSubscriptionsPagePauseResumeDeleteAndEscaping(t *testing.T) {
|
||||
t.Fatalf("登録番組ページ: %d", page.Code)
|
||||
}
|
||||
body := page.Body.String()
|
||||
for _, want := range []string{"<script>", "登録日時: 2026-10-03 09:00 JST", "最終確認: 2026-10-04 11:30 JST", "最終確認: 未確認", "関連ジョブ: 3件", "有効", "一時停止", `hx-confirm="番組の登録を解除しますか?"`} {
|
||||
for _, want := range []string{"<script>", "登録日時: 2026-10-03 09:00 JST", "最終確認: 2026-10-04 11:30 JST", "最終確認: 未確認", "最後の確認エラー(2026-10-04 12:45 JST)", `<script>alert("error")</script> token=[REDACTED]`, "関連ジョブ: 3件", "有効", "一時停止", `hx-confirm="番組の登録を解除しますか?"`} {
|
||||
if !strings.Contains(body, want) {
|
||||
t.Errorf("登録番組の情報 %q がない", want)
|
||||
}
|
||||
}
|
||||
if strings.Contains(body, `<script>alert(1)</script>`) {
|
||||
t.Fatal("番組名がエスケープされていない")
|
||||
if strings.Contains(body, `<script>`) {
|
||||
t.Fatal("番組名または確認エラーがエスケープされていない")
|
||||
}
|
||||
paused := postForm(handler, "/subscriptions/sr1/pause", nil)
|
||||
if paused.Code != http.StatusOK || jobs.subscriptions["sr1"].Enabled || !strings.Contains(paused.Body.String(), `action="/subscriptions/sr1/resume"`) || strings.Contains(paused.Body.String(), "<html") {
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
<article class="subscription-item">
|
||||
<h2>{{.Title}}</h2>
|
||||
<p>登録日時: {{.CreatedAtText}}/最終確認: {{.LastCheckedText}}/状態: {{if .Enabled}}有効{{else}}一時停止{{end}}/関連ジョブ: {{.Jobs}}件</p>
|
||||
{{if .CheckErrorText}}
|
||||
<details class="error"><summary>最後の確認エラー({{.CheckErrorAtText}})</summary><p>{{.CheckErrorText}}</p></details>
|
||||
{{end}}
|
||||
{{if .Enabled}}
|
||||
<form action="/subscriptions/{{.ID}}/pause" method="post" hx-post="/subscriptions/{{.ID}}/pause" hx-target="#subscriptions-list" hx-swap="outerHTML"><button type="submit">一時停止</button></form>
|
||||
{{else}}
|
||||
|
||||
Reference in New Issue
Block a user