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 := parseScrobbles(r.Form, session) store.PutScrobbles(scrobbles) return Scrobbles{Scrobbles: scrobbles, Attrs: Attrs{1, 0}}, 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) }