@@ -11,6 +11,7 @@ import (
11
11
"time"
12
12
13
13
"github.com/disintegration/imaging"
14
+ "github.com/jinzhu/gorm"
14
15
15
16
"go.senan.xyz/gonic/server/ctrlsubsonic/params"
16
17
"go.senan.xyz/gonic/server/ctrlsubsonic/spec"
@@ -26,42 +27,64 @@ import (
26
27
// b) return a non-nil spec.Response
27
28
// _but not both_
28
29
29
- func streamGetTransPref (dbc * db.DB , userID int , client string ) db.TranscodePreference {
30
- pref := db.TranscodePreference {}
31
- dbc .
30
+ func streamGetTransPref (dbc * db.DB , userID int , client string ) ( * db.TranscodePreference , error ) {
31
+ var pref db.TranscodePreference
32
+ err := dbc .
32
33
Where ("user_id=?" , userID ).
33
34
Where ("client COLLATE NOCASE IN (?)" , []string {"*" , client }).
34
35
Order ("client DESC" ). // ensure "*" is last if it's there
35
- First (& pref )
36
- return pref
36
+ First (& pref ).
37
+ Error
38
+ if errors .Is (err , gorm .ErrRecordNotFound ) {
39
+ return & pref , nil
40
+ }
41
+ if err != nil {
42
+ return nil , fmt .Errorf ("find transcode preference: %w" , err )
43
+ }
44
+ return & pref , nil
37
45
}
38
46
39
47
func streamGetTrack (dbc * db.DB , trackID int ) (* db.Track , error ) {
40
- track := db.Track {}
48
+ var track db.Track
41
49
err := dbc .
42
50
Preload ("Album" ).
43
51
First (& track , trackID ).
44
52
Error
45
- return & track , err
53
+ if err != nil {
54
+ return nil , fmt .Errorf ("find track: %w" , err )
55
+ }
56
+ return & track , nil
46
57
}
47
58
48
59
func streamGetPodcast (dbc * db.DB , podcastID int ) (* db.PodcastEpisode , error ) {
49
- podcast := db.PodcastEpisode {}
50
- err := dbc .First (& podcast , podcastID ).Error
51
- return & podcast , err
60
+ var podcast db.PodcastEpisode
61
+ if err := dbc .First (& podcast , podcastID ).Error ; err != nil {
62
+ return nil , fmt .Errorf ("find podcast: %w" , err )
63
+ }
64
+ return & podcast , nil
52
65
}
53
66
54
- func streamUpdateStats (dbc * db.DB , userID , albumID int ) {
67
+ func streamUpdateStats (dbc * db.DB , userID , albumID int , playTime time. Time ) error {
55
68
play := db.Play {
56
69
AlbumID : albumID ,
57
70
UserID : userID ,
58
71
}
59
- dbc .
72
+ err := dbc .
60
73
Where (play ).
61
- First (& play )
62
- play .Time = time .Now () // for getAlbumList?type=recent
63
- play .Count ++ // for getAlbumList?type=frequent
64
- dbc .Save (& play )
74
+ First (& play ).
75
+ Error
76
+ if err != nil && ! errors .Is (err , gorm .ErrRecordNotFound ) {
77
+ return fmt .Errorf ("find stat: %w" , err )
78
+ }
79
+
80
+ play .Count ++ // for getAlbumList?type=frequent
81
+ if playTime .After (play .Time ) {
82
+ play .Time = playTime // for getAlbumList?type=recent
83
+ }
84
+ if err := dbc .Save (& play ).Error ; err != nil {
85
+ return fmt .Errorf ("save stat: %w" , err )
86
+ }
87
+ return nil
65
88
}
66
89
67
90
const (
@@ -242,10 +265,18 @@ func (c *Controller) ServeStream(w http.ResponseWriter, r *http.Request) *spec.R
242
265
243
266
user := r .Context ().Value (CtxUser ).(* db.User )
244
267
if track , ok := audioFile .(* db.Track ); ok && track .Album != nil {
245
- defer streamUpdateStats (c .DB , user .ID , track .Album .ID )
268
+ defer func () {
269
+ if err := streamUpdateStats (c .DB , user .ID , track .Album .ID , time .Now ()); err != nil {
270
+ log .Printf ("error updating listen stats: %v" , err )
271
+ }
272
+ }()
273
+ }
274
+
275
+ pref , err := streamGetTransPref (c .DB , user .ID , params .GetOr ("c" , "" ))
276
+ if err != nil {
277
+ return spec .NewError (0 , "failed to get transcode stream preference: %v" , err )
246
278
}
247
279
248
- pref := streamGetTransPref (c .DB , user .ID , params .GetOr ("c" , "" ))
249
280
onInvalidProfile := func () error {
250
281
log .Printf ("serving raw `%s`\n " , audioFile .AudioFilename ())
251
282
w .Header ().Set ("Content-Type" , audioFile .MIME ())
0 commit comments