Guest User

Untitled

a guest
Dec 14th, 2017
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.02 KB | None | 0 0
  1. import (
  2. "encoding/json"
  3. "fmt"
  4. "net/http"
  5. "net/url"
  6. "strings"
  7. )
  8.  
  9. var baseURL *url.URL
  10.  
  11. func init() {
  12. var err error
  13. baseURL, err = url.Parse("https://www.googleapis.com/urlshortener/v1/url")
  14. if err != nil {
  15. panic(err)
  16. }
  17. }
  18.  
  19. // GoogleShortener communicates with the Google URL shortener API.
  20. type GoogleShortener struct {
  21. APIKey string
  22. }
  23.  
  24. func (shortener *GoogleShortener) addAPIKey(query *url.Values) {
  25. if shortener.APIKey != "" {
  26. query.Set("key", shortener.APIKey)
  27. }
  28. }
  29.  
  30. // GoogleShortenerError represents an error returned by the Google URL shortener API.
  31. type GoogleShortenerError struct {
  32. Code int
  33. Message string
  34. Errors map[string]interface{}
  35. }
  36.  
  37. func (e GoogleShortenerError) Error() string {
  38. return fmt.Sprintf("Google URL shortener reported failure: %s", e.Message)
  39. }
  40.  
  41. type shortenResponse struct {
  42. ShortURL string `json:"id,ommitempty"`
  43. Error GoogleShortenerError `json:"error,ommitempty"`
  44. }
  45.  
  46. type expandResponse struct {
  47. LongURL string `json:"longUrl,ommitempty"`
  48. Error GoogleShortenerError `json:"error,ommitempty"`
  49. }
  50.  
  51. // Shorten requests the short URL of longURL.
  52. func (shortener *GoogleShortener) Shorten(longURL *url.URL) (*url.URL, error) {
  53. u := baseURL
  54. query := url.Values{}
  55. shortener.addAPIKey(&query)
  56. u.RawQuery = query.Encode()
  57.  
  58. payload := url.Values{}
  59. payload.Set("longUrl", longURL.String())
  60. resp, err := http.Post(u.String(), "application/x-www-form-urlencoded", strings.NewReader(payload.Encode()))
  61. if err != nil {
  62. return nil, err
  63. }
  64. defer resp.Body.Close()
  65.  
  66. dec := json.NewDecoder(resp.Body)
  67. var res shortenResponse
  68. err = dec.Decode(&res)
  69. if err != nil {
  70. return nil, err
  71. }
  72. if resp.StatusCode != http.StatusOK {
  73. if res.Error.Code == 0 {
  74. res.Error.Code = resp.StatusCode
  75. }
  76. return nil, res.Error
  77. }
  78. shortURL, err := url.Parse(res.ShortURL)
  79. if err != nil {
  80. return nil, err
  81. }
  82. return shortURL, nil
  83. }
  84.  
  85. // Expand determines the long URL of shortURL.
  86. func (shortener *GoogleShortener) Expand(shortURL *url.URL) (*url.URL, error) {
  87. u := baseURL
  88. query := url.Values{}
  89. query.Set("shortUrl", shortURL.String())
  90. shortener.addAPIKey(&query)
  91. u.RawQuery = query.Encode()
  92.  
  93. resp, err := http.Get(u.String())
  94. if err != nil {
  95. return nil, err
  96. }
  97. defer resp.Body.Close()
  98.  
  99. dec := json.NewDecoder(resp.Body)
  100. var res expandResponse
  101. err = dec.Decode(&res)
  102. if err != nil {
  103. return nil, err
  104. }
  105. if resp.StatusCode != http.StatusOK {
  106. if res.Error.Code == 0 {
  107. res.Error.Code = resp.StatusCode
  108. }
  109. return nil, res.Error
  110. }
  111. longURL, err := url.Parse(res.LongURL)
  112. if err != nil {
  113. return nil, err
  114. }
  115. return longURL, nil
  116. }
  117.  
  118. // NewGoogleShortener returns a with the given API key configured GoogleShortener.
  119. func NewGoogleShortener(apiKey string) *GoogleShortener {
  120. return &GoogleShortener{apiKey}
  121. }
Add Comment
Please, Sign In to add comment