Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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

  • Loading branch information...
commit c62b433371dd72679da7c3413a755e1cf60853d4 1 parent eeb0cec
@philnash authored
View
7 History.txt
@@ -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
5 Manifest
@@ -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
14 README.txt
@@ -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
2  Rakefile
@@ -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
3  lib/bitly.rb
@@ -5,4 +5,5 @@
require 'bitly/utils'
require 'bitly/client'
require 'bitly/url'
-require 'bitly/version'
+require 'bitly/version'
+require 'bitly/v3'
View
15 lib/bitly/client.rb
@@ -7,7 +7,19 @@ 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
@@ -15,6 +27,7 @@ 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
4 lib/bitly/utils.rb
@@ -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
9 lib/bitly/v3.rb
@@ -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
16 lib/bitly/v3/bitly.rb
@@ -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
103 lib/bitly/v3/client.rb
@@ -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
View
14 lib/bitly/v3/missing_url.rb
@@ -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
53 lib/bitly/v3/url.rb
@@ -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
2  lib/bitly/version.rb
@@ -1,3 +1,3 @@
module Bitly
- VERSION = '0.4.0'
+ VERSION = '0.5.0'
end
View
6 test/test_helper.rb
@@ -26,4 +26,10 @@ def api_key
end
def login
'test_account'
+end
+
+class Test::Unit::TestCase
+ def teardown
+ FakeWeb.clean_registry
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.