add custom listenbrainz url support and make ui "consistent"

Co-authored-by: spezifisch <spezifisch@users.noreply.github.com>
Co-authored-by: Alex McGrath <amk@amk.ie>
This commit is contained in:
sentriz
2021-01-11 23:34:55 +00:00
committed by Senan Kelly
parent 4443d7d0f5
commit a18929ad01
8 changed files with 903 additions and 870 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -5,15 +5,9 @@
</div>
<div class="block-right">
<table id="stats" class="text-right">
<tr>
<td>artists:</td> <td>{{ .ArtistCount }}</td>
</tr>
<tr>
<td>albums:</td> <td>{{ .AlbumCount }}</td>
</tr>
<tr>
<td>tracks:</td> <td>{{ .TrackCount }}</td>
</tr>
<tr><td>artists:</td> <td>{{ .ArtistCount }}</td></tr>
<tr><td>albums:</td> <td>{{ .AlbumCount }}</td></tr>
<tr><td>tracks:</td> <td>{{ .TrackCount }}</td></tr>
</table>
</div>
</div>
@@ -28,13 +22,12 @@
{{ if .CurrentLastFMAPIKey }}
<span class="text-light">current status</span>
{{ if .User.LastFMSession }}
linked
<span class="text-light">&#124;</span>
<span>linked</span><br/>
<form action="{{ path "/admin/unlink_lastfm_do" }}" method="post">
<input type="submit" value="unlink">
</form>
{{ else }}
<span class="angry">unlinked</span>
<span class="angry">unlinked</span><br/>
{{ $cbPath := path "/admin/link_lastfm_do" }}
{{ $cbURL := printf "%s%s" .RequestRoot $cbPath }}
<a href="https://www.last.fm/api/auth/?api_key={{ .CurrentLastFMAPIKey }}&cb={{ $cbURL }}">link&#8230;</a>
@@ -43,7 +36,7 @@
<p class="text-light">api key not set</p>
{{ if not .User.IsAdmin }}
<p class="text-light">please ask your admin to set it</p>
{{ end }}
{{ end }}
{{ end }}
{{ if .User.IsAdmin }}
<p><a href="{{ path "/admin/update_lastfm_api_key" }}">update api key&#8230;</a></p>
@@ -52,32 +45,26 @@
</div>
<div class="padded box">
<div class="box-title">
<i class="mdi mdi-brain"></i> ListenBrainz
<i class="mdi mdi-brain"></i> listenbrainz
</div>
<div class="box-description text-light">
<p>gonic can scrobble to <a href="https://listenbrainz.org/" target="_blank">ListenBrainz</a> and compatible sites.</p>
<p>gonic can scrobble to <a href="https://listenbrainz.org/" target="_blank">listenbrainz</a> and compatible sites</p>
</div>
<div class="text-right">
<span class="text-light">current status</span>
{{ if .User.ListenBrainzSession }}
linked
<span class="text-light">&#124;</span>
<form action="{{ path "/admin/unlink_listenbrainz_do" }}" method="post">
<input type="submit" value="unlink">
</form>
{{ else }}
<span class="angry">unlinked</span>
<form id="listenbrainz-pref-set" action="{{ path "/admin/link_listenbrainz_do" }}" method="post"></form>
<table id="listenbrainz-pref">
<tr>
<td><label for="listenbrainz-token">Token:</label></td>
<td><input form="listenbrainz-pref-set" id="listenbrainz-token" type="text" name="token" value="{{ default "" .User.ListenBrainzSession }}"></td>
</tr>
<tr>
<td colspan="2"><input form="listenbrainz-pref-set" type="submit" value="save"></td>
</tr>
</table>
{{ end }}
<span class="text-light">current status</span>
{{ if .User.ListenBrainzToken }}
<span>linked</span><br/>
<form action="{{ path "/admin/unlink_listenbrainz_do" }}" method="post">
<input type="submit" value="unlink">
</form>
{{ else }}
<span class="angry">unlinked</span>
<form class="block" action="{{ path "/admin/link_listenbrainz_do" }}" method="post">
<input type="text" name="url" placeholder="server addr" value="{{ default .DefaultListenBrainzURL .User.ListenBrainzURL }}">
<input type="text" name="token" placeholder="e199b311abd01f0d" value="{{ .User.ListenBrainzToken }}">
<input type="submit" value="update">
</form>
{{ end }}
</div>
</div>
<div class="padded box">
@@ -131,8 +118,8 @@
</colgroup>
{{ range $folder := .RecentFolders }}
<tr>
<td class="text-right text-trunc">{{ $folder.RightPath }}</td>
<td><span class="text-light" title="{{ $folder.ModifiedAt }}">{{ $folder.ModifiedAt | dateHuman }}</span></td>
<td class="text-right text-trunc">{{ $folder.RightPath }}</td>
<td><span class="text-light" title="{{ $folder.ModifiedAt }}">{{ $folder.ModifiedAt | dateHuman }}</span></td>
</tr>
{{ end }}
</table>
@@ -141,7 +128,7 @@
<p class="text-light" title="{{ .LastScanTime }}">scanned {{ .LastScanTime | dateHuman }}</p>
{{ end }}
<form action="{{ path "/admin/start_scan_inc_do" }}" method="post">
<input type="submit" title="start a incremental scan" value="scan now"><br/>
<input type="submit" title="start a incremental scan" value="scan now">
</form>
<form action="{{ path "/admin/start_scan_full_do" }}" method="post">
<input type="submit" title="start a full scan (takes longer, and shouldn&#39;t usually be necessary)" value="scan full (!)">
@@ -192,11 +179,11 @@
<table id="recent-playlists">
{{ range $i, $playlist := .Playlists }}
<tr>
<form id="recent-playlists-{{ $i }}" action="{{ printf "/admin/delete_playlist_do?id=%d" $playlist.ID | path }}" method="post"></form>
<td class="text-right">{{ $playlist.Name }}</td>
<td><span class="text-light">({{ $playlist.TrackCount }} tracks)</span></td>
<td class="no-small"><span class="text-light" title="{{ $playlist.CreatedAt }}">{{ $playlist.CreatedAt | dateHuman }}</span></td>
<td><input form="recent-playlists-{{ $i }}" type="submit" value="delete"></td>
<form id="recent-playlists-{{ $i }}" action="{{ printf "/admin/delete_playlist_do?id=%d" $playlist.ID | path }}" method="post"></form>
<td class="text-right">{{ $playlist.Name }}</td>
<td><span class="text-light">({{ $playlist.TrackCount }} tracks)</span></td>
<td class="no-small"><span class="text-light" title="{{ $playlist.CreatedAt }}">{{ $playlist.CreatedAt | dateHuman }}</span></td>
<td><input form="recent-playlists-{{ $i }}" type="submit" value="delete"></td>
</tr>
{{ end }}
</table>

