Files

91 lines
2.7 KiB
Go

package web
import (
"errors"
"net/http"
"gitea.kazu634.com/kazu634/tver/internal/store"
)
type episodeActionView struct {
ID, Genre, Status, StatusText string
}
func statusText(status string) string {
switch status {
case "queued":
return "待機中"
case "running":
return "ダウンロード中"
case "succeeded":
return "完了"
case "failed":
return "失敗"
case "canceled":
return "取り消し"
default:
return ""
}
}
func (s *server) enqueue(w http.ResponseWriter, r *http.Request) {
genre, id, ok := episodeForm(w, r)
if !ok {
return
}
ep, found := s.cachedEpisode(genre, id)
if !found {
http.Error(w, "新着キャッシュにエピソードがありません。新着を再表示してください", http.StatusNotFound)
return
}
job, _, err := s.jobs.Enqueue(r.Context(), storeEpisode(ep), "manual")
if err != nil {
s.logger.Printf("待ち行列への登録に失敗: %v", err)
http.Error(w, "待ち行列に登録できませんでした", http.StatusInternalServerError)
return
}
s.episodeActionResponse(w, r, episodeActionView{ID: id, Genre: genre, Status: job.Status, StatusText: statusText(job.Status)})
}
func (s *server) retryEpisode(w http.ResponseWriter, r *http.Request) {
genre, id, ok := episodeForm(w, r)
if !ok {
return
}
if _, found := s.cachedEpisode(genre, id); !found {
http.Error(w, "新着キャッシュにエピソードがありません。新着を再表示してください", http.StatusNotFound)
return
}
if err := s.jobs.RetryEpisode(r.Context(), id); err != nil {
if errors.Is(err, store.ErrInvalidTransition) {
http.Error(w, "再試行できる状態ではありません", http.StatusConflict)
} else {
s.logger.Printf("ジョブの再試行に失敗: %v", err)
http.Error(w, "再試行できませんでした", http.StatusInternalServerError)
}
return
}
s.episodeActionResponse(w, r, episodeActionView{ID: id, Genre: genre, Status: "queued", StatusText: statusText("queued")})
}
func episodeForm(w http.ResponseWriter, r *http.Request) (string, string, bool) {
if err := r.ParseForm(); err != nil {
http.Error(w, "フォームを読み取れませんでした", http.StatusBadRequest)
return "", "", false
}
genre, id := r.Form.Get("genre"), r.Form.Get("episode_id")
if (genre != "drama" && genre != "variety") || id == "" {
http.Error(w, "ジャンルまたはエピソード ID が不正です", http.StatusBadRequest)
return "", "", false
}
return genre, id, true
}
func (s *server) episodeActionResponse(w http.ResponseWriter, r *http.Request, view episodeActionView) {
if r.Header.Get("HX-Request") != "true" {
http.Redirect(w, r, "/?genre="+view.Genre, http.StatusSeeOther)
return
}
s.render(w, "episode_action", view)
}