待ち行列への登録と状態表示を追加(新着からの登録、/queue、DATABASE_URL)
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user