Advertisement
Guest User

gombta.go

a guest
Sep 13th, 2015
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 3.54 KB | None | 0 0
  1. /*
  2. Package gombta is a MBTA v2 client written for the Go programming language
  3.  
  4. Sep 2015
  5. */
  6. package gombta
  7.  
  8. import (
  9.     "encoding/json"
  10.     "fmt"
  11.     "net/http"
  12.     "net/url"
  13.     "os"
  14. )
  15.  
  16. //Client interacts with the services provided by MBTA
  17. type Client struct {
  18.     APIKey string // private API key
  19.     URL    string // MBTA URL, probably ends with .../v2/. Must end in '/'.
  20. }
  21.  
  22. //AllRoutes is base return of MBTA All Route Call
  23. //When making MBTA Route Call it returns nested JSON
  24. //This block supports the nesting
  25. type AllRoutes struct {
  26.     Mode []struct {
  27.         RouteType string `json:"route_type"`
  28.         ModeName  string `json:"mode_name"`
  29.         Route     []struct {
  30.             RouteID   string `json:"route_id"`
  31.             RouteName string `json:"route_name"`
  32.         } `json:"route"`
  33.     } `json:"mode"`
  34. }
  35.  
  36. //
  37. //
  38. // END BLOCK
  39. //
  40. //
  41.  
  42. // ClientError is a generic error specific to the `gombta` package.
  43. type ClientError struct {
  44.     msg string
  45. }
  46.  
  47. // Error returns a string representation of the error condition.
  48. func (c ClientError) Error() string {
  49.     return c.msg
  50. }
  51.  
  52. // UseDefaultURL configures a `Client` to use the default public
  53. //   MBTA URL published on their website.
  54. func (c *Client) UseDefaultURL() {
  55.     c.URL = "http://realtime.mbta.com/developer/api/v2/"
  56. }
  57.  
  58. // checkApiKey ensures that the user configured her API key,
  59. //   or returns an error.
  60. func (c *Client) checkAPIKey() (err error) {
  61.     if c.APIKey == "" {
  62.         return ClientError{msg: "Empty API key is invalid"}
  63.     }
  64.     return nil
  65. }
  66.  
  67. // makeAPIGetRequest fetches a URL with querystring via HTTP GET and
  68. //  returns the response if the status code is HTTP 200
  69. // `parameters` should not include the apikey.
  70. // The caller must call `resp.Body.Close()`.
  71. func (c *Client) makeAPIGetRequest(fullurl string, parameters map[string]string) (resp *http.Response, err error) {
  72.     if err = c.checkAPIKey(); err != nil {
  73.         return resp, err
  74.     }
  75.  
  76.     values := url.Values{}
  77.     values.Set("api_key", c.APIKey)
  78.     for k, v := range parameters {
  79.         values.Add(k, v)
  80.     }
  81.  
  82.     httpClient := http.Client{}
  83.     // TODO(wb) check if final character is ?, or if ? already exists
  84.     req, err := http.NewRequest("GET", fullurl+"?"+values.Encode(), nil)
  85.     if err != nil {
  86.         return resp, err
  87.     }
  88.  
  89.     resp, err = httpClient.Do(req)
  90.     if err != nil {
  91.         return resp, err
  92.     }
  93.  
  94.     if resp.StatusCode != 200 {
  95.         var msg = fmt.Sprintf("Unexpected status code: %d", resp.StatusCode)
  96.         resp.Write(os.Stdout)
  97.         return resp, ClientError{msg: msg}
  98.     }
  99.  
  100.     return resp, nil
  101. }
  102.  
  103. //Parameters st
  104. type Parameters map[string]string
  105.  
  106. // fetchAPIJSON makes a request to the API and decodes the response.
  107. // `method` is one of "GET" -- "POST", or "FILE" are in govt if you need to figure out how to do it
  108. // `actionurl` is the final path component that specifies the API call
  109. // `parameters` does not include the API key
  110. // `result` is modified as an output parameter. It must be a pointer to a MBTA JSON structure.
  111. func (c *Client) fetchAPIJSON(method string, actionurl string, parameters Parameters, result interface{}) (err error) {
  112.     theurl := c.URL + actionurl
  113.     var resp *http.Response
  114.     switch method {
  115.     case "GET":
  116.         resp, err = c.makeAPIGetRequest(theurl, parameters)
  117.     }
  118.     if err != nil {
  119.         return err
  120.     }
  121.     defer resp.Body.Close()
  122.  
  123.     dec := json.NewDecoder(resp.Body)
  124.     if err = dec.Decode(result); err != nil {
  125.         return err
  126.     }
  127.  
  128.     return nil
  129. }
  130.  
  131. // GetRoutes fetches all of the Routes from MBTA
  132. func (c *Client) GetRoutes(format string) (r *AllRoutes, err error) {
  133.     r = &AllRoutes{}
  134.     err = c.fetchAPIJSON("GET", "routes", Parameters{"format": format}, r)
  135.     return r, err
  136. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement