@@ -26,17 +26,9 @@ import (
2626 "net/http"
2727 "regexp"
2828 "strconv"
29- "time "
29+ "strings "
3030)
3131
32- type location struct {
33- ID uint
34- Url string
35- Size int64
36- ETag string
37- LastModified time.Time
38- }
39-
4032type login struct {
4133 User string
4234 Pass string
@@ -223,9 +215,12 @@ func (handler *MusicHandler) apiStation(w http.ResponseWriter, r *http.Request,
223215// GET /api/{res}/id/playlist > spiff.Playlist{}
224216// 200: success
225217func (handler * MusicHandler ) apiRefPlaylist (w http.ResponseWriter , r * http.Request , m * Music ,
226- title , ref string ) {
218+ creator , title , image , ref string ) {
227219 plist := spiff .NewPlaylist ()
220+ plist .Spiff .Location = fmt .Sprintf ("%s%s" , m .config .Server .URL , r .URL .Path )
221+ plist .Spiff .Creator = creator
228222 plist .Spiff .Title = title
223+ plist .Spiff .Image = image
229224 plist .Entries = []spiff.Entry {{Ref : ref }}
230225 m .Resolve (handler .user , plist )
231226 if plist .Entries == nil {
@@ -247,7 +242,9 @@ func (handler *MusicHandler) apiRefPlaylist(w http.ResponseWriter, r *http.Reque
247242func (handler * MusicHandler ) apiPlaylist (w http.ResponseWriter , r * http.Request , music * Music ) {
248243 p := music .lookupPlaylist (handler .user )
249244 if p == nil {
250- data , _ := spiff .NewPlaylist ().Marshal ()
245+ plist := spiff .NewPlaylist ()
246+ plist .Spiff .Location = fmt .Sprintf ("%s/api/playlist" , music .config .Server .URL )
247+ data , _ := plist .Marshal ()
251248 p = & Playlist {User : handler .user .Name , Playlist : data }
252249 err := music .createPlaylist (p )
253250 if err != nil {
@@ -299,16 +296,40 @@ func (handler *MusicHandler) apiView(w http.ResponseWriter, r *http.Request, vie
299296 enc .Encode (view )
300297}
301298
299+ func (handler * MusicHandler ) apiSearch (w http.ResponseWriter , r * http.Request , music * Music ) {
300+ if v := r .URL .Query ().Get ("q" ); v != "" {
301+ // /api/search?q={pattern}
302+ view := music .SearchView (strings .TrimSpace (v ))
303+ handler .apiView (w , r , view )
304+ } else {
305+ http .Error (w , "bummer" , http .StatusNotFound )
306+ }
307+ }
308+
302309// POST /api/login -> see apiLogin
310+ //
303311// GET,PATCH /api/playlist -> see apiPlaylist
304312//
313+ // GET /api/radio > RadioView{}
314+ // GET /api/radio/1 > spiff.Playlist{}
315+ // POST /api/radio
316+ // GET,PATH,DELETE /api/radio/1 >
317+ //
305318// GET /api/home > HomeView{}
319+ // GET /api/search > SearchView{}
320+ //
321+ // GET /api/tracks/1/location -> Redirect
322+ //
306323// GET /api/artists > ArtistsView{}
307324// GET /api/artists/1 > ArtistView{}
325+ // GET /api/artists/1/popular > PopularView{}
326+ // GET /api/artists/1/singles > SinglesView{}
327+ // GET /api/artists/1/playlist > spiff.Playlist{}
328+ // GET /api/artists/1/radio > spiff.Playlist{}
329+ //
308330// GET /api/releases/1 > ReleaseView{}
309- // GET,POST /api/radio
310- // GET,PATH,DELETE /api/radio/1 >
311- // GET /api/tracks/1/location -> location{}
331+ // GET /api/releases/1/playlist > spiff.Playlist{}
332+ //
312333// 200: success
313334// 500: error
314335func (handler * MusicHandler ) apiHandler (w http.ResponseWriter , r * http.Request ) {
@@ -336,6 +357,8 @@ func (handler *MusicHandler) apiHandler(w http.ResponseWriter, r *http.Request)
336357 handler .apiView (w , r , music .HomeView ())
337358 case "/api/artists" :
338359 handler .apiView (w , r , music .ArtistsView ())
360+ case "/api/search" :
361+ handler .apiSearch (w , r , music )
339362 default :
340363 // id sub-resources
341364 locationRegexp := regexp .MustCompile (`/api/tracks/([0-9]+)/location` )
@@ -345,35 +368,54 @@ func (handler *MusicHandler) apiHandler(w http.ResponseWriter, r *http.Request)
345368 id , _ := strconv .Atoi (v )
346369 track , _ := music .lookupTrack (id )
347370 url := music .TrackURL (& track )
348- handler .apiView (w , r , location {
349- ID : track .ID ,
350- Url : url .String (),
351- Size : track .Size ,
352- ETag : track .ETag ,
353- LastModified : track .LastModified ,
354- })
371+ // TODO use 307 instead?
372+ http .Redirect (w , r , url .String (), http .StatusFound )
355373 return
356374 }
357375
358- // resources with id and playlist
359- playlistRegexp := regexp .MustCompile (`/api/([a-z]+)/([0-9]+)/playlist` )
376+ // resources with id and sub-resource
377+ playlistRegexp := regexp .MustCompile (`/api/([a-z]+)/([0-9]+)/( playlist|popular|singles|radio) ` )
360378 matches = playlistRegexp .FindStringSubmatch (r .URL .Path )
361379 if matches != nil {
362380 v := matches [1 ]
363381 id , _ := strconv .Atoi (matches [2 ])
382+ res := matches [3 ]
364383 switch v {
365384 case "artists" :
366- // /api/artists/1/playlist
367385 artist , _ := music .lookupArtist (id )
368- handler .apiRefPlaylist (w , r , music ,
369- fmt .Sprintf ("%s" , artist .Name ),
370- fmt .Sprintf ("/music/artists/%d/shuffle" , id ))
386+ if res == "playlist" {
387+ // /api/artists/1/playlist
388+ handler .apiRefPlaylist (w , r , music ,
389+ artist .Name ,
390+ "Top Tracks" ,
391+ "" ,
392+ fmt .Sprintf ("/music/artists/%d/popular" , id ))
393+ } else if res == "radio" {
394+ // /api/artists/1/radio
395+ handler .apiRefPlaylist (w , r , music ,
396+ "Radio" ,
397+ fmt .Sprintf ("%s Radio" , artist .Name ),
398+ "" ,
399+ fmt .Sprintf ("/music/artists/%d/similar" , id ))
400+ } else if res == "popular" {
401+ // /api/artists/1/popular
402+ handler .apiView (w , r , music .PopularView (artist ))
403+ } else if res == "singles" {
404+ // /api/artists/1/singles
405+ handler .apiView (w , r , music .SinglesView (artist ))
406+ }
371407 case "releases" :
372408 // /api/releases/1/playlist
373- release , _ := music .lookupRelease (id )
374- handler .apiRefPlaylist (w , r , music ,
375- fmt .Sprintf ("%s ~ %s" , release .Artist , release .Name ),
376- fmt .Sprintf ("/music/releases/%d/tracks" , id ))
409+ if res == "playlist" {
410+ release , _ := music .lookupRelease (id )
411+ handler .apiRefPlaylist (w , r , music ,
412+ release .Artist ,
413+ release .Name ,
414+ music .cover (release , "250" ),
415+ fmt .Sprintf ("/music/releases/%d/tracks" , id ))
416+ } else {
417+ http .Error (w , "bummer" , http .StatusNotFound )
418+ }
377419 default :
378420 http .Error (w , "bummer" , http .StatusNotFound )
379421 }
0 commit comments