bitly 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,10 @@
1
+ === 0.5.0 / 2010-05-12
2
+
3
+ * Loads of major enhancements
4
+
5
+ * Support for version 3 of the bit.ly API
6
+ * deprecation for version 2 client object
7
+
1
8
  === 0.4.0 / 2009-12-19
2
9
 
3
10
  * 1 major enhancement
data/Manifest CHANGED
@@ -3,6 +3,11 @@ History.txt
3
3
  lib/bitly/client.rb
4
4
  lib/bitly/url.rb
5
5
  lib/bitly/utils.rb
6
+ lib/bitly/v3/bitly.rb
7
+ lib/bitly/v3/client.rb
8
+ lib/bitly/v3/missing_url.rb
9
+ lib/bitly/v3/url.rb
10
+ lib/bitly/v3.rb
6
11
  lib/bitly/version.rb
7
12
  lib/bitly.rb
8
13
  Manifest
data/README.txt CHANGED
@@ -6,6 +6,20 @@ A Ruby API for http://bit.ly (and now http://j.mp)
6
6
 
7
7
  http://code.google.com/p/bitly-api/wiki/ApiDocumentation
8
8
 
9
+ == NOTE:
10
+
11
+ Bitly recently released their version 3 API. From this 0.5.0 release, the gem will continue to work the same but also provide a V3 module, using the version 3 API. The standard module will become deprecated, as Bitly do not plan to keep the version 2 API around forever.
12
+
13
+ To move to using the version 3 API, call:
14
+
15
+ Bitly.use_api_version_3
16
+
17
+ Then, when you call Bitly.new(username, api_key) you will get a Bitly::V3::Client instead, which provides the version 3 api calls (shorten, expand, clicks, validate and bitly_pro_domain). See http://api.bit.ly for details.
18
+
19
+ Eventually, this will become the default version used and finally, the V3 module will disappear, with the version 3 classes replacing the version 2 classes.
20
+
21
+ (Please excuse the lack of tests for the v3 classes, they are fully tested and ready to replace this whole codebase in the v3 branch of the github repo, until I realised it would break everything.)
22
+
9
23
  == INSTALLATION:
10
24
 
11
25
  gem install bitly
data/Rakefile CHANGED
@@ -8,6 +8,6 @@ Echoe.new('bitly', Bitly::VERSION) do |p|
8
8
  p.url = "http://github.com/philnash/bitly"
9
9
  p.author = "Phil Nash"
10
10
  p.email = "philnash@gmail.com"
11
- p.extra_deps = [['crack', '>= 0.1.1']]
11
+ p.extra_deps = [['crack', '>= 0.1.4'], ['httparty', '>= 0.5.2']]
12
12
  p.development_dependencies = []
13
13
  end
@@ -2,20 +2,20 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{bitly}
5
- s.version = "0.4.0"
5
+ s.version = "0.5.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Phil Nash"]
9
- s.date = %q{2009-12-19}
9
+ s.date = %q{2010-05-12}
10
10
  s.description = %q{Use the bit.ly API to shorten or expand URLs}
11
11
  s.email = %q{philnash@gmail.com}
