Skip to content

Commit 6eabc83

Browse files
committed
refactor: Separate some app logic into package session
This is a good start in refactoring the daemon app by separating the code into different packages.
1 parent 1c04775 commit 6eabc83

10 files changed

Lines changed: 806 additions & 725 deletions

File tree

cmd/daemon/controls.go

Lines changed: 149 additions & 149 deletions
Large diffs are not rendered by default.

cmd/daemon/creds.go

Lines changed: 0 additions & 24 deletions
This file was deleted.

cmd/daemon/main.go

Lines changed: 45 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ import (
88
"fmt"
99
log "github.com/sirupsen/logrus"
1010
"go-librespot/apresolve"
11+
"go-librespot/player"
1112
devicespb "go-librespot/proto/spotify/connectstate/devices"
13+
"go-librespot/session"
1214
"go-librespot/zeroconf"
1315
"gopkg.in/yaml.v3"
1416
"os"
1517
"strings"
16-
"sync"
1718
)
1819

1920
type App struct {
@@ -25,9 +26,6 @@ type App struct {
2526
deviceType devicespb.DeviceType
2627
clientToken string
2728

28-
sess *Session
29-
sessLock sync.Mutex
30-
3129
server *ApiServer
3230
}
3331

@@ -42,7 +40,6 @@ func parseDeviceType(val string) (devicespb.DeviceType, error) {
4240

4341
func NewApp(cfg *Config) (app *App, err error) {
4442
app = &App{cfg: cfg}
45-
app.resolver = apresolve.NewApResolver()
4643

4744
app.deviceType, err = parseDeviceType(cfg.DeviceType)
4845
if err != nil {
@@ -58,36 +55,37 @@ func NewApp(cfg *Config) (app *App, err error) {
5855
app.deviceId = cfg.DeviceId
5956
}
6057

61-
if len(cfg.ClientToken) == 0 {
62-
app.clientToken, err = retrieveClientToken(app.deviceId)
63-
if err != nil {
64-
return nil, fmt.Errorf("failed obtaining client token: %w", err)
65-
}
66-
} else {
58+
if len(cfg.ClientToken) > 0 {
6759
app.clientToken = cfg.ClientToken
6860
}
6961

7062
return app, nil
7163
}
7264

73-
func (app *App) newSession(creds SessionCredentials) (*Session, error) {
74-
// connect new session
75-
sess := &Session{app: app, countryCode: new(string)}
76-
if err := sess.Connect(creds); err != nil {
65+
func (app *App) newAppPlayer(creds any) (_ *AppPlayer, err error) {
66+
appPlayer := &AppPlayer{
67+
app: app,
68+
stop: make(chan struct{}, 1),
69+
countryCode: new(string),
70+
}
71+
72+
if appPlayer.sess, err = session.NewSessionFromOptions(&session.Options{
73+
DeviceType: app.deviceType,
74+
DeviceId: app.deviceId,
75+
ClientToken: app.clientToken,
76+
Resolver: app.resolver,
77+
Credentials: creds,
78+
}); err != nil {
7779
return nil, err
7880
}
7981

80-
app.sessLock.Lock()
81-
defer app.sessLock.Unlock()
82+
appPlayer.initState()
8283

83-
// disconnect previous session
84-
if app.sess != nil {
85-
app.sess.Close()
84+
if appPlayer.player, err = player.NewPlayer(appPlayer.sess.Spclient(), appPlayer.sess.AudioKey(), appPlayer.countryCode, app.cfg.AudioDevice, app.cfg.VolumeSteps); err != nil {
85+
return nil, fmt.Errorf("failed initializing player: %w", err)
8686
}
8787

88-
// update current session
89-
app.sess = sess
90-
return sess, nil
88+
return appPlayer, nil
9189
}
9290

9391
func (app *App) Zeroconf() error {
@@ -103,35 +101,35 @@ func (app *App) Zeroconf() error {
103101
}
104102

105103
// TODO: unset this when logging out
106-
var currentSession *Session
107-
var sessCh chan ApiRequest
104+
var currentPlayer *AppPlayer
105+
var apiCh chan ApiRequest
108106

109107
// forward API requests to proper channel only if a session is present
110108
go func() {
111109
for {
112110
select {
113111
case req := <-app.server.Receive():
114-
if currentSession == nil {
112+
if currentPlayer == nil {
115113
req.Reply(nil, ErrNoSession)
116114
break
117115
}
118116

119117
// if we are here a channel must exist
120-
sessCh <- req
118+
apiCh <- req
121119
}
122120
}
123121
}()
124122

125123
return z.Serve(func(req zeroconf.NewUserRequest) bool {
126-
if currentSession != nil {
127-
currentSession.Close()
128-
currentSession = nil
124+
if currentPlayer != nil {
125+
currentPlayer.Close()
126+
currentPlayer = nil
129127

130128
// close the channel after setting the current session to nil
131-
close(sessCh)
129+
close(apiCh)
132130
}
133131

134-
sess, err := app.newSession(SessionBlobCredentials{
132+
appPlayer, err := app.newAppPlayer(session.BlobCredentials{
135133
Username: req.Username,
136134
Blob: req.AuthBlob,
137135
})
@@ -141,10 +139,10 @@ func (app *App) Zeroconf() error {
141139
}
142140

143141
// first create the channel and then assign the current session
144-
sessCh = make(chan ApiRequest)
145-
currentSession = sess
142+
apiCh = make(chan ApiRequest)
143+
currentPlayer = appPlayer
146144

147-
go sess.Run(sessCh)
145+
go appPlayer.Run(apiCh)
148146
return true
149147
})
150148
}
@@ -155,19 +153,19 @@ type storedCredentialsFile struct {
155153
}
156154

157155
func (app *App) SpotifyToken(username, token string) error {
158-
return app.withReusableCredentials(SessionSpotifyTokenCredentials{username, token})
156+
return app.withReusableCredentials(session.SpotifyTokenCredentials{Username: username, Token: token})
159157
}
160158

161159
func (app *App) UserPass(username, password string) error {
162-
return app.withReusableCredentials(SessionUserPassCredentials{username, password})
160+
return app.withReusableCredentials(session.UserPassCredentials{Username: username, Password: password})
163161
}
164162

165-
func (app *App) withReusableCredentials(creds SessionCredentials) (err error) {
163+
func (app *App) withReusableCredentials(creds any) (err error) {
166164
var username string
167165
switch creds := creds.(type) {
168-
case SessionSpotifyTokenCredentials:
166+
case session.SpotifyTokenCredentials:
169167
username = creds.Username
170-
case SessionUserPassCredentials:
168+
case session.UserPassCredentials:
171169
username = creds.Username
172170
default:
173171
return fmt.Errorf("unsupported credentials for reuse")
@@ -190,31 +188,31 @@ func (app *App) withReusableCredentials(creds SessionCredentials) (err error) {
190188
log.Debugf("stored credentials not found")
191189
}
192190

193-
var sess *Session
191+
var appPlayer *AppPlayer
194192
if len(storedCredentials) > 0 {
195-
sess, err = app.newSession(SessionStoredCredentials{username, storedCredentials})
193+
appPlayer, err = app.newAppPlayer(session.StoredCredentials{Username: username, Data: storedCredentials})
196194
if err != nil {
197195
return err
198196
}
199197
} else {
200-
sess, err = app.newSession(creds)
198+
appPlayer, err = app.newAppPlayer(creds)
201199
if err != nil {
202200
return err
203201
}
204202

205203
if content, err := json.Marshal(&storedCredentialsFile{
206-
Username: sess.ap.Username(),
207-
Data: sess.ap.StoredCredentials(),
204+
Username: appPlayer.sess.Username(),
205+
Data: appPlayer.sess.StoredCredentials(),
208206
}); err != nil {
209207
return fmt.Errorf("failed marshalling stored credentials: %w", err)
210208
} else if err := os.WriteFile(app.cfg.CredentialsPath, content, 0600); err != nil {
211209
return fmt.Errorf("failed writing stored credentials file: %w", err)
212210
}
213211

214-
log.Debugf("stored credentials for %s", sess.ap.Username())
212+
log.Debugf("stored credentials for %s", appPlayer.sess.Username())
215213
}
216214

217-
sess.Run(app.server.Receive())
215+
appPlayer.Run(app.server.Receive())
218216
return nil
219217
}
220218

0 commit comments

Comments
 (0)