This repository has been archived by the owner on Nov 19, 2017. It is now read-only.
/
albums.go
120 lines (102 loc) · 2.72 KB
/
albums.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package api
import (
"database/sql"
"fmt"
"log"
"net/http"
"strconv"
"github.com/mdlayher/wavepipe/data"
"github.com/gorilla/context"
"github.com/gorilla/mux"
"github.com/unrolled/render"
)
// AlbumsResponse represents the JSON response for the Albums API.
type AlbumsResponse struct {
Error *Error `json:"error"`
Albums []data.Album `json:"albums"`
Songs []data.Song `json:"songs"`
}
// GetAlbums retrieves one or more albums from wavepipe, and returns a HTTP status and JSON.
// It can be used to fetch a single album, a limited subset of albums, or all albums, depending
// on the request parameters.
func GetAlbums(w http.ResponseWriter, r *http.Request) {
// Retrieve render
ren := context.Get(r, CtxRender).(*render.Render)
// Output struct for albums request
out := AlbumsResponse{}
// Check API version
if version, ok := mux.Vars(r)["version"]; ok {
// Check if this API call is supported in the advertised version
if !apiVersionSet.Has(version) {
ren.JSON(w, 400, errRes(400, "unsupported API version: "+version))
return
}
}
// Check for an ID parameter
if pID, ok := mux.Vars(r)["id"]; ok {
// Verify valid integer ID
id, err := strconv.Atoi(pID)
if err != nil {
ren.JSON(w, 400, errRes(400, "invalid integer album ID"))
return
}
// Load the album
album := &data.Album{ID: id}
if err := album.Load(); err != nil {
// Check for invalid ID
if err == sql.ErrNoRows {
ren.JSON(w, 404, errRes(404, "album ID not found"))
return
}
// All other errors
log.Println(err)
ren.JSON(w, 500, serverErr)
return
}
// On single album, load the songs for this album
songs, err := data.DB.SongsForAlbum(album.ID)
if err != nil {
log.Println(err)
ren.JSON(w, 500, serverErr)
return
}
// Add album and songs to output
out.Albums = []data.Album{*album}
out.Songs = songs
// HTTP 200 OK with JSON
ren.JSON(w, 200, out)
return
}
// Check for a limit parameter
if pLimit := r.URL.Query().Get("limit"); pLimit != "" {
// Split limit into two integers
var offset int
var count int
if n, err := fmt.Sscanf(pLimit, "%d,%d", &offset, &count); n < 2 || err != nil {
ren.JSON(w, 400, errRes(400, "invalid comma-separated integer pair for limit"))
return
}
// Retrieve limited subset of albums
albums, err := data.DB.LimitAlbums(offset, count)
if err != nil {
log.Println(err)
ren.JSON(w, 500, serverErr)
return
}
// HTTP 200 OK with JSON
out.Albums = albums
ren.JSON(w, 200, out)
return
}
// If no other case, retrieve all albums
albums, err := data.DB.AllAlbums()
if err != nil {
log.Println(err)
ren.JSON(w, 500, serverErr)
return
}
// HTTP 200 OK with JSON
out.Albums = albums
ren.JSON(w, 200, out)
return
}