View File

@@ -23,6 +23,7 @@ html {
font-family: monospace;
font-size: var(--size);
color: black;
line-height: 1;
}
body {
@@ -37,10 +38,12 @@ button,
textarea {
border-radius: 0;
box-sizing: border-box;
margin: calc(var(--size)*0.33) 0 0 0;;
border: 1px solid #ccc;
margin: 0;
padding: 0;
vertical-align: middle;
border: none;
outline: 1px solid #ccc;
height: var(--size);
vertical-align: bottom;
}
input[type] {
@@ -54,10 +57,6 @@ input[type="password"] {
width: 100%;
}
form {
display: inline;
}
form.block {
max-width: var(--width-form);
margin-left: auto;
@@ -171,8 +170,3 @@ a:hover {
.angry {
background-color: #f4433669;
}
#listenbrainz-pref {
width: 100%;
margin: calc(var(--size)*0.5) 0;
}

View File

@@ -122,6 +122,7 @@ type templateData struct {
//
CurrentLastFMAPIKey string
CurrentLastFMAPISecret string
DefaultListenBrainzURL string
SelectedUser *db.User
}

View File

@@ -11,6 +11,7 @@ import (
"go.senan.xyz/gonic/server/encode"
"go.senan.xyz/gonic/server/scanner"
"go.senan.xyz/gonic/server/scrobble/lastfm"
"go.senan.xyz/gonic/server/scrobble/listenbrainz"
)
func firstExisting(or string, strings ...string) string {
@@ -58,6 +59,7 @@ func (c *Controller) ServeHome(r *http.Request) *Response {
)
data.RequestRoot = fmt.Sprintf("%s://%s", scheme, host)
data.CurrentLastFMAPIKey = c.DB.GetSetting("lastfm_api_key")
data.DefaultListenBrainzURL = listenbrainz.BaseURL
// ** begin users box
c.DB.Find(&data.AllUsers)
// ** begin recent folders box
@@ -163,21 +165,24 @@ func (c *Controller) ServeUnlinkLastFMDo(r *http.Request) *Response {
func (c *Controller) ServeLinkListenBrainzDo(r *http.Request) *Response {
token := r.FormValue("token")
if token == "" {
url := r.FormValue("url")
if token == "" || url == "" {
return &Response{
err: "please provide a token",
code: 400,
redirect: r.Referer(),
flashW: []string{"please provide a url and token"},
}
}
user := r.Context().Value(CtxUser).(*db.User)
user.ListenBrainzSession = token
user.ListenBrainzURL = url
user.ListenBrainzToken = token
c.DB.Save(&user)
return &Response{redirect: "/admin/home"}
}
func (c *Controller) ServeUnlinkListenBrainzDo(r *http.Request) *Response {
user := r.Context().Value(CtxUser).(*db.User)
user.ListenBrainzSession = ""
user.ListenBrainzURL = ""
user.ListenBrainzToken = ""
c.DB.Save(&user)
return &Response{redirect: "/admin/home"}
}

View File

@@ -55,8 +55,9 @@ func (c *Controller) ServeScrobble(r *http.Request) *spec.Response {
optSubmission := params.GetOrBool("submission", true)
scrobbleErrs := []error{}
for _, scrobbler := range c.Scrobblers {
err = scrobbler.Scrobble(user, track, optStampMili, optSubmission)
scrobbleErrs = append(scrobbleErrs, err)
if err := scrobbler.Scrobble(user, track, optStampMili, optSubmission); err != nil {
scrobbleErrs = append(scrobbleErrs, err)
}
}
if len(scrobbleErrs) != 0 {
return spec.NewError(0, "error when submitting: %v", scrobbleErrs)

View File

@@ -134,13 +134,14 @@ func (t *Track) GenreStrings() []string {
}
type User struct {
ID int `gorm:"primary_key"`
CreatedAt time.Time
Name string `gorm:"not null; unique_index" sql:"default: null"`
Password string `gorm:"not null" sql:"default: null"`
LastFMSession string `sql:"default: null"`
ListenBrainzSession string `sql:"default: null"`
IsAdmin bool `sql:"default: null"`
ID int `gorm:"primary_key"`
CreatedAt time.Time
Name string `gorm:"not null; unique_index" sql:"default: null"`
Password string `gorm:"not null" sql:"default: null"`
LastFMSession string `sql:"default: null"`
ListenBrainzURL string `sql:"default: null"`
ListenBrainzToken string `sql:"default: null"`
IsAdmin bool `sql:"default: null"`
}
type Setting struct {

View File

@@ -12,9 +12,9 @@ import (
)
const (
baseURL = "https://api.listenbrainz.org"
submitPath = "/1/submit-listens"
BaseURL = "https://api.listenbrainz.org"
submitPath = "/1/submit-listens"
listenTypeSingle = "single"
listenTypePlayingNow = "playing_now"
)
@@ -47,7 +47,7 @@ type Scrobble struct {
type Scrobbler struct{}
func (s *Scrobbler) Scrobble(user *db.User, track *db.Track, stampMili int, submission bool) error {
if user.ListenBrainzSession == "" {
if user.ListenBrainzURL == "" || user.ListenBrainzToken == "" {
return nil
}
payload := Payload{
@@ -72,9 +72,9 @@ func (s *Scrobbler) Scrobble(user *db.User, track *db.Track, stampMili int, subm
if err := json.NewEncoder(&payloadBuf).Encode(scrobble); err != nil {
return err
}
submitURL := fmt.Sprintf("%s%s", baseURL, submitPath)
authHeader := fmt.Sprintf("Token %s", user.ListenBrainzSession)
req, _ := http.NewRequest("POST", submitURL, &payloadBuf)
submitURL := fmt.Sprintf("%s%s", user.ListenBrainzURL, submitPath)
authHeader := fmt.Sprintf("Token %s", user.ListenBrainzToken)
req, _ := http.NewRequest(http.MethodPost, submitURL, &payloadBuf)
req.Header.Add("Authorization", authHeader)
res, err := http.DefaultClient.Do(req)
if err != nil {