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
121
122
123
124
125
126
127
128
129
|
package main
import (
"database/sql/driver"
"encoding/json"
"encoding/xml"
"fmt"
"net/http"
)
type Api interface {
AuthGetToken(*http.Request) ApiResponse
AuthGetSession(*http.Request) ApiResponse
AuthGetMobileSession(*http.Request) ApiResponse
TrackScrobble(*http.Request) (ApiResponse, error)
}
type ApiResponse interface {
}
type Name struct {
XMLName xml.Name
}
type Token struct {
Name
string
}
type LFMResponse struct {
XMLName xml.Name `xml:"lfm" json:"-"`
Status string `xml:"status,attr" json:"-"`
Response ApiResponse `json:"scrobbles"`
}
type Attrs struct {
Accepted int `xml:"accepted,attr" json:"accepted"`
Ignored int `xml:"ignored,attr" json:"ignored"`
}
type Scrobbles struct {
XMLName xml.Name `xml:"scrobbles" json:"-"`
Scrobbles []Scrobble `xml:"scrobble" json:"scrobble"`
Attrs `json:"@attr"`
}
type Correctable struct {
Name string `xml:",chardata" json:"#text"`
Corrected int `xml:"corrected,attr" json:"corrected"`
}
func (field Correctable) Value() (driver.Value, error) {
return field.Name, nil
}
func NewCorrectable(name string) Correctable {
return Correctable{
Name: name,
}
}
func (field *Correctable) String() string {
return field.Name
}
func (n Name) getName() string {
return n.XMLName.Local
}
func (store *SqlStore) AuthGetToken(r *http.Request) ApiResponse {
token := randomToken(16)
response := struct {
Token string `xml:"token" json:"token"`
}{Token: token}
return response
}
func (store *SqlStore) AuthGetMobileSession(r *http.Request) ApiResponse {
return struct{}{}
}
func (store *SqlStore) AuthGetSession(r *http.Request) ApiResponse {
var response struct {
Session *Session `json:"session"`
}
session := NewSession("thibauthorel", r.FormValue("api_key"), "2.0")
store.PutSession(session)
response.Session = session
return response
}
func (store *SqlStore) TrackScrobble(r *http.Request) (ApiResponse, error) {
if session, err := store.GetSession(r.FormValue("sk")); err != nil {
fmt.Printf("%v\n", err)
return struct{}{}, err
} else {
scrobbles, ignored := parseScrobbles(r.Form, session)
store.PutScrobbles(scrobbles)
return Scrobbles{Scrobbles: scrobbles,
Attrs: Attrs{len(scrobbles), ignored}}, nil
}
}
func ApiHandler(ds DataStore, w http.ResponseWriter, r *http.Request) {
method := r.FormValue("method")
response := LFMResponse{Status: "ok"}
switch method {
case "auth.getToken":
response.Response = ds.AuthGetToken(r)
case "auth.getSession":
response.Response = ds.AuthGetSession(r)
case "track.scrobble":
if r, err := ds.TrackScrobble(r); err != nil {
fmt.Printf("%v\n", err)
} else {
response.Response = r
}
}
var text []byte
switch r.FormValue("format") {
case "json":
text, _ = json.Marshal(response)
default:
text, _ = xml.Marshal(response)
}
fmt.Printf("%s\n", text)
fmt.Fprint(w, xml.Header)
w.Write(text)
}
|