diff --git a/r_request.go b/r_request.go index 266b0f6..eaf8e43 100644 --- a/r_request.go +++ b/r_request.go @@ -37,13 +37,13 @@ type Request struct { Conductor []string `json:"conductor"` RemixedBy []string `json:"remixedBy"` Producer []string `json:"producer"` - } `json"musicInfo"` + } `json:"musicInfo"` CatalogueNumber string `json:"catalogueNumber"` ReleaseType int `json:"releaseType"` ReleaseName string `json:"releaseName"` - BitrateList []string `json:"bitrateList"` - FormatList []string `json:"formatList"` - MediaList []string `json:"mediaList"` + BitrateList []string `json:"bitrateList"` + FormatList []string `json:"formatList"` + MediaList []string `json:"mediaList"` LogCue string `json:"logCue"` IsFilled bool `json:"isFilled"` FillerID int `json:"fillerID"` @@ -68,4 +68,4 @@ type Request struct { } `json:"comments"` CommentPage int `json:"commentPage"` CommentPages int `json:"commentPages"` -} \ No newline at end of file +} diff --git a/r_torrent.go b/r_torrent.go index 4355714..84ba4e5 100644 --- a/r_torrent.go +++ b/r_torrent.go @@ -1,7 +1,7 @@ package whatapi type Torrent struct { - Group GroupType `json:"group"` + Group GroupType `json:"group"` Torrent TorrentType `json:"torrent"` } @@ -19,9 +19,15 @@ type GroupType struct { Time string `json:"time"` VanityHouse bool `json:"vanityHouse"` MusicInfo struct { - Composers []string `json:"composers"` - DJ []string `json:"dj"` - Artists []struct { + Composers []struct { + ID int `json:"id"` + Name string `json:"name"` + } `json:"composers"` + DJ []struct { + ID int `json:"id"` + Name string `json:"name"` + } `json:"dj"` + Artists []struct { ID int `json:"id"` Name string `json:"name"` } @@ -29,11 +35,20 @@ type GroupType struct { ID int `json:"id"` Name string `json:"name"` } `json:"with"` - Conductor []string `json:"conductor"` - RemixedBy []string `json:"remixedBy"` - Producer []string `json:"producer"` - } `json"musicInfo"` - Tags []string `json"tags"` + Conductor []struct { + ID int `json:"id"` + Name string `json:"name"` + } `json:"conductor"` + RemixedBy []struct { + ID int `json:"id"` + Name string `json:"name"` + } `json:"remixedBy"` + Producer []struct { + ID int `json:"id"` + Name string `json:"name"` + } `json:"producer"` + } `json:"musicInfo"` + Tags []string `json:"tags"` } type TorrentType struct { @@ -62,4 +77,4 @@ type TorrentType struct { FilePath string `json:"filePath"` UserID int `json:"userID"` Username string `json:"username"` -} \ No newline at end of file +} diff --git a/whatapi.go b/whatapi.go index 76691b8..f3f7a10 100644 --- a/whatapi.go +++ b/whatapi.go @@ -8,12 +8,14 @@ import ( "net/http/cookiejar" "net/url" "strconv" + "strings" ) //NewWhatAPI creates a new client for the What.CD API using the provided URL. -func NewWhatAPI(url string) (*WhatAPI, error) { +func NewWhatAPI(url, agent string) (*WhatAPI, error) { w := new(WhatAPI) w.baseURL = url + w.userAgent = agent cookieJar, err := cookiejar.New(nil) if err != nil { return w, err @@ -24,50 +26,79 @@ func NewWhatAPI(url string) (*WhatAPI, error) { //WhatAPI represents a client for the What.CD API. type WhatAPI struct { - baseURL string - client *http.Client - authkey string - passkey string - loggedIn bool + baseURL string + userAgent string + client *http.Client + authkey string + passkey string + loggedIn bool } //GetJSON sends a HTTP GET request to the API and decodes the JSON response into responseObj. func (w *WhatAPI) GetJSON(requestURL string, responseObj interface{}) error { - if w.loggedIn { - resp, err := w.client.Get(requestURL) - if err != nil { - return err - } - defer resp.Body.Close() - if resp.StatusCode != 200 { - return errRequestFailedReason("Status Code " + resp.Status) - } - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - return json.Unmarshal(body, responseObj) - - } - return errRequestFailedLogin + if !w.loggedIn { + return errRequestFailedLogin + } + + req, err := http.NewRequest("GET", requestURL, nil) + req.Header.Set("User-Agent", w.userAgent) + if err != nil { + return err + } + resp, err := w.client.Do(req) + if err != nil { + return err + } + + defer resp.Body.Close() + if resp.StatusCode != 200 { + return errRequestFailedReason("Status Code " + resp.Status) + } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + + var st GenericResponse + if err := json.Unmarshal(body, &st); err != nil { + return err + } + + if err := checkResponseStatus(st.Status, st.Error); err != nil { + return err + } + return json.Unmarshal(body, responseObj) +} + +type GenericResponse struct { + Status string `json:"status"` + Error string `json:"error"` +} + +func (w *WhatAPI) Do(action string, params url.Values, result interface{}) error { + requestURL, err := buildURL(w.baseURL, "ajax.php", action, params) + if err != nil { + return err + } + return w.GetJSON(requestURL, result) } //CreateDownloadURL constructs a download URL using the provided torrent id. func (w *WhatAPI) CreateDownloadURL(id int) (string, error) { - if w.loggedIn { - params := url.Values{} - params.Set("action", "download") - params.Set("id", strconv.Itoa(id)) - params.Set("authkey", w.authkey) - params.Set("torrent_pass", w.passkey) - downloadURL, err := buildURL(w.baseURL, "torrents.php", "", params) - if err != nil { - return "", err - } - return downloadURL, nil - } - return "", errRequestFailedLogin + if !w.loggedIn { + return "", errRequestFailedLogin + } + params := url.Values{} + params.Set("action", "download") + params.Set("id", strconv.Itoa(id)) + params.Set("authkey", w.authkey) + params.Set("torrent_pass", w.passkey) + downloadURL, err := buildURL(w.baseURL, "torrents.php", "", params) + if err != nil { + return "", err + } + return downloadURL, nil } //Login logs in to the API using the provided credentials. @@ -75,10 +106,16 @@ func (w *WhatAPI) Login(username, password string) error { params := url.Values{} params.Set("username", username) params.Set("password", password) - resp, err := w.client.PostForm(w.baseURL+"login.php?", params) + + reqBody := strings.NewReader(params.Encode()) + req, err := http.NewRequest("POST", w.baseURL+"login.php", reqBody) + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.Header.Set("User-Agent", w.userAgent) + resp, err := w.client.Do(req) if err != nil { return err } + defer resp.Body.Close() if resp.Request.URL.String()[len(w.baseURL):] != "index.php" { return errLoginFailed