musicbrainz-provider #2
@@ -55,11 +55,11 @@
|
||||
- [x] run project tests - must pass before next task
|
||||
|
||||
### Task 3: Update Web UI and Handlers
|
||||
- [ ] Update `ArtistData` or similar view models to include the new filter booleans
|
||||
- [ ] Update `internal/web/handlers.go` to handle the new toggle POST requests
|
||||
- [ ] Update `internal/web/templates/artist.html` to show new toggles for Live and Remix
|
||||
- [ ] write tests for new web handlers
|
||||
- [ ] run project tests - must pass before next task
|
||||
- [x] Update `ArtistData` or similar view models to include the new filter booleans
|
||||
- [x] Update `internal/web/handlers.go` to handle the new toggle POST requests
|
||||
- [x] Update `internal/web/templates/artist.html` to show new toggles for Live and Remix
|
||||
- [x] write tests for new web handlers
|
||||
- [x] run project tests - must pass before next task
|
||||
|
||||
### Task 4: Verify and Document
|
||||
- [ ] Verify the scanner correctly suppresses "Live" and "Remix" types when toggles are enabled
|
||||
|
||||
@@ -82,6 +82,9 @@ type ArtistData struct {
|
||||
Name string
|
||||
MBID string
|
||||
IgnoreSingles bool
|
||||
IgnoreCompilations bool
|
||||
IgnoreLive bool
|
||||
IgnoreRemix bool
|
||||
LocalAlbums []LocalAlbumView
|
||||
Missing []MissingReleaseView
|
||||
UIBaseURL string
|
||||
@@ -146,11 +149,14 @@ func (s *Server) buildArtistData(ctx context.Context, id string) (*ArtistData, e
|
||||
}
|
||||
|
||||
data := &ArtistData{
|
||||
ID: settings.ID,
|
||||
Name: settings.Name,
|
||||
MBID: settings.MBID,
|
||||
IgnoreSingles: settings.IgnoreSingles,
|
||||
UIBaseURL: s.uiBaseURL,
|
||||
ID: settings.ID,
|
||||
Name: settings.Name,
|
||||
MBID: settings.MBID,
|
||||
IgnoreSingles: settings.IgnoreSingles,
|
||||
IgnoreCompilations: settings.IgnoreCompilations,
|
||||
IgnoreLive: settings.IgnoreLive,
|
||||
IgnoreRemix: settings.IgnoreRemix,
|
||||
UIBaseURL: s.uiBaseURL,
|
||||
}
|
||||
for _, a := range locals {
|
||||
data.LocalAlbums = append(data.LocalAlbums, LocalAlbumView{Title: a.Title})
|
||||
@@ -318,3 +324,99 @@ func (s *Server) toggleIgnoreSingles(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
http.Redirect(w, r, "/artist/"+id, http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// toggleIgnoreCompilations handles POST /artist/{id}/ignore-compilations which flips the
|
||||
// artist's ignore_compilations flag.
|
||||
func (s *Server) toggleIgnoreCompilations(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
if !s.sameOrigin(r) {
|
||||
http.Error(w, "forbidden: cross-origin request", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
id := r.PathValue("id")
|
||||
if id == "" || !isValidID(id) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
settings, err := database.GetArtistSettings(s.db, id)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("load artist: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if err := database.UpdateArtistSettings(s.db, id, map[string]interface{}{
|
||||
"ignore_compilations": !settings.IgnoreCompilations,
|
||||
}); err != nil {
|
||||
http.Error(w, fmt.Sprintf("update artist: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/artist/"+id, http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// toggleIgnoreLive handles POST /artist/{id}/ignore-live which flips the
|
||||
// artist's ignore_live flag.
|
||||
func (s *Server) toggleIgnoreLive(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
if !s.sameOrigin(r) {
|
||||
http.Error(w, "forbidden: cross-origin request", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
id := r.PathValue("id")
|
||||
if id == "" || !isValidID(id) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
settings, err := database.GetArtistSettings(s.db, id)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("load artist: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if err := database.UpdateArtistSettings(s.db, id, map[string]interface{}{
|
||||
"ignore_live": !settings.IgnoreLive,
|
||||
}); err != nil {
|
||||
http.Error(w, fmt.Sprintf("update artist: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/artist/"+id, http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// toggleIgnoreRemix handles POST /artist/{id}/ignore-remix which flips the
|
||||
// artist's ignore_remix flag.
|
||||
func (s *Server) toggleIgnoreRemix(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
if !s.sameOrigin(r) {
|
||||
http.Error(w, "forbidden: cross-origin request", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
id := r.PathValue("id")
|
||||
if id == "" || !isValidID(id) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
settings, err := database.GetArtistSettings(s.db, id)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("load artist: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if err := database.UpdateArtistSettings(s.db, id, map[string]interface{}{
|
||||
"ignore_remix": !settings.IgnoreRemix,
|
||||
}); err != nil {
|
||||
http.Error(w, fmt.Sprintf("update artist: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/artist/"+id, http.StatusSeeOther)
|
||||
}
|
||||
|
||||
@@ -58,6 +58,9 @@ func NewServer(cfg *config.ServerConfig, db *database.DB, uiBaseURL string, thre
|
||||
mux.HandleFunc("/artist/{id}/ignore", s.ignoreOrRestore)
|
||||
mux.HandleFunc("/artist/{id}/restore", s.ignoreOrRestore)
|
||||
mux.HandleFunc("/artist/{id}/ignore-singles", s.toggleIgnoreSingles)
|
||||
mux.HandleFunc("/artist/{id}/ignore-compilations", s.toggleIgnoreCompilations)
|
||||
mux.HandleFunc("/artist/{id}/ignore-live", s.toggleIgnoreLive)
|
||||
mux.HandleFunc("/artist/{id}/ignore-remix", s.toggleIgnoreRemix)
|
||||
mux.HandleFunc("/archive", s.handleArchive)
|
||||
s.mux = mux
|
||||
return s
|
||||
@@ -171,11 +174,11 @@ func (s *Server) sameOrigin(r *http.Request) bool {
|
||||
// ArtistSummary is the dashboard projection of a single monitored artist and
|
||||
// its missing-release count.
|
||||
type ArtistSummary struct {
|
||||
ID string
|
||||
Name string
|
||||
MBID string
|
||||
MissingCount int
|
||||
Monitored bool
|
||||
ID string
|
||||
Name string
|
||||
MBID string
|
||||
MissingCount int
|
||||
Monitored bool
|
||||
}
|
||||
|
||||
// DashboardData is the view model passed to the dashboard template.
|
||||
|
||||
@@ -30,6 +30,21 @@
|
||||
{{ if .IgnoreSingles }}<span class="sub"> (singles currently ignored)</span>{{ end }}
|
||||
</form>
|
||||
|
||||
<form class="toggle" method="POST" action="/artist/{{ .ID }}/ignore-compilations">
|
||||
<button type="submit">{{ if .IgnoreCompilations }}Enable compilations{{ else }}Ignore all compilations{{ end }}</button>
|
||||
{{ if .IgnoreCompilations }}<span class="sub"> (compilations currently ignored)</span>{{ end }}
|
||||
</form>
|
||||
|
||||
<form class="toggle" method="POST" action="/artist/{{ .ID }}/ignore-live">
|
||||
<button type="submit">{{ if .IgnoreLive }}Enable live{{ else }}Ignore all live{{ end }}</button>
|
||||
{{ if .IgnoreLive }}<span class="sub"> (live recordings currently ignored)</span>{{ end }}
|
||||
</form>
|
||||
|
||||
<form class="toggle" method="POST" action="/artist/{{ .ID }}/ignore-remix">
|
||||
<button type="submit">{{ if .IgnoreRemix }}Enable remixes{{ else }}Ignore all remixes{{ end }}</button>
|
||||
{{ if .IgnoreRemix }}<span class="sub"> (remixes currently ignored)</span>{{ end }}
|
||||
</form>
|
||||
|
||||
<h2>Local albums (Subsonic)</h2>
|
||||
{{ if .LocalAlbums }}
|
||||
<table>
|
||||
|
||||
Reference in New Issue
Block a user