Implemented service edit command

This commit is contained in:
Philipp Wolfer 2023-12-08 08:38:17 +01:00
parent c6c0723e27
commit 58a47a43e7
No known key found for this signature in database
GPG key ID: 8FDF744D4919943B
15 changed files with 213 additions and 57 deletions

View file

@ -36,8 +36,8 @@ type DeezerApiBackend struct {
func (b *DeezerApiBackend) Name() string { return "deezer" }
func (b *DeezerApiBackend) Options() *[]models.BackendOption {
return &[]models.BackendOption{{
func (b *DeezerApiBackend) Options() []models.BackendOption {
return []models.BackendOption{{
Name: "client-id",
Label: "Client ID",
Type: models.String,

View file

@ -25,7 +25,7 @@ type DumpBackend struct{}
func (b *DumpBackend) Name() string { return "dump" }
func (b *DumpBackend) Options() *[]models.BackendOption { return nil }
func (b *DumpBackend) Options() []models.BackendOption { return nil }
func (b *DumpBackend) FromConfig(config *config.ServiceConfig) models.Backend {
return b

View file

@ -33,8 +33,8 @@ type FunkwhaleApiBackend struct {
func (b *FunkwhaleApiBackend) Name() string { return "funkwhale" }
func (b *FunkwhaleApiBackend) Options() *[]models.BackendOption {
return &[]models.BackendOption{{
func (b *FunkwhaleApiBackend) Options() []models.BackendOption {
return []models.BackendOption{{
Name: "server-url",
Label: "Server URL",
Type: models.String,

View file

@ -36,8 +36,8 @@ type JSPFBackend struct {
func (b *JSPFBackend) Name() string { return "jspf" }
func (b *JSPFBackend) Options() *[]models.BackendOption {
return &[]models.BackendOption{{
func (b *JSPFBackend) Options() []models.BackendOption {
return []models.BackendOption{{
Name: "file-path",
Label: "File path",
Type: models.String,

View file

@ -43,8 +43,8 @@ type LastfmApiBackend struct {
func (b *LastfmApiBackend) Name() string { return "lastfm" }
func (b *LastfmApiBackend) Options() *[]models.BackendOption {
return &[]models.BackendOption{{
func (b *LastfmApiBackend) Options() []models.BackendOption {
return []models.BackendOption{{
Name: "username",
Label: "User name",
Type: models.String,

View file

@ -34,8 +34,8 @@ type ListenBrainzApiBackend struct {
func (b *ListenBrainzApiBackend) Name() string { return "listenbrainz" }
func (b *ListenBrainzApiBackend) Options() *[]models.BackendOption {
return &[]models.BackendOption{{
func (b *ListenBrainzApiBackend) Options() []models.BackendOption {
return []models.BackendOption{{
Name: "username",
Label: "User name",
Type: models.String,

View file

@ -33,8 +33,8 @@ type MalojaApiBackend struct {
func (b *MalojaApiBackend) Name() string { return "maloja" }
func (b *MalojaApiBackend) Options() *[]models.BackendOption {
return &[]models.BackendOption{{
func (b *MalojaApiBackend) Options() []models.BackendOption {
return []models.BackendOption{{
Name: "server-url",
Label: "Server URL",
Type: models.String,

View file

@ -36,8 +36,8 @@ type ScrobblerLogBackend struct {
func (b *ScrobblerLogBackend) Name() string { return "scrobbler-log" }
func (b *ScrobblerLogBackend) Options() *[]models.BackendOption {
return &[]models.BackendOption{{
func (b *ScrobblerLogBackend) Options() []models.BackendOption {
return []models.BackendOption{{
Name: "file-path",
Label: "File path",
Type: models.String,

View file

@ -39,8 +39,8 @@ type SpotifyApiBackend struct {
func (b *SpotifyApiBackend) Name() string { return "spotify" }
func (b *SpotifyApiBackend) Options() *[]models.BackendOption {
return &[]models.BackendOption{{
func (b *SpotifyApiBackend) Options() []models.BackendOption {
return []models.BackendOption{{
Name: "client-id",
Label: "Client ID",
Type: models.String,

View file

@ -34,8 +34,8 @@ type SubsonicApiBackend struct {
func (b *SubsonicApiBackend) Name() string { return "subsonic" }
func (b *SubsonicApiBackend) Options() *[]models.BackendOption {
return &[]models.BackendOption{{
func (b *SubsonicApiBackend) Options() []models.BackendOption {
return []models.BackendOption{{
Name: "server-url",
Label: "Server URL",
Type: models.String,

88
internal/cli/services.go Normal file
View file

@ -0,0 +1,88 @@
/*
Copyright © 2023 Philipp Wolfer <phw@uploadedlobster.com>
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 cli
import (
"errors"
"fmt"
"slices"
"github.com/manifoldco/promptui"
"go.uploadedlobster.com/scotty/internal/backends"
"go.uploadedlobster.com/scotty/internal/config"
)
func SelectService() (config.ServiceConfig, error) {
services := config.AllServicesAsList()
if len(services) == 0 {
err := errors.New("no existing service configurations")
return config.ServiceConfig{}, err
}
sel := promptui.Select{
Label: "Service",
Items: services,
Size: 10,
}
i, _, err := sel.Run()
if err != nil {
return config.ServiceConfig{}, err
}
return services[i], nil
}
func SelectBackend(selected string) (string, error) {
backendList := backends.GetBackends()
i := slices.IndexFunc(backendList, func(b backends.BackendInfo) bool {
return b.Name == selected
})
sel := promptui.Select{
Label: "Backend",
Items: backendList,
CursorPos: i,
Size: 10,
}
_, backend, err := sel.Run()
return backend, err
}
func PromptExtraOptions(config config.ServiceConfig) (config.ServiceConfig, error) {
backend, err := backends.BackendByName(config.Backend)
if err != nil {
return config, err
}
opts := backend.Options()
if opts == nil {
return config, nil
}
values := make(map[string]any, len(opts))
for _, opt := range opts {
// Use current value as default
current, exists := config.ConfigValues[opt.Name]
if exists {
opt.Default = fmt.Sprintf("%v", current)
}
val, err := Prompt(opt)
if err != nil {
return config, err
}
values[opt.Name] = val
}
config.ConfigValues = values
return config, nil
}

View file

@ -17,6 +17,7 @@ package config
import (
"fmt"
"sort"
"github.com/spf13/cast"
"github.com/spf13/viper"
@ -44,6 +45,10 @@ func NewServiceConfig(name string, config *viper.Viper) ServiceConfig {
return service
}
func (c ServiceConfig) String() string {
return c.Name
}
func (c *ServiceConfig) GetString(key string) string {
return cast.ToString(c.ConfigValues[key])
}
@ -66,13 +71,27 @@ func (c *ServiceConfig) Save() error {
return viper.WriteConfig()
}
type ServiceList []ServiceConfig
func (l ServiceList) Len() int {
return len(l)
}
func (l ServiceList) Less(i, j int) bool {
return l[i].Name < l[j].Name
}
func (l ServiceList) Swap(i, j int) {
l[i], l[j] = l[j], l[i]
}
func AllServices() map[string]ServiceConfig {
services := make(map[string]ServiceConfig)
config := viper.Sub("service")
if config != nil {
for k, v := range config.AllSettings() {
s, ok := v.(*viper.Viper)
if ok {
for k := range config.AllSettings() {
s := config.Sub(k)
if s != nil {
services[k] = NewServiceConfig(k, s)
}
}
@ -80,6 +99,16 @@ func AllServices() map[string]ServiceConfig {
return services
}
func AllServicesAsList() ServiceList {
services := AllServices()
list := make(ServiceList, 0, len(services))
for _, s := range services {
list = append(list, s)
}
sort.Sort(list)
return list
}
func GetService(name string) (*ServiceConfig, error) {
key := "service." + name
config := viper.Sub(key)

View file

@ -35,7 +35,7 @@ type Backend interface {
FromConfig(config *config.ServiceConfig) Backend
// Return configuration options
Options() *[]BackendOption
Options() []BackendOption
}
type ImportBackend interface {