scotty/backends/subsonic/subsonic.go
Philipp Wolfer 117014a977
Change project license to GPLv3
Individual files, mainly the models and the HTTP clients stay under MIT
2023-11-22 08:05:23 +01:00

95 lines
2.6 KiB
Go

/*
Copyright © 2023 Philipp Wolfer <phw@uploadedlobster.com>
This file is part of Scotty.
Scotty is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later version.
Scotty is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
Scotty. If not, see <https://www.gnu.org/licenses/>.
*/
package subsonic
import (
"net/http"
"sort"
"time"
"github.com/delucks/go-subsonic"
"github.com/spf13/viper"
"go.uploadedlobster.com/scotty/models"
)
type SubsonicApiBackend struct {
client subsonic.Client
password string
}
func (b *SubsonicApiBackend) Name() string { return "subsonic" }
func (b *SubsonicApiBackend) FromConfig(config *viper.Viper) models.Backend {
b.client = subsonic.Client{
Client: &http.Client{},
BaseUrl: config.GetString("server-url"),
User: config.GetString("username"),
ClientName: "Scotty",
}
b.password = config.GetString("token")
return b
}
func (b *SubsonicApiBackend) ExportLoves(oldestTimestamp time.Time, results chan models.LovesResult, progress chan models.Progress) {
defer close(results)
defer close(progress)
err := b.client.Authenticate(b.password)
if err != nil {
results <- models.LovesResult{Error: err}
return
}
starred, err := b.client.GetStarred2(map[string]string{})
if err != nil {
results <- models.LovesResult{Error: err}
return
}
progress <- models.Progress{Elapsed: int64(len(starred.Song))}.Complete()
results <- models.LovesResult{Loves: b.filterSongs(starred.Song, oldestTimestamp)}
}
func (b *SubsonicApiBackend) filterSongs(songs []*subsonic.Child, oldestTimestamp time.Time) models.LovesList {
loves := make(models.LovesList, len(songs))
for i, song := range songs {
love := SongToLove(*song, b.client.User)
if love.Created.Unix() > oldestTimestamp.Unix() {
loves[i] = love
}
}
sort.Sort(loves)
return loves
}
func SongToLove(song subsonic.Child, username string) models.Love {
love := models.Love{
UserName: username,
Created: song.Starred,
Track: models.Track{
TrackName: song.Title,
ReleaseName: song.Album,
ArtistNames: []string{song.Artist},
TrackNumber: song.Track,
Tags: []string{song.Genre},
AdditionalInfo: map[string]any{},
Duration: time.Duration(song.Duration * int(time.Second)),
},
}
return love
}