bitly 0.4.0 → 0.5.0

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.
@@ -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