1
0
Fork 0
mirror of https://github.com/imjasonh/go-marvel synced 2026-07-17 06:21:55 +00:00

Add lots more methods

This commit is contained in:
Jason Hall 2014-05-04 12:20:47 -04:00
parent dd29e025ee
commit 4cf4c023a5

324
marvel.go
View file

@ -28,12 +28,30 @@ func NewClient(public, private string) Client {
return Client{public, private}
}
// See http://developer.marvel.com/documentation/authorization
func (c Client) hash() (int64, string) {
ts := time.Now().Unix()
hash := md5.New()
io.WriteString(hash, fmt.Sprintf("%d%s%s", ts, c.private, c.public))
return ts, fmt.Sprintf("%x", hash.Sum(nil))
func (c Client) fetch(path string, params interface{}, out interface{}) error {
u := c.baseURL(path, params)
if u.RawQuery != "" {
u.RawQuery += "&"
}
ts, hash := c.hash()
u.RawQuery += url.Values(map[string][]string{
"ts": []string{fmt.Sprintf("%d", ts)},
"apikey": []string{c.public},
"hash": []string{hash},
}).Encode()
resp, err := http.Get(u.String())
if err != nil {
return err
}
if resp.StatusCode >= http.StatusBadRequest {
slurp, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
return fmt.Errorf("error response from API: %d\n%s", resp.StatusCode, slurp)
}
defer resp.Body.Close()
return json.NewDecoder(resp.Body).Decode(out)
}
func (c Client) baseURL(path string, params interface{}) url.URL {
@ -49,6 +67,14 @@ func (c Client) baseURL(path string, params interface{}) url.URL {
return u
}
// See http://developer.marvel.com/documentation/authorization
func (c Client) hash() (int64, string) {
ts := time.Now().Unix()
hash := md5.New()
io.WriteString(hash, fmt.Sprintf("%d%s%s", ts, c.private, c.public))
return ts, fmt.Sprintf("%x", hash.Sum(nil))
}
// TODO: Replace with subtypes that know what their response will be, with a Fetch() method to pull down and deserialize correctly.
type URL struct {
Type string `json:"type,omitempty"`
@ -125,51 +151,7 @@ func (d Date) Parse() time.Time {
return t
}
func (c Client) Series(id int) SeriesResource {
return SeriesResource{seriesID: id, client: c}
}
type SeriesResource struct {
seriesID int
client Client
}
func (s SeriesResource) Comics(params ComicsParams) (*ComicsResponse, error) {
u := s.client.baseURL(fmt.Sprintf("series/%d/comics", s.seriesID), params)
r, err := s.client.fetch(u)
if err != nil {
return nil, err
}
defer r.Close()
var resp ComicsResponse
err = json.NewDecoder(r).Decode(&resp)
return &resp, err
}
func (c Client) fetch(u url.URL) (io.ReadCloser, error) {
if u.RawQuery != "" {
u.RawQuery += "&"
}
ts, hash := c.hash()
u.RawQuery += url.Values(map[string][]string{
"ts": []string{fmt.Sprintf("%d", ts)},
"apikey": []string{c.public},
"hash": []string{hash},
}).Encode()
resp, err := http.Get(u.String())
if err != nil {
return nil, err
}
if resp.StatusCode >= http.StatusBadRequest {
slurp, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return nil, fmt.Errorf("error response from API: %d\n%s", resp.StatusCode, slurp)
}
return resp.Body, nil
}
type ResourceList struct {
Available int `json:"available,omitempty"`
@ -177,6 +159,56 @@ type ResourceList struct {
CollectionURI string `json:"collectionUri,omitempty"`
}
/////
// Characters
/////
func (c Client) Characters(id int) CharactersResource {
return CharactersResource{basePath: fmt.Sprintf("/characters/%d", id), client: c}
}
type CharactersResource struct {
basePath string
client Client
}
func (s CharactersResource) Comics(params ComicsParams) (resp *ComicsResponse, err error) {
err = s.client.fetch(s.basePath+"/comics", params, &resp)
return
}
func (s CharactersResource) Events(params EventsParams) (resp *EventsResponse, err error) {
err = s.client.fetch(s.basePath+"/events", params, &resp)
return
}
func (s CharactersResource) Series(params SeriesParams) (resp *SeriesResponse, err error) {
err = s.client.fetch(s.basePath+"/stories", params, &resp)
return
}
func (s CharactersResource) Stories(params StoriesParams) (resp *StoriesResponse, err error) {
err = s.client.fetch(s.basePath+"/stories", params, &resp)
return
}
type CharactersParams struct {
CommonParams
Name string `url:"name,omitempty"`
NameStartsWith string `url:"nameStartsWith,omitempty"`
Comics string `url:"comics,omitempty"`
Events string `url:"events,omitempty"`
Stories string `url:"stories,omitempty"`
}
type CharactersResponse struct {
CommonResponse
Data struct {
CommonList
Results []Character `json:"results,omitempty"`
} `json:"data,omitempty"`
}
type Character struct {
ResourceURI string `json:"resourceURI,omitempty"`
ID *int `json:"id,omitempty"`
@ -200,6 +232,35 @@ type CharactersList struct {
// Comics
/////
func (c Client) Comics(id int) ComicsResource {
return ComicsResource{basePath: fmt.Sprintf("comics/%d", id), client: c}
}
type ComicsResource struct {
basePath string
client Client
}
func (s ComicsResource) Characters(params CharactersParams) (resp *CharactersResponse, err error) {
err = s.client.fetch(s.basePath+"/characters", params, &resp)
return
}
func (s ComicsResource) Events(params EventsParams) (resp *EventsResponse, err error) {
err = s.client.fetch(s.basePath+"/events", params, &resp)
return
}
func (s ComicsResource) Series(params SeriesParams) (resp *SeriesResponse, err error) {
err = s.client.fetch(s.basePath+"/stories", params, &resp)
return
}
func (s ComicsResource) Stories(params StoriesParams) (resp *StoriesResponse, err error) {
err = s.client.fetch(s.basePath+"/stories", params, &resp)
return
}
type ComicsParams struct {
CommonParams
Format string `url:"format,omitempty"`
@ -288,6 +349,40 @@ type ComicsList struct {
// Stories
/////
func (c Client) Stories(id int) StoriesResource {
return StoriesResource{basePath: fmt.Sprintf("stories/%d", id), client: c}
}
type StoriesResource struct {
basePath string
client Client
}
func (s StoriesResource) Characters(params CharactersParams) (resp *CharactersResponse, err error) {
err = s.client.fetch(s.basePath+"/characters", params, &resp)
return
}
func (s StoriesResource) Comics(params ComicsParams) (resp *ComicsResponse, err error) {
err = s.client.fetch(s.basePath+"/comics", params, &resp)
return
}
func (s StoriesResource) Creators(params CreatorsParams) (resp *CreatorsResponse, err error) {
err = s.client.fetch(s.basePath+"/creators", params, &resp)
return
}
func (s StoriesResource) Events(params EventsParams) (resp *EventsResponse, err error) {
err = s.client.fetch(s.basePath+"/events", params, &resp)
return
}
func (s StoriesResource) Series(params SeriesParams) (resp *SeriesResponse, err error) {
err = s.client.fetch(s.basePath+"/stories", params, &resp)
return
}
type StoriesParams struct {
CommonParams
Comics string `url:"comics,omitempty"`
@ -296,6 +391,14 @@ type StoriesParams struct {
Characters string `url:"characters,omitempty"`
}
type StoriesResponse struct {
CommonResponse
Data struct {
CommonList
Results []Story `json:"results,omitempty"`
} `json:"data,omitempty"`
}
type Story struct {
ResourceURI *string `json:"resourceURI,omitempty"`
ID *int `json:"id,omitempty"`
@ -322,6 +425,40 @@ type StoriesList struct {
// Events
/////
func (c Client) Events(id int) EventsResource {
return EventsResource{basePath: fmt.Sprintf("events/%d", id), client: c}
}
type EventsResource struct {
basePath string
client Client
}
func (s EventsResource) Characters(params CharactersParams) (resp *CharactersResponse, err error) {
err = s.client.fetch(s.basePath+"/characters", params, &resp)
return
}
func (s EventsResource) Comics(params ComicsParams) (resp *ComicsResponse, err error) {
err = s.client.fetch(s.basePath+"/comics", params, &resp)
return
}
func (s EventsResource) Creators(params CreatorsParams) (resp *CreatorsResponse, err error) {
err = s.client.fetch(s.basePath+"/creators", params, &resp)
return
}
func (s EventsResource) Series(params SeriesParams) (resp *SeriesResponse, err error) {
err = s.client.fetch(s.basePath+"/stories", params, &resp)
return
}
func (s EventsResource) Stories(params StoriesParams) (resp *StoriesResponse, err error) {
err = s.client.fetch(s.basePath+"/stories", params, &resp)
return
}
type EventsParams struct {
CommonParams
Name string `url:"name,omitempty"`
@ -332,6 +469,14 @@ type EventsParams struct {
Stories string `url:"stories,omitempty"`
}
type EventsResponse struct {
CommonResponse
Data struct {
CommonList
Results []Event `json:"results,omitempty"`
} `json:"data,omitempty"`
}
type Event struct {
ResourceURI *string `json:"resourceURI,omitempty"`
ID *int `json:"id,omitempty"`
@ -360,6 +505,40 @@ type EventsList struct {
// Series
/////
func (c Client) Series(id int) SeriesResource {
return SeriesResource{basePath: fmt.Sprintf("/series/%d", id), client: c}
}
type SeriesResource struct {
basePath string
client Client
}
func (s SeriesResource) Characters(params CharactersParams) (resp *CharactersResponse, err error) {
err = s.client.fetch(s.basePath+"/characters", params, resp)
return
}
func (s SeriesResource) Comics(params ComicsParams) (resp *ComicsResponse, err error) {
err = s.client.fetch(s.basePath+"/comics", params, &resp)
return
}
func (s SeriesResource) Creators(params CreatorsParams) (resp *CreatorsResponse, err error) {
err = s.client.fetch(s.basePath+"/creators", params, &resp)
return
}
func (s SeriesResource) Events(params EventsParams) (resp *EventsResponse, err error) {
err = s.client.fetch(s.basePath+"/events", params, &resp)
return
}
func (s SeriesResource) Stories(params StoriesParams) (resp *StoriesResponse, err error) {
err = s.client.fetch(s.basePath+"/stories", params, &resp)
return
}
type SeriesParams struct {
CommonParams
Events string `url:"events,omitempty"`
@ -373,6 +552,14 @@ type SeriesParams struct {
Characters string `url:"characters,omitempty"`
}
type SeriesResponse struct {
CommonResponse
Data struct {
CommonList
Results []Series `json:"results,omitempty"`
} `json:"data,omitempty"`
}
type Series struct {
ResourceURI *string `json:"resourceURI,omitempty"`
ID *int `json:"id,omitempty"`
@ -403,6 +590,35 @@ type SeriesList struct {
// Creators
/////
func (c Client) Creators(id int) CreatorsResource {
return CreatorsResource{basePath: fmt.Sprintf("/creators/%d", id), client: c}
}
type CreatorsResource struct {
basePath string
client Client
}
func (s CreatorsResource) Comics(params ComicsParams) (resp *ComicsResponse, err error) {
err = s.client.fetch(s.basePath+"/comics", params, &resp)
return
}
func (s CreatorsResource) Events(params EventsParams) (resp *EventsResponse, err error) {
err = s.client.fetch(s.basePath+"/events", params, &resp)
return
}
func (s CreatorsResource) Series(params SeriesParams) (resp *SeriesResponse, err error) {
err = s.client.fetch(s.basePath+"/series", params, &resp)
return
}
func (s CreatorsResource) Stories(params StoriesParams) (resp *StoriesResponse, err error) {
err = s.client.fetch(s.basePath+"/stories", params, &resp)
return
}
type CreatorsParams struct {
CommonParams
FirstName string `url:"firstName,omitempty"`
@ -418,6 +634,14 @@ type CreatorsParams struct {
Stories string `url:"stories,omitempty"`
}
type CreatorsResponse struct {
CommonResponse
Data struct {
CommonList
Results []Creator `json:"results,omitempty"`
} `json:"data,omitempty"`
}
type Creator struct {
ResourceURI *string `json:"resourceURI,omitempty"`
ID *int `json:"id,omitempty"`