12
- s.extra_rdoc_files = ["lib/bitly/client.rb", "lib/bitly/url.rb", "lib/bitly/utils.rb", "lib/bitly/version.rb", "lib/bitly.rb", "README.txt"]
13
- s.files = ["bitly.gemspec", "History.txt", "lib/bitly/client.rb", "lib/bitly/url.rb", "lib/bitly/utils.rb", "lib/bitly/version.rb", "lib/bitly.rb", "Manifest", "Rakefile", "README.txt", "test/bitly/test_client.rb", "test/bitly/test_url.rb", "test/bitly/test_utils.rb", "test/fixtures/cnn.json", "test/fixtures/cnn_and_google.json", "test/fixtures/expand_cnn.json", "test/fixtures/expand_cnn_and_google.json", "test/fixtures/google_and_cnn_info.json", "test/fixtures/google_info.json", "test/fixtures/google_stats.json", "test/fixtures/shorten_error.json", "test/test_helper.rb"]
12
+ s.extra_rdoc_files = ["lib/bitly/client.rb", "lib/bitly/url.rb", "lib/bitly/utils.rb", "lib/bitly/v3/bitly.rb", "lib/bitly/v3/client.rb", "lib/bitly/v3/missing_url.rb", "lib/bitly/v3/url.rb", "lib/bitly/v3.rb", "lib/bitly/version.rb", "lib/bitly.rb", "README.txt"]
13
+ s.files = ["bitly.gemspec", "History.txt", "lib/bitly/client.rb", "lib/bitly/url.rb", "lib/bitly/utils.rb", "lib/bitly/v3/bitly.rb", "lib/bitly/v3/client.rb", "lib/bitly/v3/missing_url.rb", "lib/bitly/v3/url.rb", "lib/bitly/v3.rb", "lib/bitly/version.rb", "lib/bitly.rb", "Manifest", "Rakefile", "README.txt", "test/bitly/test_client.rb", "test/bitly/test_url.rb", "test/bitly/test_utils.rb", "test/fixtures/cnn.json", "test/fixtures/cnn_and_google.json", "test/fixtures/expand_cnn.json", "test/fixtures/expand_cnn_and_google.json", "test/fixtures/google_and_cnn_info.json", "test/fixtures/google_info.json", "test/fixtures/google_stats.json", "test/fixtures/shorten_error.json", "test/test_helper.rb"]
14
14
  s.homepage = %q{http://github.com/philnash/bitly}
15
15
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Bitly", "--main", "README.txt"]
16
16
  s.require_paths = ["lib"]
17
17
  s.rubyforge_project = %q{bitly}
18
- s.rubygems_version = %q{1.3.5}
18
+ s.rubygems_version = %q{1.3.6}
19
19
  s.summary = %q{Use the bit.ly API to shorten or expand URLs}
20
20
  s.test_files = ["test/bitly/test_client.rb", "test/bitly/test_url.rb", "test/bitly/test_utils.rb", "test/test_helper.rb"]
21
21
 
@@ -24,11 +24,14 @@ Gem::Specification.new do |s|
24
24
  s.specification_version = 3
25
25
 
26
26
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
- s.add_runtime_dependency(%q<crack>, [">= 0.1.1"])
27
+ s.add_runtime_dependency(%q<crack>, [">= 0.1.4"])
28
+ s.add_runtime_dependency(%q<httparty>, [">= 0.5.2"])
28
29
  else
29
- s.add_dependency(%q<crack>, [">= 0.1.1"])
30
+ s.add_dependency(%q<crack>, [">= 0.1.4"])
31
+ s.add_dependency(%q<httparty>, [">= 0.5.2"])
30
32
  end
31
33
  else
32
- s.add_dependency(%q<crack>, [">= 0.1.1"])
34
+ s.add_dependency(%q<crack>, [">= 0.1.4"])
35
+ s.add_dependency(%q<httparty>, [">= 0.5.2"])
33
36
  end
34
37
  end
@@ -5,4 +5,5 @@ require 'crack'
5
5
  require 'bitly/utils'
6
6
  require 'bitly/client'
7
7
  require 'bitly/url'
8
- require 'bitly/version'
8
+ require 'bitly/version'
9
+ require 'bitly/v3'
@@ -7,7 +7,19 @@ module Bitly
7
7
  API_VERSION = '2.0.1'
8
8
 
9
9
  def self.new(login, api_key)
10
- Bitly::Client.new(login,api_key)
10
+ if @version == 3
11
+ Bitly::V3::Client.new(login, api_key)
12
+ else
13
+ Bitly::Client.new(login,api_key)
14
+ end
15
+ end
16
+
17
+ def self.use_api_version_3
18
+ @version = 3
19
+ end
20
+
21
+ def self.use_api_version_2
22
+ @version = 2
11
23
  end
12
24
 
13
25
  class Client
@@ -15,6 +27,7 @@ module Bitly
15
27
  include Bitly::Utils
16
28
 
17
29
  def initialize(login,api_key)
30
+ warn "[DEPRECATION] The bit.ly version 2 API has been superceded by version 3 and will be removed. See the README for details"
18
31
  @login = login
19
32
  @api_key = api_key
20
33
  end
@@ -43,7 +43,9 @@ module Bitly
43
43
 
44
44
  def get_result(request)
45
45
  begin
46
- result = Crack::JSON.parse(Net::HTTP.get(request))
46
+ json = Net::HTTP.get(request)
47
+ # puts json.inspect
48
+ result = Crack::JSON.parse(json)
47
49
  rescue
48
50
  result = {'errorMessage' => 'JSON Parse Error(Bit.ly messed up)', 'errorCode' => 69, 'statusCode' => 'ERROR'}
49
51
  end
@@ -0,0 +1,9 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'httparty'
4
+ require 'cgi'
5
+
6
+ require 'v3/bitly'
7
+ require 'v3/client'
8
+ require 'v3/url'
9
+ require 'v3/missing_url'
@@ -0,0 +1,16 @@
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
8
+
9
+ class BitlyError < StandardError
10
+ attr_reader :code
11
+ alias :msg :message
12
+ def initialize(msg, code)
13
+ @code = code
14
+ super("#{msg} - '#{code}'")
15
+ end
16
+ end
@@ -0,0 +1,103 @@
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 'http://api.bit.ly/v3/'
9
+
10
+ # Requires a login and api key. Get yours from your account page at http://bit.ly/a/account
11
+ def initialize(login, api_key)
12
+ @default_query_opts = { :login => login, :apiKey => api_key }
13
+ end
14
+
15
+ # Validates a login and api key
16
+ def validate(x_login, x_api_key)
17
+ response = get('/validate', :query => { :x_login => x_login, :x_apiKey => x_api_key })
18
+ return response['data']['valid'] == 1
19
+ end
20
+ alias :valid? :validate
21
+
22
+ # Checks whether a domain is a bitly.Pro domain
23
+ def bitly_pro_domain(domain)
24
+ response = get('/bitly_pro_domain', :query => { :domain => domain })
25
+ return response['data']['bitly_pro_domain']
26
+ end
27
+ alias :pro? :bitly_pro_domain
28
+
29
+ # Shortens a long url
30
+ #
31
+ # Options can be:
32
+ #
33
+ # [domain] choose bit.ly or j.mp (bit.ly is default)
34
+ #
35
+ # [x_login and x_apiKey] add this link to another user's history (both required)
36
+ #
37
+ def shorten(long_url, opts={})
38
+ query = { :longUrl => long_url }.merge(opts)
39
+ response = get('/shorten', :query => query)
40
+ return Bitly::V3::Url.new(self, response['data'])
41
+ end
42
+
43
+ # Expands either a hash, short url or array of either.
44
+ #
45
+ # Returns the results in the order they were entered
46
+ def expand(input)
47
+ get_method(:expand, input)
48
+ end
49
+
50
+ # Expands either a hash, short url or array of either and gets click data too.
51
+ #
52
+ # Returns the results in the order they were entered
53
+ def clicks(input)
54
+ get_method(:clicks, input)
55
+ end
56
+
57
+ private
58
+
59
+ def get(method, opts={})
60
+ opts[:query] ||= {}
61
+ opts[:query].merge!(@default_query_opts)
62
+ response = self.class.get(method, opts)
63
+ if response['status_code'] == 200
64
+ return response
65
+ else
66
+ raise BitlyError.new(response['status_txt'], response['status_code'])
67
+ end
68
+ end
69
+
70
+ def is_a_short_url?(input)
71
+ input.match(/^http:\/\//)
72
+ end
73
+
74
+ def get_method(method, input)
75
+ input = [input] if input.is_a? String
76
+ query = []
77
+ input.each do |i|
78
+ if is_a_short_url?(i)
79
+ query << "shortUrl=#{CGI.escape(i)}"
80
+ else
81
+ query << "hash=#{CGI.escape(i)}"
82
+ end
83
+ end
84
+ query = "/#{method}?" + query.join('&')
85
+ response = get(query)
86
+ results = []
87
+ response['data'][method.to_s].each do |url|
88
+ if url['error'].nil?
89
+ # builds the results array in the same order as the input
90
+ results[input.index(url['short_url'] || url['hash'])] = 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['short_url'] || url['hash'])] = nil
93
+ else
94
+ results[input.index(url['short_url'] || url['hash'])] = Bitly::V3::MissingUrl.new(url)
95
+ input[input.index(url['short_url'] || url['hash'])] = nil
96
+ end
97
+ end
98
+ return results.length > 1 ? results : results[0]
99
+ end
100
+
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,14 @@
1
+ module Bitly
2
+ module V3
3
+ class MissingUrl
4
+ attr_accessor :short_url, :user_hash, :error
5
+ def initialize(opts={})
6
+ if opts
7
+ @short_url = opts['short_url']
8
+ @user_hash = opts['hash']
9
+ @error = opts['error']
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,53 @@
1
+ module Bitly
2
+ module V3
3
+ # Url objects should only be created by the client object as it collects the correct information
4
+ # from the API.
5
+ class Url
6
+ attr_reader :short_url, :long_url, :user_hash, :global_hash
7
+
8
+ # Initialize with a bitly client and optional hash to fill in the details for the url.
9
+ def initialize(client, opts={})
10
+ @client = client
11
+ if opts
12
+ @short_url = opts['url']
13
+ @long_url = opts['long_url']
14
+ @user_hash = opts['hash']
15
+ @global_hash = opts['global_hash']
16
+ @new_hash = (opts['new_hash'] == 1)
17
+ @user_clicks = opts['user_clicks']
18
+ @global_clicks = opts['global_clicks']
19
+ end
20
+ @short_url = "http://bit.ly/#{@user_hash}" unless @short_url
21
+ end
22
+
23
+ # Returns true if the user hash was created first for this call
24
+ def new_hash?
25
+ @new_hash
26
+ end
27
+
28
+ # If the url already has click statistics, returns the user clicks.
29
+ # IF there are no click statistics or <tt>:force => true</tt> is passed,
30
+ # updates the stats and returns the user clicks
31
+ def user_clicks(opts={})
32
+ update_clicks_data if @global_clicks.nil? || opts[:force]
33
+ @user_clicks
34
+ end
35
+
36
+ # If the url already has click statistics, returns the global clicks.
37
+ # IF there are no click statistics or <tt>:force => true</tt> is passed,
38
+ # updates the stats and returns the global clicks
39
+ def global_clicks(opts={})
40
+ update_clicks_data if @global_clicks.nil? || opts[:force]
41
+ @global_clicks
42
+ end
43
+
44
+ private
45
+
46
+ def update_clicks_data
47
+ full_url = @client.clicks(@user_hash || @short_url)
48
+ @global_clicks = full_url.global_clicks
49
+ @user_clicks = full_url.user_clicks
50
+ end
51
+ end
52
+ end
53
+ end
@@ -1,3 +1,3 @@
1
1
  module Bitly
