bitly-oauth 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/History.txt +154 -0
  2. data/LICENSE +20 -0
  3. data/README.md +87 -0
  4. data/README.rdoc +35 -0
  5. data/Rakefile +42 -0
  6. data/VERSION +1 -0
  7. data/lib/bitly_oauth.rb +28 -0
  8. data/lib/bitly_oauth/access_token.rb +37 -0
  9. data/lib/bitly_oauth/client.rb +149 -0
  10. data/lib/bitly_oauth/country.rb +10 -0
  11. data/lib/bitly_oauth/day.rb +12 -0
  12. data/lib/bitly_oauth/error.rb +15 -0
  13. data/lib/bitly_oauth/lib/core_ext/hash.rb +27 -0
  14. data/lib/bitly_oauth/lib/core_ext/string.rb +5 -0
  15. data/lib/bitly_oauth/missing_url.rb +12 -0
  16. data/lib/bitly_oauth/realtime_link.rb +16 -0
  17. data/lib/bitly_oauth/referrer.rb +12 -0
  18. data/lib/bitly_oauth/referring_domain.rb +11 -0
  19. data/lib/bitly_oauth/response.rb +39 -0
  20. data/lib/bitly_oauth/url.rb +118 -0
  21. data/lib/bitly_oauth/user.rb +104 -0
  22. data/test/fixtures/9uX1TE.json +1 -0
  23. data/test/fixtures/9uX1TEclicks.json +1 -0
  24. data/test/fixtures/9uX1TEclicks2.json +1 -0
  25. data/test/fixtures/9uX1TEinfo.json +1 -0
  26. data/test/fixtures/9uX1TEinfo2.json +1 -0
  27. data/test/fixtures/auth_fail.json +1 -0
  28. data/test/fixtures/auth_success.json +1 -0
  29. data/test/fixtures/betaworks.json +1 -0
  30. data/test/fixtures/betaworks2.json +1 -0
  31. data/test/fixtures/betaworks_jmp.json +1 -0
  32. data/test/fixtures/betaworks_other_user.json +1 -0
  33. data/test/fixtures/bitly9uX1TE.json +1 -0
  34. data/test/fixtures/bitly_pro_domain.json +1 -0
  35. data/test/fixtures/clicks_by_day.json +1 -0
  36. data/test/fixtures/clicks_by_day1.json +1 -0
  37. data/test/fixtures/clicks_by_day2.json +1 -0
  38. data/test/fixtures/clicks_by_minute1_url.json +1 -0
  39. data/test/fixtures/clicks_by_minute2_url.json +1 -0
  40. data/test/fixtures/clicks_by_minute_hash.json +1 -0
  41. data/test/fixtures/clicks_by_minute_hashes.json +1 -0
  42. data/test/fixtures/country_hash.json +1 -0
  43. data/test/fixtures/country_hash2.json +1 -0
  44. data/test/fixtures/country_url.json +1 -0
  45. data/test/fixtures/failure.json +1 -0
  46. data/test/fixtures/invalid_bitly_pro_domain.json +1 -0
  47. data/test/fixtures/invalid_credentials.json +1 -0
  48. data/test/fixtures/invalid_domain.json +1 -0
  49. data/test/fixtures/invalid_user.json +1 -0
  50. data/test/fixtures/invalid_x_api_key.json +1 -0
  51. data/test/fixtures/lookup_multiple_url.json +1 -0
  52. data/test/fixtures/lookup_not_real_url.json +1 -0
  53. data/test/fixtures/lookup_single_url.json +1 -0
  54. data/test/fixtures/missing_hash.json +1 -0
  55. data/test/fixtures/multiple_info.json +1 -0
  56. data/test/fixtures/multiple_url_click.json +1 -0
  57. data/test/fixtures/multiple_urls.json +1 -0
  58. data/test/fixtures/not_bitly_pro_domain.json +1 -0
  59. data/test/fixtures/not_found_info.json +1 -0
  60. data/test/fixtures/referrer_hash.json +1 -0
  61. data/test/fixtures/referrer_hash2.json +1 -0
  62. data/test/fixtures/referrer_url.json +1 -0
  63. data/test/fixtures/success.json +1 -0
  64. data/test/fixtures/url_info.json +1 -0
  65. data/test/fixtures/user_clicks.json +32 -0
  66. data/test/fixtures/user_countries.json +60 -0
  67. data/test/fixtures/user_realtime_links.json +15 -0
  68. data/test/fixtures/user_referrers.json +1 -0
  69. data/test/fixtures/valid_user.json +1 -0
  70. data/test/integration/strategy/old_test_api_key.rb +20 -0
  71. data/test/integration/test_client.rb +709 -0
  72. data/test/integration/test_user.rb +97 -0
  73. data/test/test_helper.rb +54 -0
  74. data/test/unit/core_ext/test_hash.rb +69 -0
  75. data/test/unit/core_ext/test_string.rb +14 -0
  76. data/test/unit/test_bitly_oauth.rb +19 -0
  77. data/test/unit/test_client.rb +87 -0
  78. data/test/unit/test_country.rb +19 -0
  79. data/test/unit/test_day.rb +22 -0
  80. data/test/unit/test_error.rb +11 -0
  81. data/test/unit/test_missing.rb +34 -0
  82. data/test/unit/test_realtime_link.rb +30 -0
  83. data/test/unit/test_referrer.rb +19 -0
  84. data/test/unit/test_referring_domain.rb +21 -0
  85. data/test/unit/test_response.rb +86 -0
  86. data/test/unit/test_url.rb +156 -0
  87. data/test/unit/test_user.rb +17 -0
  88. metadata +215 -0
