bitly 1.1.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +36 -3
  3. data/.rspec +3 -0
  4. data/.travis.yml +6 -2
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +5 -2
  7. data/History.txt +32 -1
  8. data/LICENSE.md +1 -1
  9. data/README.md +151 -58
  10. data/Rakefile +6 -9
  11. data/bitly.gemspec +36 -32
  12. data/config/env.yml.example +5 -0
  13. data/lib/bitly.rb +9 -7
  14. data/lib/bitly/api.rb +19 -0
  15. data/lib/bitly/api/base.rb +23 -0
  16. data/lib/bitly/api/bitlink.rb +342 -0
  17. data/lib/bitly/api/bitlink/clicks_summary.rb +35 -0
  18. data/lib/bitly/api/bitlink/deeplink.rb +29 -0
  19. data/lib/bitly/api/bitlink/link_click.rb +75 -0
  20. data/lib/bitly/api/bitlink/paginated_list.rb +52 -0
  21. data/lib/bitly/api/bsd.rb +24 -0
  22. data/lib/bitly/api/click_metric.rb +186 -0
  23. data/lib/bitly/api/client.rb +588 -0
  24. data/lib/bitly/api/group.rb +232 -0
  25. data/lib/bitly/api/group/preferences.rb +73 -0
  26. data/lib/bitly/api/list.rb +22 -0
  27. data/lib/bitly/api/oauth_app.rb +26 -0
  28. data/lib/bitly/api/organization.rb +104 -0
  29. data/lib/bitly/api/shorten_counts.rb +61 -0
  30. data/lib/bitly/api/user.rb +107 -0
  31. data/lib/bitly/error.rb +33 -0
  32. data/lib/bitly/http.rb +10 -0
  33. data/lib/bitly/http/adapters.rb +9 -0
  34. data/lib/bitly/http/adapters/net_http.rb +27 -0
  35. data/lib/bitly/http/client.rb +33 -0
  36. data/lib/bitly/http/request.rb +118 -0
  37. data/lib/bitly/http/response.rb +66 -0
  38. data/lib/bitly/oauth.rb +109 -0
  39. data/lib/bitly/version.rb +3 -1
  40. metadata +82 -111
  41. data/Manifest +0 -37
  42. data/lib/bitly/client.rb +0 -145
  43. data/lib/bitly/config.rb +0 -29
  44. data/lib/bitly/url.rb +0 -103
  45. data/lib/bitly/utils.rb +0 -57
  46. data/lib/bitly/v3.rb +0 -14
  47. data/lib/bitly/v3/bitly.rb +0 -7
  48. data/lib/bitly/v3/client.rb +0 -207
  49. data/lib/bitly/v3/country.rb +0 -13
  50. data/lib/bitly/v3/day.rb +0 -13
  51. data/lib/bitly/v3/missing_url.rb +0 -15
  52. data/lib/bitly/v3/oauth.rb +0 -41
  53. data/lib/bitly/v3/realtime_link.rb +0 -18
  54. data/lib/bitly/v3/referrer.rb +0 -13
  55. data/lib/bitly/v3/url.rb +0 -154
  56. data/lib/bitly/v3/user.rb +0 -135
  57. data/test/bitly/test_client.rb +0 -266
  58. data/test/bitly/test_config.rb +0 -28
  59. data/test/bitly/test_url.rb +0 -167
  60. data/test/bitly/test_utils.rb +0 -79
  61. data/test/fixtures/cnn.json +0 -1
  62. data/test/fixtures/cnn_and_google.json +0 -1
  63. data/test/fixtures/expand_cnn.json +0 -1
  64. data/test/fixtures/expand_cnn_and_google.json +0 -1
  65. data/test/fixtures/google_and_cnn_info.json +0 -1
  66. data/test/fixtures/google_info.json +0 -1
  67. data/test/fixtures/google_stats.json +0 -1
  68. data/test/fixtures/shorten_error.json +0 -1
  69. data/test/test_helper.rb +0 -39