2
- VERSION = '0.4.0'
2
+ VERSION = '0.5.0'
3
3
  end
@@ -26,4 +26,10 @@ def api_key
26
26
  end
27
27
  def login
28
28
  'test_account'
29
+ end
30
+
31
+ class Test::Unit::TestCase
32
+ def teardown
33
+ FakeWeb.clean_registry
34
+ end
29
35
  end
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 5
8
+ - 0
9
+ version: 0.5.0
5
10
  platform: ruby
6
11
  authors:
7
12
  - Phil Nash
@@ -9,19 +14,37 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2009-12-19 00:00:00 +00:00
17
+ date: 2010-05-12 00:00:00 +01:00
13
18
  default_executable:
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
21
  name: crack
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ - 1
30
+ - 4
31
+ version: 0.1.4
17
32
  type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: httparty
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
20
38
  requirements:
21
39
  - - ">="
22
40
  - !ruby/object:Gem::Version
23
- version: 0.1.1
24
- version:
41
+ segments:
42
+ - 0
43
+ - 5
44
+ - 2
45
+ version: 0.5.2
46
+ type: :runtime
47
+ version_requirements: *id002
25
48
  description: Use the bit.ly API to shorten or expand URLs
26
49
  email: philnash@gmail.com
27
50
  executables: []