data/History.txt ADDED
@@ -0,0 +1,154 @@
1
+ === 0.1.0 / 2012-1-21
2
+ * Rename Project to BitlyOAuth
3
+
4
+ * Remove Login and ApiKey Authentication
5
+ * Remove strategies
6
+ * Rollback version to 0.1.0
7
+ * Add Referring Domains Endpoint
8
+
9
+ === 0.8.0 / 2012-1-17
10
+
11
+ * Major Refactor
12
+
13
+ * Adds Authentication Strategies
14
+ * Client supports OAuth & Login/ApiKey strategies
15
+ * User supports AccessToken strategy
16
+ * Forked original project. Pull requests in original project showed no movement.
17
+
18
+ === 0.7.0 / 2011-1-8
19
+
20
+ * 1 major bug fix
21
+
22
+ * Updates OAuth2 gem and fixes OAuth class
23
+
24
+ * 1 minor enhancement
25
+
26
+ Adds link_history to user model
27
+
28
+ === 0.6.2 / 2011-11-10
29
+
30
+ * 2 minor enhancements
31
+
32
+ * Adds days parameter to clicks_by_minute v3 API call
33
+ * Converts Readme to markdown
34
+
35
+ * 2 minor bug fixes
36
+
37
+ * Increases HTTParty version to avoid issues with Rubygems
38
+ * Stops mutating arguments on array methods
39
+
40
+ === 0.6.1 / 2011-01-12
41
+
42
+ * 1 minor enhancement
43
+
44
+ * Updated OAuth2 gem and used extra information to save login and api_key to user objects
45
+
46
+ === 0.6.0 / 2011-01-03
47
+
48
+ * 1 major enhancement
49
+
50
+ * Added OAuth 2 and User calls for the version 3 API
51
+
52
+ === 0.5.5 / 2010-12-22
53
+
54
+ * 1 minor bug fix
55
+
56
+ * fixed method redifined warnings
57
+
58
+ === 0.5.4 / 2010-12-01
59
+
60
+ * 4 minor enhancements
61
+
62
+ * Added referrers, countries, clicks_by_minute and clicks_by_day calls to the version 3 API
63
+
64
+ === 0.5.3 / 2010-07-30
65
+
66
+ * 1 minor enhancement
67
+
68
+ * Added the info call to the version 3 API
69
+
70
+ === 0.5.2 / 2010-07-18
71
+
72
+ * 1 minor enhancement
73
+
74
+ * Added the lookup call to the version 3 API.
75
+
76
+ === 0.5.1 / 2010-05-26
77
+
78
+ * 1 bug fix
79
+
80
+ * When expanding a short url with the v3 module, user hash and short url weren't being set properly
81
+
82
+ === 0.5.0 / 2010-05-12
83
+
84
+ * Loads of major enhancements
85
+
86
+ * Support for version 3 of the bit.ly API
87
+ * deprecation for version 2 client object
88
+
89
+ === 0.4.0 / 2009-12-19
90
+
91
+ * 1 major enhancement
92
+
93
+ * support for j.mp urls
94
+
95
+ === 0.3.2 / 2009-11-15
96
+
97
+ * 1 bug fix
98
+
99
+ * called the wrong variable in case of error in the creation of a Url object
100
+
101
+ === 0.3.1 / 2009-07-29
102
+
103
+ * 1 minor enhancement
104
+
105
+ * removed require 'rubygems' from library (http://gist.github.com/54177)
106
+
107
+ === 0.3 / 2009-07-09
108
+
109
+ * 1 major enhancement
110
+
111
+ * a full set of tests, properly mocked
112
+
113
+ * 1 minor enhancement
114
+
115
+ * calling bitly.shorten(:history => 1) will add the url to the api user's history.
116
+
117
+ * 1 bug fix
118
+
119
+ * you can no longer call shorten with a keyword, this was unsupported in the API and consequently removed
120
+
121
+ === 0.2 / 2009-06-23
122
+
123
+ * 1 enhancement
124
+
125
+ * Depends on Crack instead of JSON, so can run on Jruby
126
+
127
+ * 1 bug fix
128
+
129
+ * Does not choke when bit.ly chokes. Returns a BitlyError instead
130
+
131
+ === 0.1.4 / 2009-04-13
132
+
133
+ * 1 bug fix
134
+
135
+ * Urls with parameters were choking, changed to using CGI.
136
+
137
+ === 0.1.2 / 2009-03-12
138
+
139
+ * 1 minor enhancement
140
+
141
+ * Allows to add a keyword for shortening urls
142
+
143
+ === 0.1.1 / 2009-01-26
144
+
145
+ * 1 bug fix
146
+
147
+ * Didn't include dependency on JSON
148
+
149
+ === 0.1.0 / 2009-01-26
150
+
151
+ * 1 major enhancement
152
+
153
+ * First release
154
+
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 jonstorer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # bitly-oauth
2
+
3
+ ## DESCRIPTION:
4
+
5
+ A Ruby API for [http://bit.ly](http://bit.ly)
6
+
7
+ [http://code.google.com/p/bitly-api/wiki/ApiDocumentation](http://code.google.com/p/bitly-api/wiki/ApiDocumentation)
8
+
9
+ ## NOTE:
10
+
11
+ BitlyOAuth supports version 3 of the API as well as OAuth authenticate for user access.
12
+
13
+ To use, you will need a client id and client secret. Get yours at [http://bitly.com/a/account](http://bitly.com/a/account).
14
+
15
+ client = BitlyOAuth::Client.new(client_id, client_secret)
16
+
17
+ With a ``BitlyOAuth::Client`` you have access to the following API endpoints:
18
+ ``shorten``, ``expand``, ``lookup``, ``info``, ``clicks``, ``clicks_by_minute``,
19
+ ``clicks_by_day``, ``countries``, ``referrers``, ``referring_domains``,
20
+ ``validate``, ``bitly_pro_domain`` See [http://bit.ly/apidocs](http://bit.ly/apidocs) for details.
21
+
22
+ ## INSTALLATION:
23
+
24
+ gem install bitly-oauth
25
+
26
+ ## USAGE:
27
+
28
+ Please see the Bit.ly API documentation [http://bit.ly/apidocs](http://bit.ly/apidocs) for details on the V3 API.
29
+
30
+ You can initialize a client through the following shortcut as well:
31
+
32
+ client = BitlyOAuth.new("client id", "client secret")
33
+ client.set_access_token_from_token('token')
34
+
35
+ You can then use that client to shorten or expand urls or return more information or statistics as so:
36
+
37
+ client.shorten('http://www.google.com')
38
+ client.shorten('http://www.google.com', :history => 1) # adds the url to the api user's history
39
+
40
+ client.expand('wQaT') || client.expand('http://bit.ly/wQaT')
41
+ client.info('wQaT') || client.info('http://bit.ly/wQaT')
42
+ client.stats('wQaT') || client.stats('http://bit.ly/wQaT')
43
+
44
+ Each can be used in all the methods described in the API docs, the shorten function, for example, takes a url or an array of urls.
45
+
46
+ Then functions ``shorten``, ``expand``, ``info``, and ``stats`` return a ``BitlyOAuth::Url`` object (or an array of ``BitlyOAuth::Url`` objects if you supplied an array as the input). You can then get all the information required from that object.
47
+
48
+ url = client.shorten('http://www.google.com') #=> BitlyOAuth::Url
49
+
50
+ url.clicks_by_day #=> an array of ``BitlyOAuth::Day``s
51
+ url.countries #=> an array of ``BitlyOAuth::Country``s
52
+ url.referrers #=> an array of ``BitlyOAuth::Referrer``s
53
+ url.clicks_by_minute #=> an array of 60 integers representing click counts over the last 60 minutes
54
+ url.created_by #=> string / http://bit.ly/apidocs#/v3/info
55
+ url.global_clicks #=> integer / http://bit.ly/apidocs#/v3/clicks
56
+ url.global_hash #=> string / http://bit.ly/apidocs#/v3/info
57
+ url.long_url #=> string / http://bit.ly/apidocs#/v3/expand
58
+ url.new_hash? #=> boolean / http://bit.ly/apidocs#/v3/shorten
59
+ url.short_url #=> string / http://bit.ly/apidocs#/v3/shorten
60
+ url.title #=> string / http://bit.ly/apidocs#/v3/info
61
+ url.user_clicks #=> integer / http://bit.ly/apidocs#/v3/clicks
62
+ url.user_hash #=> string / http://bit.ly/apidocs#/v3/expand
63
+
64
+ ## LICENSE:
65
+
66
+ > (The MIT License)
67
+ >
68
+ > Copyright (c) 2012 Jonathon Storer
69
+ >
70
+ > Permission is hereby granted, free of charge, to any person obtaining
71
+ > a copy of this software and associated documentation files (the
72
+ > 'Software'), to deal in the Software without restriction, including
73
+ > without limitation the rights to use, copy, modify, merge, publish,
74
+ > distribute, sublicense, and/or sell copies of the Software, and to
75
+ > permit persons to whom the Software is furnished to do so, subject to
76
+ > the following conditions:
77
+ >
78
+ > The above copyright notice and this permission notice shall be
79
+ > included in all copies or substantial portions of the Software.
80
+ >
81
+ > THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
82
+ > EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
83
+ > MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
84
+ > IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
85
+ > CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
86
+ > TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
87
+ > SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,35 @@
1
+ = bitly
2
+
3
+ == DESCRIPTION:
4
+
5
+ A Ruby API for version 3 of the http://bit.ly API, including j.mp and bitly.Pro support.
6
+
7
+ http://api.bit.ly
8
+
9
+ == INSTALLATION:
10
+
11
+ <tt>gem install bitly-oauth</tt>
12
+
13
+ == USAGE:
14
+
15
+ Create a client using your client id and client secret from http://bit.ly
16
+
17
+ <tt>client = BitlyOAuth.new(client_id, client_secret)</tt>
18
+
19
+ Then use that client to shorten or expand urls and hashes.
20
+
21
+ <tt>client.shorten('http://google.com')</tt>
22
+
23
+ == Note on Patches/Pull Requests
24
+
25
+ * Fork the project.
26
+ * Make your feature addition or bug fix.
27
+ * Add tests for it. This is important so I don't break it in a
28
+ future version unintentionally.
29
+ * Commit, do not mess with rakefile, version, or history.
30
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
31
+ * Send me a pull request. Bonus points for topic branches.
32
+
33
+ == Copyright
34
+
35
+ Copyright (c) 2010 jonstorer. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,42 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'jeweler'
4
+
5
+ Jeweler::Tasks.new do |gem|
6
+ gem.name = "bitly-oauth"
7
+ gem.summary = "A ruby wrapper for the bit.ly API"
8
+ gem.description = <<-DESCRIPTION
9
+ A ruby wrapper for version 3 of the bit.ly API
10
+ Supports OAuth authentication
11
+ DESCRIPTION
12
+ gem.email = "jonathon.scott.storer@gmail.com"
13
+ gem.homepage = "http://github.com/jonstorer/bitly-oauth"
14
+ gem.authors = ["jonstorer"]
15
+ gem.add_dependency 'httparty', ">= 0.7.6"
16
+ gem.add_dependency 'oauth2', '>= 0.1.1'
17
+ gem.add_development_dependency "shoulda", ">= 0"
18
+ gem.add_development_dependency "jeweler", ">= 1.4.0"
19
+ gem.add_development_dependency "rcov", ">= 0"
20
+ gem.add_development_dependency "mocha", ">= 0.10.0"
21
+ gem.add_development_dependency "fakeweb", ">= 1.2.8"
22
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
23
+ end
24
+
25
+ require 'rake/testtask'
26
+ Rake::TestTask.new(:test) do |test|
27
+ test.libs << 'lib' << 'test'
28
+ test.pattern = 'test/**/test_*.rb'
29
+ test.verbose = true
30
+ end
31
+
32
+ task :default => :test
33
+
34
+ require 'rake/rdoctask'
35
+ Rake::RDocTask.new do |rdoc|
36
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
37
+
38
+ rdoc.rdoc_dir = 'rdoc'
39
+ rdoc.title = "bitly-oauth #{version}"
40
+ rdoc.rdoc_files.include('README*')
41
+ rdoc.rdoc_files.include('lib/**/*.rb')
42
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,28 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'httparty'
4
+ require 'oauth2'
5
+ require 'cgi'
6
+ require 'forwardable'
7
+
8
+ module BitlyOAuth
9
+ def self.new(*args)
10
+ BitlyOAuth::Client.new(*args)
11
+ end
12
+ end
13
+
14
+ require 'bitly_oauth/access_token'
15
+ require 'bitly_oauth/client'
16
+ require 'bitly_oauth/country'
17
+ require 'bitly_oauth/day'
18
+ require 'bitly_oauth/error'
19
+ require 'bitly_oauth/missing_url'
20
+ require 'bitly_oauth/realtime_link'
21
+ require 'bitly_oauth/referring_domain'
22
+ require 'bitly_oauth/referrer'
23
+ require 'bitly_oauth/response'
24
+ require 'bitly_oauth/url'
25
+ require 'bitly_oauth/user'
26
+
27
+ require 'bitly_oauth/lib/core_ext/hash'
28
+ require 'bitly_oauth/lib/core_ext/string'
@@ -0,0 +1,37 @@
1
+ module BitlyOAuth
2
+ class AccessToken
3
+ extend Forwardable
4
+ delegate [ :client, :token ] => :access_token
5
+
6
+ def initialize(access_token)
7
+ @access_token = access_token
8
+ end
9
+
10
+ def get(method, options)
11
+ request(:get, method, options)
12
+ end
13
+
14
+ def post(method, options)
15
+ request(:post, method, options)
16
+ end
17
+
18
+ private
19
+ def request(verb, method, options={})
20
+ response = access_token.send(verb, method, :params => params(options), :parse => :json)
21
+ response = BitlyOAuth::Response.new(response)
22
+ if response.success?
23
+ response.body
24
+ else
25
+ raise BitlyOAuth::Error.new(response)
26
+ end
27
+ end
28
+
29
+ def params(options={})
30
+ { :access_token => access_token.token }.merge(options)
31
+ end
32
+
33
+ def access_token
34
+ @access_token
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,149 @@
1
+ module BitlyOAuth
2
+ class Client
3
+ extend Forwardable
4
+ delegate [ :get, :post ] => :access_token
5
+
6
+ BASE_URL = 'https://api-ssl.bit.ly/v3/'
7
+
8
+ def initialize(client_id, client_secret)
9
+ @client_id = client_id
10
+ @client_secret = client_secret
11
+ end
12
+
13
+ def authorize_url(redirect_url)
14
+ client.auth_code.authorize_url(:redirect_uri => redirect_url).gsub(/api-ssl.bit.ly/,'bitly.com')
15
+ end
16
+
17
+ def get_access_token_from_code(code, redirect_url)
18
+ access_token = client.auth_code.get_token(code, :redirect_uri => redirect_url, :parse => :query)
19
+ BitlyOAuth::AccessToken.new(access_token)
20
+ end
21
+
22
+ def set_access_token_from_code(*args)
23
+ @access_token ||= get_access_token_from_code(*args)
24
+ end
25
+
26
+ def get_access_token_from_token(token, params={})
27
+ params.stringify_keys!
28
+ access_token = ::OAuth2::AccessToken.new(client, token, params)
29
+ BitlyOAuth::AccessToken.new(access_token)
30
+ end
31
+
32
+ def set_access_token_from_token(*args)
33
+ @access_token ||= get_access_token_from_token(*args)
34
+ end
35
+
36
+ def bitly_pro_domain(domain)
37
+ get(:bitly_pro_domain, :domain => domain)['bitly_pro_domain']
38
+ end
39
+ alias :pro? :bitly_pro_domain
40
+
41
+ # Validates a login and api key
42
+ def validate(x_login, x_api_key)
43
+ get(:validate, :x_login => x_login, :x_apiKey => x_api_key)['valid'] == 1
44
+ end
45
+ alias :valid? :validate
46
+
47
+ def shorten(long_url, options={})
48
+ response = get(:shorten, { :longUrl => long_url }.merge(options))
49
+ BitlyOAuth::Url.new(self, response)
50
+ end
51
+
52
+ def expand(input)
53
+ get_method(:expand, input)
54
+ end
55
+
56
+ def clicks(input)
57
+ get_method(:clicks, input)
58
+ end
59
+
60
+ def info(input)
61
+ get_method(:info, input)
62
+ end
63
+
64
+ def clicks_by_minute(input)
65
+ get_method(:clicks_by_minute, input)
66
+ end
67
+
68
+ def clicks_by_day(input, options={})
69
+ options.reject! { |k, v| k.to_s != 'days' }
70
+ get_method(:clicks_by_day, input, options)
71
+ end
72
+
73
+ def countries(input)
74
+ get_single_method(:countries, input)
75
+ end
76
+
77
+ def referrers(input)
78
+ get_single_method(:referrers, input)
79
+ end
80
+
81
+ def referring_domains(link, options={})
82
+ response = get('link/referring_domains', :link => link)
83
+ response['referring_domains'].map do |referring_domain|
84
+ BitlyOAuth::ReferringDomain.new(referring_domain)
85
+ end
86
+ end
87
+
88
+ def lookup(input)
89
+ input = input.to_a
90
+ response = get(:lookup, :url => input)
91
+ results = response['lookup'].inject([]) do |results, url|
92
+ index = input.index(url['long_url'] = url.delete('url'))
93
+ if url['error'].nil?
94
+ results[index] = BitlyOAuth::Url.new(self, url)
95
+ else
96
+ results[index] = BitlyOAuth::MissingUrl.new(url)
97
+ end
98
+ input[index] = nil
99
+ results
100
+ end
101
+ results.length > 1 ? results : results[0]
102
+ end
103
+
104
+ private
105
+
106
+ def get_method(method, input, options={})
107
+ options.symbolize_keys!
108
+ input = input.to_a
109
+
110
+ input.each do |i|
111
+ (options[key_for(i)] ||= []) << i
112
+ end
113
+
114
+ response = get(method, options)
115
+
116
+ results = response[method.to_s].inject([]) do |results, url|
117
+ result_index = input.index(url['short_url'] || url['hash']) || input.index(url['global_hash'])
118
+
119
+ if url['error'].nil?
120
+ results[result_index] = BitlyOAuth::Url.new(self, url)
121
+ else
122
+ results[result_index] = BitlyOAuth::MissingUrl.new(url)
123
+ end
124
+ input[result_index] = nil
125
+ results
126
+ end
127
+ results.length > 1 ? results : results[0]
128
+ end
129
+
130
+ def get_single_method(method, input)
131
+ raise ArgumentError.new("This method only takes a hash or url input") unless input.is_a? String
132
+
133
+ response = get(method, key_for(input) => input.to_a)
134
+ BitlyOAuth::Url.new(self, response)
135
+ end
136
+
137
+ def client
138
+ @client ||= ::OAuth2::Client.new(@client_id, @client_secret, :site => BASE_URL, :token_url => '/oauth/access_token')
139
+ end
140
+
141
+ def access_token
142
+ @access_token
143
+ end
144
+
145
+ def key_for(input)
146
+ input.match(/^http:\/\//) ? :shortUrl : :hash
147
+ end
148
+ end
149
+ end