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, http.ResponseWriter) ApiResponse } type ApiResponse interface { } type Name struct { XMLName xml.Name } type Token struct { Name string } 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{ Corrected: 0, 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, w http.ResponseWriter) ApiResponse { if session, err := store.GetSession(r.FormValue("s")); err != nil { scrobbles := parseScrobbles(r.Form, session) store.PutScrobbles(scrobbles) fmt.Fprintln(w, "OK") } else { fmt.Fprintln(w, "BADSESSION") } return struct{}{} } func ApiHandler(ds DataStore, w http.ResponseWriter, r *http.Request) { method := r.FormValue("method") var response ApiResponse switch method { case "auth.getToken": response = ds.AuthGetToken(r) case "auth.getSession": response = ds.AuthGetSession(r) case "track.scrobble": response = ds.TrackScrobble(r, w) } var text []byte switch r.FormValue("format") { case "json": text, _ = json.Marshal(response) default: text, _ = xml.Marshal(response) } fmt.Printf("%s\n", text) w.Write(text) }