Permalink
Browse files

Includes v3 as separate module and allows use of either API easily.

  • Loading branch information...
1 parent eeb0cec commit c62b433371dd72679da7c3413a755e1cf60853d4 @philnash committed May 11, 2010
Showing with 248 additions and 5 deletions.
  1. +7 −0 History.txt
  2. +5 −0 Manifest
  3. +14 −0 README.txt
  4. +1 −1 Rakefile
  5. +2 −1 lib/bitly.rb
  6. +14 −1 lib/bitly/client.rb
  7. +3 −1 lib/bitly/utils.rb
  8. +9 −0 lib/bitly/v3.rb
  9. +16 −0 lib/bitly/v3/bitly.rb
  10. +103 −0 lib/bitly/v3/client.rb
  11. +14 −0 lib/bitly/v3/missing_url.rb
  12. +53 −0 lib/bitly/v3/url.rb
  13. +1 −1 lib/bitly/version.rb
  14. +6 −0 test/test_helper.rb
View
@@ -1,3 +1,10 @@
+=== 0.5.0 / 2010-05-12
+
+* Loads of major enhancements
+
+ * Support for version 3 of the bit.ly API
+ * deprecation for version 2 client object
+
=== 0.4.0 / 2009-12-19
* 1 major enhancement
View
@@ -3,6 +3,11 @@ 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
View
@@ -6,6 +6,20 @@ A Ruby API for http://bit.ly (and now http://j.mp)
http://code.google.com/p/bitly-api/wiki/ApiDocumentation
+== NOTE:
+
+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.
+
+To move to using the version 3 API, call:
+
+Bitly.use_api_version_3
+
+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.
+
+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.
+
+(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.)
+
== INSTALLATION:
gem install bitly
View
@@ -8,6 +8,6 @@ Echoe.new('bitly', Bitly::VERSION) do |p|
p.url = "http://github.com/philnash/bitly"
p.author = "Phil Nash"
p.email = "philnash@gmail.com"
- p.extra_deps = [['crack', '>= 0.1.1']]
+ p.extra_deps = [['crack', '>= 0.1.4'], ['httparty', '>= 0.5.2']]
p.development_dependencies = []
end
View
@@ -5,4 +5,5 @@
require 'bitly/utils'
require 'bitly/client'
require 'bitly/url'
-require 'bitly/version'
+require 'bitly/version'
+require 'bitly/v3'
View
@@ -7,14 +7,27 @@ module Bitly
API_VERSION = '2.0.1'
def self.new(login, api_key)
- Bitly::Client.new(login,api_key)
+ if @version == 3
+ Bitly::V3::Client.new(login, api_key)
+ else
+ Bitly::Client.new(login,api_key)
+ end
+ end
+
+ def self.use_api_version_3
+ @version = 3
+ end
+
+ def self.use_api_version_2
+ @version = 2
end
class Client
include Bitly::Utils
def initialize(login,api_key)
+ warn "[DEPRECATION] The bit.ly version 2 API has been superceded by version 3 and will be removed. See the README for details"
@login = login
@api_key = api_key
end
View
@@ -43,7 +43,9 @@ def create_url(resource="",args={})
def get_result(request)
begin
- result = Crack::JSON.parse(Net::HTTP.get(request))
+ json = Net::HTTP.get(request)
+ # puts json.inspect
+ result = Crack::JSON.parse(json)
rescue
result = {'errorMessage' => 'JSON Parse Error(Bit.ly messed up)', 'errorCode' => 69, 'statusCode' => 'ERROR'}
end
View
@@ -0,0 +1,9 @@
+$:.unshift File.dirname(__FILE__)
+
+require 'httparty'
+require 'cgi'
+
+require 'v3/bitly'
+require 'v3/client'
+require 'v3/url'
+require 'v3/missing_url'
View
@@ -0,0 +1,16 @@
+module Bitly
+ module V3
+ def self.new(login, api_key)
+ Bitly::V3::Client.new(login, api_key)
+ end
+ end
+end
+
+class BitlyError < StandardError
+ attr_reader :code
+ alias :msg :message
+ def initialize(msg, code)
+ @code = code
+ super("#{msg} - '#{code}'")
+ end
+end
View
@@ -0,0 +1,103 @@
+module Bitly
+ module V3
+ # The client is the main part of this gem. You need to initialize the client with your
+ # username and API key and then you will be able to use the client to perform
+ # all the rest of the actions available through the API.
+ class Client
+ include HTTParty
+ base_uri 'http://api.bit.ly/v3/'
+
+ # Requires a login and api key. Get yours from your account page at http://bit.ly/a/account
+ def initialize(login, api_key)
+ @default_query_opts = { :login => login, :apiKey => api_key }
+ end
+
+ # Validates a login and api key
+ def validate(x_login, x_api_key)
+ response = get('/validate', :query => { :x_login => x_login, :x_apiKey => x_api_key })
+ return response['data']['valid'] == 1
+ end
+ alias :valid? :validate
+
+ # Checks whether a domain is a bitly.Pro domain
+ def bitly_pro_domain(domain)
+ response = get('/bitly_pro_domain', :query => { :domain => domain })
+ return response['data']['bitly_pro_domain']
+ end
+ alias :pro? :bitly_pro_domain
+
+ # Shortens a long url
+ #
+ # Options can be:
+ #
+ # [domain] choose bit.ly or j.mp (bit.ly is default)
+ #
+ # [x_login and x_apiKey] add this link to another user's history (both required)
+ #
+ def shorten(long_url, opts={})
+ query = { :longUrl => long_url }.merge(opts)
+ response = get('/shorten', :query => query)
+ return Bitly::V3::Url.new(self, response['data'])
+ end
+
+ # Expands either a hash, short url or array of either.
+ #
+ # Returns the results in the order they were entered
+ def expand(input)
+ get_method(:expand, input)
+ end
+
+ # Expands either a hash, short url or array of either and gets click data too.
+ #
+ # Returns the results in the order they were entered
+ def clicks(input)
+ get_method(:clicks, input)
+ end
+
+ private
+
+ def get(method, opts={})
+ opts[:query] ||= {}
+ opts[:query].merge!(@default_query_opts)
+ response = self.class.get(method, opts)
+ if response['status_code'] == 200
+ return response
+ else
+ raise BitlyError.new(response['status_txt'], response['status_code'])
+ end
+ end
+
+ def is_a_short_url?(input)
+ input.match(/^http:\/\//)
+ end
+
+ def get_method(method, input)
+ input = [input] if input.is_a? String
+ query = []
+ input.each do |i|
+ if is_a_short_url?(i)
+ query << "shortUrl=#{CGI.escape(i)}"
+ else
+ query << "hash=#{CGI.escape(i)}"
+ end
+ end
+ query = "/#{method}?" + query.join('&')
+ response = get(query)
+ results = []
+ response['data'][method.to_s].each do |url|
+ if url['error'].nil?
+ # builds the results array in the same order as the input
+ results[input.index(url['short_url'] || url['hash'])] = Bitly::V3::Url.new(self, url)
+ # remove the key from the original array, in case the same hash/url was entered twice
+ input[input.index(url['short_url'] || url['hash'])] = nil
+ else
+ results[input.index(url['short_url'] || url['hash'])] = Bitly::V3::MissingUrl.new(url)
+ input[input.index(url['short_url'] || url['hash'])] = nil
+ end
+ end
+ return results.length > 1 ? results : results[0]
+ end
+
+ end
+ end
+end
@@ -0,0 +1,14 @@
+module Bitly
+ module V3
+ class MissingUrl
+ attr_accessor :short_url, :user_hash, :error
+ def initialize(opts={})
+ if opts
+ @short_url = opts['short_url']
+ @user_hash = opts['hash']
+ @error = opts['error']
+ end
+ end
+ end
+ end
+end
View
@@ -0,0 +1,53 @@
+module Bitly
+ module V3
+ # Url objects should only be created by the client object as it collects the correct information
+ # from the API.
+ class Url
+ attr_reader :short_url, :long_url, :user_hash, :global_hash
+
+ # Initialize with a bitly client and optional hash to fill in the details for the url.
+ def initialize(client, opts={})
+ @client = client
+ if opts
+ @short_url = opts['url']
+ @long_url = opts['long_url']
+ @user_hash = opts['hash']
+ @global_hash = opts['global_hash']
+ @new_hash = (opts['new_hash'] == 1)
+ @user_clicks = opts['user_clicks']
+ @global_clicks = opts['global_clicks']
+ end
+ @short_url = "http://bit.ly/#{@user_hash}" unless @short_url
+ end
+
+ # Returns true if the user hash was created first for this call
+ def new_hash?
+ @new_hash
+ end
+
+ # If the url already has click statistics, returns the user clicks.
+ # IF there are no click statistics or <tt>:force => true</tt> is passed,
+ # updates the stats and returns the user clicks
+ def user_clicks(opts={})
+ update_clicks_data if @global_clicks.nil? || opts[:force]
+ @user_clicks
+ end
+
+ # If the url already has click statistics, returns the global clicks.
+ # IF there are no click statistics or <tt>:force => true</tt> is passed,
+ # updates the stats and returns the global clicks
+ def global_clicks(opts={})
+ update_clicks_data if @global_clicks.nil? || opts[:force]
+ @global_clicks
+ end
+
+ private
+
+ def update_clicks_data
+ full_url = @client.clicks(@user_hash || @short_url)
+ @global_clicks = full_url.global_clicks
+ @user_clicks = full_url.user_clicks
+ end
+ end
+ end
+end
View
@@ -1,3 +1,3 @@
module Bitly
- VERSION = '0.4.0'
+ VERSION = '0.5.0'
end
View
@@ -26,4 +26,10 @@ def api_key
end
def login
'test_account'
+end
+
+class Test::Unit::TestCase
+ def teardown
+ FakeWeb.clean_registry
+ end
end

0 comments on commit c62b433

Please sign in to comment.