mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-19 09:06:14 +00:00
This commit completes the music service account management implementation and resolves all golangci-lint issues across the codebase. Music Service Account Management: • Add/remove accounts for all major streaming services (Spotify, Pandora, Amazon Music, Deezer, iHeartRadio) • Support for network music libraries (NAS/UPnP/DLNA servers) • Generic account management with service-specific convenience methods • Full CLI integration with 14 account management commands • Comprehensive test coverage with mock HTTP servers • Complete API documentation and usage examples New CLI Commands: • account list - List configured accounts • account add/remove - Generic account management • account add-spotify/remove-spotify - Spotify Premium • account add-pandora/remove-pandora - Pandora Music Service • account add-amazon/remove-amazon - Amazon Music • account add-deezer/remove-deezer - Deezer Premium • account add-iheart/remove-iheart - iHeartRadio • account add-nas/remove-nas - Network music libraries New API Methods: • SetMusicServiceAccount() / RemoveMusicServiceAccount() - Generic methods • AddSpotifyAccount() / RemoveSpotifyAccount() - Convenience methods • AddPandoraAccount() / RemovePandoraAccount() - Convenience methods • AddAmazonMusicAccount() / RemoveAmazonMusicAccount() - Convenience methods • AddDeezerAccount() / RemoveDeezerAccount() - Convenience methods • AddIHeartRadioAccount() / RemoveIHeartRadioAccount() - Convenience methods • AddStoredMusicAccount() / RemoveStoredMusicAccount() - Network libraries golangci-lint Fixes (36 issues resolved): • errcheck (3): Fixed unchecked w.Write() returns in tests • gocritic (3): Rewrote if-else chains to switch statements • gocyclo (6): Reduced cyclomatic complexity via helper function extraction • govet (12): Removed unused test data and field assignments • revive (6): Added package comments and fixed unused parameters • staticcheck (2): Replaced deprecated strings.Title usage • thelper (6): Added t.Helper() calls to test helper functions • unused (1): Removed unused createTestApp() function • whitespace/wsl_v5 (7): Fixed whitespace and formatting issues Code Quality Improvements: • All functions now have complexity < 15 (down from max 28) • Consistent error handling and validation patterns • Better separation of concerns with extracted helper functions • Zero external dependencies added for simple fixes • Comprehensive documentation with usage examples • Full backward compatibility maintained Files Added: • pkg/models/account.go - Account management models • pkg/models/account_test.go - Account model tests • pkg/client/account_test.go - Account client tests • cmd/soundtouch-cli/cmd_account.go - Account CLI commands • examples/account-management/ - Complete usage example • Updated docs/CLI-REFERENCE.md with account management section The implementation provides a complete, production-ready music service account management system with full CLI and programmatic API support.
123 lines
3.9 KiB
Go
123 lines
3.9 KiB
Go
// Package models provides data structures and types for music service account management
|
|
// on Bose SoundTouch devices.
|
|
package models
|
|
|
|
import (
|
|
"encoding/xml"
|
|
"fmt"
|
|
)
|
|
|
|
// MusicServiceCredentials represents credentials for music service account operations
|
|
type MusicServiceCredentials struct {
|
|
XMLName xml.Name `xml:"credentials"`
|
|
Source string `xml:"source,attr"`
|
|
DisplayName string `xml:"displayName,attr,omitempty"`
|
|
User string `xml:"user"`
|
|
Pass string `xml:"pass"`
|
|
}
|
|
|
|
// NewMusicServiceCredentials creates new music service credentials
|
|
func NewMusicServiceCredentials(source, displayName, user, pass string) *MusicServiceCredentials {
|
|
return &MusicServiceCredentials{
|
|
Source: source,
|
|
DisplayName: displayName,
|
|
User: user,
|
|
Pass: pass,
|
|
}
|
|
}
|
|
|
|
// NewSpotifyCredentials creates credentials for Spotify service
|
|
func NewSpotifyCredentials(user, pass string) *MusicServiceCredentials {
|
|
return NewMusicServiceCredentials("SPOTIFY", "Spotify Premium", user, pass)
|
|
}
|
|
|
|
// NewPandoraCredentials creates credentials for Pandora service
|
|
func NewPandoraCredentials(user, pass string) *MusicServiceCredentials {
|
|
return NewMusicServiceCredentials("PANDORA", "Pandora Music Service", user, pass)
|
|
}
|
|
|
|
// NewStoredMusicCredentials creates credentials for STORED_MUSIC (NAS/UPnP) service
|
|
func NewStoredMusicCredentials(user, displayName string) *MusicServiceCredentials {
|
|
return NewMusicServiceCredentials("STORED_MUSIC", displayName, user, "")
|
|
}
|
|
|
|
// NewAmazonMusicCredentials creates credentials for Amazon Music service
|
|
func NewAmazonMusicCredentials(user, pass string) *MusicServiceCredentials {
|
|
return NewMusicServiceCredentials("AMAZON", "Amazon Music", user, pass)
|
|
}
|
|
|
|
// NewDeezerCredentials creates credentials for Deezer service
|
|
func NewDeezerCredentials(user, pass string) *MusicServiceCredentials {
|
|
return NewMusicServiceCredentials("DEEZER", "Deezer Premium", user, pass)
|
|
}
|
|
|
|
// NewIHeartRadioCredentials creates credentials for iHeartRadio service
|
|
func NewIHeartRadioCredentials(user, pass string) *MusicServiceCredentials {
|
|
return NewMusicServiceCredentials("IHEART", "iHeartRadio", user, pass)
|
|
}
|
|
|
|
// Validate ensures the credentials have required fields
|
|
func (cred *MusicServiceCredentials) Validate() error {
|
|
if cred.Source == "" {
|
|
return fmt.Errorf("source cannot be empty")
|
|
}
|
|
|
|
if cred.User == "" {
|
|
return fmt.Errorf("user cannot be empty")
|
|
}
|
|
|
|
// STORED_MUSIC typically doesn't require a password
|
|
if cred.Source != "STORED_MUSIC" && cred.Pass == "" {
|
|
return fmt.Errorf("password cannot be empty for %s", cred.Source)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// IsForRemoval returns true if these credentials are for removing an account (empty password)
|
|
func (cred *MusicServiceCredentials) IsForRemoval() bool {
|
|
return cred.Pass == ""
|
|
}
|
|
|
|
// HasPassword returns true if credentials include a password
|
|
func (cred *MusicServiceCredentials) HasPassword() bool {
|
|
return cred.Pass != ""
|
|
}
|
|
|
|
// GetDescription returns a human-readable description of the service
|
|
func (cred *MusicServiceCredentials) GetDescription() string {
|
|
if cred.DisplayName != "" {
|
|
return cred.DisplayName
|
|
}
|
|
|
|
switch cred.Source {
|
|
case "SPOTIFY":
|
|
return "Spotify Premium"
|
|
case "PANDORA":
|
|
return "Pandora Music Service"
|
|
case "AMAZON":
|
|
return "Amazon Music"
|
|
case "DEEZER":
|
|
return "Deezer Premium"
|
|
case "IHEART":
|
|
return "iHeartRadio"
|
|
case "STORED_MUSIC":
|
|
return "Network Music Library"
|
|
case "LOCAL_MUSIC":
|
|
return "Local Music Server"
|
|
default:
|
|
return cred.Source
|
|
}
|
|
}
|
|
|
|
// MusicServiceAccountResponse represents the response from account management operations
|
|
type MusicServiceAccountResponse struct {
|
|
XMLName xml.Name `xml:"status"`
|
|
Status string `xml:",chardata"`
|
|
}
|
|
|
|
// IsSuccess returns true if the account operation was successful
|
|
func (resp *MusicServiceAccountResponse) IsSuccess() bool {
|
|
return resp.Status == "/setMusicServiceAccount" || resp.Status == "/removeMusicServiceAccount"
|
|
}
|