feat(irc): manually re-process announces (#1419)

* fix(releases): add manual processing

* feat(irc): add re-process button to channel msg

* feat(irc): add missing client method

* feat(web): change reprocess icon placement

---------

Co-authored-by: martylukyy <35452459+martylukyy@users.noreply.github.com>
This commit is contained in:
ze0s 2024-03-19 18:23:43 +01:00 committed by GitHub
parent d9fc163655
commit be05ffba73
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 306 additions and 18 deletions

View file

@ -6,8 +6,10 @@ package http
import (
"context"
"encoding/json"
"fmt"
"net/http"
"strconv"
"strings"
"github.com/autobrr/autobrr/internal/domain"
@ -25,6 +27,7 @@ type ircService interface {
StoreChannel(ctx context.Context, networkID int64, channel *domain.IrcChannel) error
RestartNetwork(ctx context.Context, id int64) error
SendCmd(ctx context.Context, req *domain.SendIrcCmdRequest) error
ManualProcessAnnounce(ctx context.Context, req *domain.IRCManualProcessRequest) error
}
type ircHandler struct {
@ -54,6 +57,8 @@ func (h ircHandler) Routes(r chi.Router) {
r.Post("/cmd", h.sendCmd)
r.Post("/channel", h.storeChannel)
r.Get("/restart", h.restartNetwork)
r.Post("/channel/{channel}/announce/process", h.announceProcess)
})
r.HandleFunc("/events", func(w http.ResponseWriter, r *http.Request) {
@ -185,6 +190,58 @@ func (h ircHandler) sendCmd(w http.ResponseWriter, r *http.Request) {
h.encoder.NoContent(w)
}
// announceProcess manually trigger announce process
func (h ircHandler) announceProcess(w http.ResponseWriter, r *http.Request) {
var (
ctx = r.Context()
data domain.IRCManualProcessRequest
)
paramNetworkID := chi.URLParam(r, "networkID")
if paramNetworkID == "" {
h.encoder.StatusResponse(w, http.StatusBadRequest, map[string]interface{}{
"code": "BAD_REQUEST_PARAMS",
"message": "parameter networkID missing",
})
return
}
networkID, err := strconv.Atoi(paramNetworkID)
if err != nil {
h.encoder.Error(w, err)
return
}
paramChannel := chi.URLParam(r, "channel")
if paramChannel == "" {
h.encoder.StatusResponse(w, http.StatusBadRequest, map[string]interface{}{
"code": "BAD_REQUEST_PARAMS",
"message": "parameter channel missing",
})
return
}
if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
h.encoder.Error(w, err)
return
}
data.NetworkId = int64(networkID)
data.Channel = paramChannel
// we cant pass # as an url parameter so the frontend has to strip it
if !strings.HasPrefix("#", data.Channel) {
data.Channel = fmt.Sprintf("#%s", data.Channel)
}
if err := h.service.ManualProcessAnnounce(ctx, &data); err != nil {
h.encoder.Error(w, err)
return
}
h.encoder.NoContent(w)
}
func (h ircHandler) storeChannel(w http.ResponseWriter, r *http.Request) {
var (
ctx = r.Context()

View file

@ -5,6 +5,7 @@ package http
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
@ -22,6 +23,7 @@ type releaseService interface {
Stats(ctx context.Context) (*domain.ReleaseStats, error)
Delete(ctx context.Context, req *domain.DeleteReleaseRequest) error
Retry(ctx context.Context, req *domain.ReleaseActionRetryReq) error
ProcessManual(ctx context.Context, req *domain.ReleaseProcessReq) error
}
type releaseHandler struct {
@ -43,6 +45,8 @@ func (h releaseHandler) Routes(r chi.Router) {
r.Get("/indexers", h.getIndexerOptions)
r.Delete("/", h.deleteReleases)
r.Post("/process", h.retryAction)
r.Route("/{releaseId}", func(r chi.Router) {
r.Post("/actions/{actionStatusId}/retry", h.retryAction)
})
@ -215,6 +219,38 @@ func (h releaseHandler) deleteReleases(w http.ResponseWriter, r *http.Request) {
h.encoder.NoContent(w)
}
func (h releaseHandler) process(w http.ResponseWriter, r *http.Request) {
var req *domain.ReleaseProcessReq
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
h.encoder.Error(w, err)
return
}
if req.IndexerIdentifier == "" {
h.encoder.StatusResponse(w, http.StatusBadRequest, map[string]interface{}{
"code": "VALIDATION_ERROR",
"message": "field indexer_identifier empty",
})
}
if len(req.AnnounceLines) == 0 {
h.encoder.StatusResponse(w, http.StatusBadRequest, map[string]interface{}{
"code": "VALIDATION_ERROR",
"message": "field announce_lines empty",
})
}
err = h.service.ProcessManual(r.Context(), req)
if err != nil {
h.encoder.Error(w, err)
return
}
h.encoder.NoContent(w)
}
func (h releaseHandler) retryAction(w http.ResponseWriter, r *http.Request) {
var (
req *domain.ReleaseActionRetryReq
@ -223,7 +259,10 @@ func (h releaseHandler) retryAction(w http.ResponseWriter, r *http.Request) {
releaseIdParam := chi.URLParam(r, "releaseId")
if releaseIdParam == "" {
h.encoder.StatusError(w, http.StatusBadRequest, err)
h.encoder.StatusResponse(w, http.StatusBadRequest, map[string]interface{}{
"code": "BAD_REQUEST_PARAMS",
"message": "parameter releaseId missing",
})
return
}
@ -235,7 +274,10 @@ func (h releaseHandler) retryAction(w http.ResponseWriter, r *http.Request) {
actionStatusIdParam := chi.URLParam(r, "actionStatusId")
if actionStatusIdParam == "" {
h.encoder.StatusError(w, http.StatusBadRequest, err)
h.encoder.StatusResponse(w, http.StatusBadRequest, map[string]interface{}{
"code": "BAD_REQUEST_PARAMS",
"message": "parameter actionStatusId missing",
})
return
}

View file

@ -94,7 +94,7 @@ func (s Server) tryToServe(addr, protocol string) error {
return err
}
s.log.Info().Msgf("Starting server %s. Listening on %s", protocol, listener.Addr().String())
s.log.Info().Msgf("Starting API %s server. Listening on %s", protocol, listener.Addr().String())
server := http.Server{
Handler: s.Handler(),