@@ -1,145 +0,0 @@
1
- require 'rubygems'
2
- require 'net/http'
3
- require 'uri'
4
-
5
- module Bitly
6
- extend Config
7
- API_URL = 'https://api-ssl.bitly.com/'
8
- API_VERSION = '2.0.1'
9
-
10
- def self.new(login, api_key = nil, timeout=nil)
11
- if api_version == 3
12
- Bitly::V3::Client.new(login, api_key, timeout)
13
- else
14
- Bitly::Client.new(login,api_key)
15
- end
16
- end
17
-
18
- def self.use_api_version_3
19
- self.api_version = 3
20
- end
21
-
22
- def self.use_api_version_2
23
- self.api_version = 2
24
- end
25
-
26
- # get and initialize a client if configured using Config
27
- def self.client
28
- # api_verison, login, and api_key are set in Config
29
- if api_version == 3
30
- Bitly::V3::Client.new(login, api_key, timeout)
31
- else
32
- Bitly::Client.new(login, api_key)
33
- end
34
- end
35
-
36
- class Client
37
-
38
- include Bitly::Utils
39
- attr_accessor *Config::OPTION_KEYS
40
-
41
- def initialize(login,api_key)
42
- warn "[DEPRECATION] The bit.ly version 2 API has been superseded by version 3 and will be removed. See the README for details"
43
- @login = login
44
- @api_key = api_key
45
- end
46
-
47
- def shorten(input, opts={})
48
- if input.is_a? String
49
- request = create_url("shorten", :longUrl => input, :history => (opts[:history] ? 1 : nil))
50
- result = get_result(request)
51
- result = {:long_url => input}.merge result[input]
52
- Bitly::Url.new(@login,@api_key,result)
53
- elsif input.is_a? Array
54
- request = create_url("shorten", :history => (opts[:history] ? 1 : nil))
55
- request.query << "&" + input.map { |long_url| "longUrl=#{CGI.escape(long_url)}" }.join("&") unless input.nil?
56
- result = get_result(request)
57
- input.map do |long_url|
58
- new_url = {:long_url => long_url}.merge result[long_url]
59
- long_url = Bitly::Url.new(@login,@api_key,new_url)
60
- end
61
- else
62
- raise ArgumentError.new("Shorten requires either a url or an array of urls")
63
- end
64
- end
65
-
66
- def expand(input)
67
- if input.is_a? String
68
- if input.include?('bit.ly/') || input.include?('j.mp/')
69
- hash = create_hash_from_url(input)
70
- request = create_url "expand", :hash => hash
71
- result = get_result(request)
72
- result = { :short_url => input, :hash => hash }.merge result[hash]
73
- else
74
- request = create_url "expand", :hash => input
75
- result = get_result(request)
76
- result = { :hash => input, :short_url => "http://bit.ly/#{input}" }.merge result[input]
77
- end
78
- Bitly::Url.new(@login,@api_key,result)
79
- elsif input.is_a? Array
80
- request = create_url "expand", :hash => input.join(',')
81
- result = get_result(request)
82
- input.map do |hsh|
83
- new_url = {:hash => hsh, :short_url => "http://bit.ly/#{hsh}"}.merge result[hsh]
84
- hsh = Bitly::Url.new(@login,@api_key,new_url)
85
- end
86
- else
87
- raise ArgumentError('Expand requires either a short url, a hash or an array of hashes')
88
- end
89
- end
90
-
91
- def info(input)
92
- if input.is_a? String
93
- if input.include? "bit.ly/"
94
- hash = create_hash_from_url(input)
95
- request = create_url 'info', :hash => hash
96
- result = get_result(request)
97
- result = { :short_url => "http://bit.ly/#{hash}", :hash => hash }.merge result[hash]
98
- else
99
- request = create_url 'info', :hash => input
100
- result = get_result(request)
101
- result = { :short_url => "http://bit.ly/#{input}", :hash => input }.merge result[input]
102
- end
103
- Bitly::Url.new(@login,@api_key,result)
104
- elsif input.is_a? Array
105
- request = create_url "info", :hash => input.join(',')
106
- result = get_result(request)
107
- input.map do |hsh|
108
- new_url = {:hash => hsh, :short_url => "http://bit.ly/#{hsh}"}.merge result[hsh]
109
- hsh = Bitly::Url.new(@login,@api_key,:info => new_url)
110
- end
111
- else
112
- raise ArgumentError.new('Info requires either a short url, a hash or an array of hashes')
113
- end
114
- end
115
-
116
- def stats(input)
117
- if input.is_a? String
118
- if input.include? "bit.ly/"
119
- hash = create_hash_from_url(input)
120
- request = create_url 'stats', :hash => hash
121
- result = get_result(request)
122
- result = { :short_url => "http://bit.ly/#{hash}", :hash => hash }.merge result
123
- else
124
- request = create_url 'stats', :hash => input
125
- result = get_result(request)
126
- result = { :short_url => "http://bit.ly/#{input}", :hash => input }.merge result
127
- end
128
- Bitly::Url.new(@login,@api_key,:stats => result)
129
- else
130
- raise ArgumentError.new("Stats requires either a short url or a hash")
131
- end
132
- end
133
-
134
- end
135
-
136
- end
137
-
138
- class BitlyError < StandardError
139
- attr_reader :code
140
- alias :msg :message
141
- def initialize(msg, code)
142
- @code = code
143
- super("#{msg} - '#{code}'")
144
- end
145
- end
@@ -1,29 +0,0 @@
1
- module Bitly
2
- module Config
3
-
4
- # bitly client options
5
- OPTION_KEYS = [
6
- :login,
7
- :api_key,
8
- :api_version,
9
- :timeout
10
- ]
11
-
12
- attr_accessor *OPTION_KEYS
13
-
14
- alias_method :access_token, :login
15
- alias_method :access_token=, :login=
16
-
17
- def configure
18
- yield self
19
- self
20
- end
21
-
22
- def options
23
- options = {}
24
- OPTION_KEYS.each{|key| options[key] = send(key)}
25
- options
26
- end
27
-
28
- end
29
- end
@@ -1,103 +0,0 @@
1
- module Bitly
2
-
3
- class Url
4
- include Bitly::Utils
5
-
6
- attr_accessor :long_url, :short_url, :hash, :user_hash
7
- VARIABLES = ['long_url', 'short_url', 'hash', 'user_hash']
8
-
9
- def initialize(login,api_key,obj=nil)
10
- unless obj.nil?
11
- raise BitlyError.new(obj['errorMessage'],obj['errorCode']) if obj['statusCode'] == "ERROR"
12
- instance_variablise(obj, VARIABLES)
13
- @info = obj.fetch(:info, nil)
14
- @stats = obj.fetch(:stats, nil)
15
- end
16
- @login = login
17
- @api_key = api_key
18
- raise ArgumentError.new("Please provide a login and api_key") if @login.nil? || @api_key.nil?
19
- end
20
-
21
- def shorten(opts = {})
22
- return @short_url if defined? @short_url
23
- if defined? @long_url
24
- request = create_url("shorten", :longUrl => @long_url, :history => (opts[:history] ? 1 : nil))
25
- result = get_result(request)[@long_url.gsub(/\/$/,'')]
26
- if result['statusCode'] == "ERROR"
27
- raise BitlyError.new(result['errorMessage'],result['errorCode'])
28
- else
29
- instance_variablise(result,VARIABLES)
30
- return @short_url
31
- end
32
- else
33
- raise ArgumentError.new("You need a long_url in order to shorten it")
34
- end
35
- end
36
-
37
- def expand
38
- return @long_url if defined? @long_url
39
- unless !(short_url || hash)
40
- unless defined? @hash
41
- @hash = create_hash_from_url(@short_url)
42
- end
43
- request = create_url("expand", :hash => @hash)
44
- result = get_result(request)[@hash]
45
- if result['statusCode'] == "ERROR"
46
- raise BitlyError.new(result['errorMessage'],result['errorCode'])
47
- else
48
- instance_variablise(result,VARIABLES)
49
- return @long_url
50
- end
51
- else
52
- raise ArgumentError.new("You need a short_url or a hash in order to expand it")
53
- end
54
- end
55
-
56
- def info
57
- if @info.nil?
58
- if defined? @hash
59
- request = create_url "info", :hash => @hash
60
- result = get_result(request)[@hash]
61
- instance_variablise(result, VARIABLES)
62
- @info = result
63
- elsif defined? @short_url
64
- @hash = create_hash_from_url(@short_url)
65
- request = create_url "info", :hash => hash
66
- result = get_result(request)[hash]
67
- instance_variablise(result, VARIABLES)
68
- @info = result
69
- else
70
- raise ArgumentError.new("You need a hash or short_url in order to get info")
71
- end
72
- return @info
73
- else
74
- @info
75
- end
76
- end
77
-
78
- def stats
79
- if @stats.nil?
80
- if defined? @hash
81
- request = create_url "stats", :hash => @hash
82
- elsif defined? @short_url
83
- @hash = create_hash_from_url(@short_url)
84
- request = create_url "stats", :hash => @hash
85
- else
86
- raise ArgumentError.new("You need a hash or short_url in order to get stats")
87
- end
88
- @stats = get_result(request)
89
- else
90
- @stats
91
- end
92
- end
93
-
94
- def bitly_url
95
- @short_url.nil? ? nil : @short_url.gsub(/j\.mp/,'bit.ly')
96
- end
97
-
98
- def jmp_url
99
- @short_url.nil? ? nil : @short_url.gsub(/bit\.ly/,'j.mp')
100
- end
101
- end
102
-
103
- end
@@ -1,57 +0,0 @@
1
- require 'cgi'
2
-
3
- module Bitly
4
- module Utils
5
- def underscore(camel_cased_word) # stolen from rails
6
- camel_cased_word.to_s.gsub(/::/, '/').
7
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
8
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
9
- tr("-", "_").
10
- downcase
11
- end
12
-
13
- def create_hash_from_url(url)
14
- url.gsub(/^.*(bit\.ly|j\.mp)\//,'')
15
- end
16
-
17
- def attr_define(k,v)
18
- instance_variable_set("@#{k}", v)
19
- end
20
-
21
- def instance_variablise(obj,variables)
22
- if obj.is_a? Hash
23
- obj.each do |k,v|
24
- if v.is_a? Hash
25
- instance_variablise(v,variables)
26
- else
27
- attr_define(underscore(k),v) if variables.include?(underscore(k))
28
- end
29
- end
30
- end
31
- end
32
-
33
- def create_url(resource="",args={})
34
- args = args.merge({:login => @login, :apiKey => @api_key, :version => API_VERSION})
35
- url = URI.join(API_URL,resource)
36
- long_urls = args.delete(:long_urls)
37
- url.query = args.map { |k,v| "%s=%s" % [CGI.escape(k.to_s), CGI.escape(v.to_s)] }.join("&")
38
- url.query << "&" + long_urls.map { |long_url| "longUrl=#{CGI.escape(long_url)}" }.join("&") unless long_urls.nil?
39
- url
40
- end
41
-
42
- def get_result(request)
43
- begin
44
- json = Net::HTTP.get(request)
45
- result = MultiJson.load(json)
46
- rescue MultiJson::DecodeError
47
- result = {'errorMessage' => 'JSON Parse Error(Bit.ly messed up)', 'errorCode' => 69, 'statusCode' => 'ERROR'}
48
- end
49
- if result['statusCode'] == "OK"
50
- result = result['results']
51
- else
52
- raise BitlyError.new(result['errorMessage'],result['errorCode'])
53
- end
54
- end
55
-
56
- end
57
- end
@@ -1,14 +0,0 @@
1
- require 'httparty'
2
- require 'cgi'
3
- require 'oauth2'
4
-
5
- require 'bitly/v3/bitly'
6
- require 'bitly/v3/client'
7
- require 'bitly/v3/url'
8
- require 'bitly/v3/referrer'
9
- require 'bitly/v3/day'
10
- require 'bitly/v3/country'
11
- require 'bitly/v3/missing_url'
12
- require 'bitly/v3/realtime_link'
13
- require 'bitly/v3/oauth'
14
- require 'bitly/v3/user'
@@ -1,7 +0,0 @@
1
- module Bitly
2
- module V3
3
- def self.new(login, api_key)
4
- Bitly::V3::Client.new(login, api_key)
5
- end
6
- end
7
- end
@@ -1,207 +0,0 @@
1
- module Bitly
2
- module V3
3
- # The client is the main part of this gem. You need to initialize the client with your
4
- # username and API key and then you will be able to use the client to perform
5
- # all the rest of the actions available through the API.
6
- class Client
7
- include HTTParty
8
- base_uri 'https://api-ssl.bitly.com/v3/'
9
-
10
- # Requires a generic OAuth2 access token or -deprecated- login and api key.
11
- # http://dev.bitly.com/authentication.html#apikey
12
- # Generic OAuth2 access token: https://bitly.com/a/oauth_apps
13
- # ApiKey: Get yours from your account page at https://bitly.com/a/your_api_key
14
- # Visit your account at http://bit.ly/a/account
15
- def initialize(*args)
16
- args.compact!
17
- self.timeout = args.last.is_a?(0.class) ? args.pop : nil
18
- if args.count == 1
19
- # Set generic OAuth2 access token
20
- @default_query_opts = { :access_token => args.first }
21
- else
22
- # Deprecated ApiKey authentication
23
- @default_query_opts = {
24
- :login => args[0],
25
- :apiKey => args[1]
26
- }
27
- end
28
- end
29
-
30
- # Validates a login and api key
31
- def validate(x_login, x_api_key)
32
- response = get('/validate', :query => { :x_login => x_login, :x_apiKey => x_api_key })
33
- return response['data']['valid'] == 1
34
- end
35
- alias :valid? :validate
36
-
37
- # Checks whether a domain is a bitly.Pro domain
38
- def bitly_pro_domain(domain)
39
- response = get('/bitly_pro_domain', :query => { :domain => domain })
40
- return response['data']['bitly_pro_domain']
41
- end
42
- alias :pro? :bitly_pro_domain
43
-
44
- # Shortens a long url
45
- #
46
- # Options can be:
47
- #
48
- # [domain] choose bit.ly or j.mp (bit.ly is default)
49
- #
50
- # [x_login and x_apiKey] add this link to another user's history (both required)
51
- #
52
- def shorten(long_url, opts={})
53
- query = { :longUrl => long_url }.merge(opts)
54
- response = get('/shorten', :query => query)
55
- return Bitly::V3::Url.new(self, response['data'])
56
- end
57
-
58
- # Expands either a hash, short url or array of either.
59
- #
60
- # Returns the results in the order they were entered
61
- def expand(input)
62
- get_method(:expand, input)
63
- end
64
-
65
- # Expands either a hash, short url or array of either and gets click data too.
66
- #
67
- # Returns the results in the order they were entered
68
- def clicks(input)
69
- get_method(:clicks, input)
70
- end
71
-
72
- # Like expand, but gets the title of the page and who created it
73
- def info(input)
74
- get_method(:info, input)
75
- end
76
-
77
- # Looks up the short url and global hash of a url or array of urls
78
- #
79
- # Returns the results in the order they were entered
80
- def lookup(input)
81
- input = arrayize(input)
82
- query = input.inject([]) { |query, i| query << "url=#{CGI.escape(i)}" }
83
- query = "/lookup?" + query.join('&')
84
- response = get(query)
85
- results = response['data']['lookup'].inject([]) do |results, url|
86
- url['long_url'] = url['url']
87
- url['url'] = nil
88
- if url['error'].nil?
89
- # builds the results array in the same order as the input
90
- results[input.index(url['long_url'])] = Bitly::V3::Url.new(self, url)
91
- # remove the key from the original array, in case the same hash/url was entered twice
92
- input[input.index(url['long_url'])] = nil
93
- else
94
- results[input.index(url['long_url'])] = Bitly::V3::MissingUrl.new(url)
95
- input[input.index(url['long_url'])] = nil
96
- end
97
- results
98
- end
99
- return results.length > 1 ? results : results[0]
100
- end
101
-
102
- # Expands either a short link or hash and gets the referrer data for that link
103
- #
104
- # This method does not take an array as an input
105
- def referrers(input)
106
- get_single_method('referrers', input)
107
- end
108
-
109
- # Expands either a short link or hash and gets the country data for that link
110
- #
111
- # This method does not take an array as an input
112
- def countries(input)
113
- get_single_method('countries', input)
114
- end
115
-
116
- # Takes a short url, hash or array of either and gets the clicks by minute of each of the last hour
117
- def clicks_by_minute(input)
118
- get_method(:clicks_by_minute, input)
119
- end
120
-
121
- # Takes a short url, hash or array of either and gets the clicks by day
122
- def clicks_by_day(input, opts={})
123
- opts.reject! { |k, v| k.to_s != 'days' }
124
- get_method(:clicks_by_day, input, opts)
125
- end
126
-
127
- def timeout=(timeout=nil)
128
- self.class.default_timeout(timeout) if timeout
129
- end
130
-
131
- private
132
-
133
- def arrayize(arg)
134
- if arg.is_a?(String)
135
- [arg]
136
- else
137
- arg.dup
138
- end
139
- end
140
-
141
- def get(method, opts={})
142
- opts[:query] ||= {}
143
- opts[:query].merge!(@default_query_opts)
144
-
145
- begin
146
- response = self.class.get(method, opts)
147
- rescue Timeout::Error
148
- raise BitlyTimeout.new("Bitly didn't respond in time", "504")
149
- end
150
-
151
- if response['status_code'] == 200
152
- return response
153
- else
154
- raise BitlyError.new(response['status_txt'], response['status_code'])
155
- end
156
- end
157
-
158
- def is_a_short_url?(input)
159
- input.match(/^http:\/\//)
160
- end
161
-
162
- def get_single_method(method, input)
163
- raise ArgumentError.new("This method only takes a hash or url input") unless input.is_a? String
164
- if is_a_short_url?(input)
165
- query = "shortUrl=#{CGI.escape(input)}"
166
- else
167
- query = "hash=#{CGI.escape(input)}"
168
- end
169
- query = "/#{method}?" + query
170
- response = get(query)
171
- return Bitly::V3::Url.new(self,response['data'])
172
- end
173
-
174
- def get_method(method, input, opts={})
175
- input = arrayize(input)
176
- query = input.inject([]) do |query,i|
177
- if is_a_short_url?(i)
178
- query << "shortUrl=#{CGI.escape(i)}"
179
- else
180
- query << "hash=#{CGI.escape(i)}"
181
- end
182
- end
183
- query = opts.inject(query) do |query, (k,v)|
184
- query << "#{k}=#{v}"
185
- end
186
- query = "/#{method}?" + query.join('&')
187
- response = get(query)
188
- results = response['data'][method.to_s].inject([]) do |results, url|
189
- result_index = input.index(url['short_url'] || url['hash']) || input.index(url['global_hash'])
190
- if url['error'].nil?
191
- # builds the results array in the same order as the input
192
- results[result_index] = Bitly::V3::Url.new(self, url)
193
- # remove the key from the original array, in case the same hash/url was entered twice
194
- input[result_index] = nil
195
- else
196
- results[result_index] = Bitly::V3::MissingUrl.new(url)
197
- input[result_index] = nil
198
- end
199
- results
200
- end
201
- return results.length > 1 ? results : results[0]
202
- end
203
- end
204
- end
205
- end
206
-
207
- class BitlyTimeout < BitlyError; end