91 lines
2.7 KiB
Go
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)
|
|
}
|