@@ -32,6 +55,11 @@ extra_rdoc_files:
32
55
  - lib/bitly/client.rb
33
56
  - lib/bitly/url.rb
34
57
  - lib/bitly/utils.rb
58
+ - lib/bitly/v3/bitly.rb
59
+ - lib/bitly/v3/client.rb
60
+ - lib/bitly/v3/missing_url.rb
61
+ - lib/bitly/v3/url.rb
62
+ - lib/bitly/v3.rb
35
63
  - lib/bitly/version.rb
36
64
  - lib/bitly.rb
37
65
  - README.txt
@@ -41,6 +69,11 @@ files:
41
69
  - lib/bitly/client.rb
42
70
  - lib/bitly/url.rb
43
71
  - lib/bitly/utils.rb
72
+ - lib/bitly/v3/bitly.rb
73
+ - lib/bitly/v3/client.rb
74
+ - lib/bitly/v3/missing_url.rb
75
+ - lib/bitly/v3/url.rb
76
+ - lib/bitly/v3.rb
44
77
  - lib/bitly/version.rb
45
78
  - lib/bitly.rb
46
79
  - Manifest
@@ -76,18 +109,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
76
109
  requirements:
77
110
  - - ">="
78
111
  - !ruby/object:Gem::Version
112
+ segments:
113
+ - 0
79
114
  version: "0"
80
- version:
81
115
  required_rubygems_version: !ruby/object:Gem::Requirement
82
116
  requirements:
83
117
  - - ">="
84
118
  - !ruby/object:Gem::Version
119
+ segments:
120
+ - 1
121
+ - 2
85
122
  version: "1.2"
86
- version:
87
123
  requirements: []
88
124
 
89
125
  rubyforge_project: bitly
90
- rubygems_version: 1.3.5
126
+ rubygems_version: 1.3.6
91
127
  signing_key:
92
128
  specification_version: 3
93
129
  summary: Use the bit.ly API to shorten or expand URLs