bitly 0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,34 @@
1
+ === 0.2 / 2009-06-23
2
+
3
+ * 1 enhancement
4
+
5
+ * Depends on Crack instead of JSON, so can run on Jruby
6
+
7
+ * 1 bug fix
8
+
9
+ * Does not choke when bit.ly chokes. Returns a BitlyError instead
10
+
11
+ === 0.1.4 / 2009-04-13
12
+
13
+ * 1 bug fix
14
+
15
+ * Urls with parameters were choking, changed to using CGI.
16
+
17
+ === 0.1.2 / 2009-03-12
18
+
19
+ * 1 minor enhancement
20
+
21
+ * Allows to add a keyword for shortening urls
22
+
23
+ === 0.1.1 / 2009-01-26
24
+
25
+ * 1 bug fix
26
+
27
+ * Didn't include dependency on JSON
28
+
29
+ === 0.1.0 / 2009-01-26
30
+
31
+ * 1 major enhancement
32
+
33
+ * First release
34
+
@@ -0,0 +1,11 @@
1
+ bitly.gemspec
2
+ History.txt
3
+ lib/bitly/client.rb
4
+ lib/bitly/url.rb
5
+ lib/bitly/utils.rb
6
+ lib/bitly/version.rb
7
+ lib/bitly.rb
8
+ Manifest
9
+ Rakefile
10
+ README.txt
11
+ test/test_bitly.rb
@@ -0,0 +1,63 @@
1
+ = bitly
2
+
3
+ == DESCRIPTION:
4
+
5
+ A Ruby API for bit.ly
6
+
7
+ http://code.google.com/p/bitly-api/wiki/ApiDocumentation
8
+
9
+ == USAGE:
10
+
11
+ Create a Bitly client using your username and api key as follows:
12
+
13
+ bitly = Bitly.new(username, api_key)
14
+
15
+ You can then use that client to shorten or expand urls or return more information or statistics as so:
16
+
17
+ bitly.shorten('http://www.google.com')
18
+ bitly.shorten('http://www.google.com', 'keyword') # returns a shortened url using the given keyword
19
+ bitly.expand('wQaT')
20
+ bitly.info('http://bit.ly/wQaT')
21
+ bitly.stats('http://bit.ly/wQaT')
22
+
23
+ Each can be used in all the methods described in the API docs, the shorten function, for example, takes a url or an array of urls.
24
+
25
+ All four functions return a Bitly::Url object (or an array of Bitly::Url objects if you supplied an array as the input). You can then get all the information required from that object.
26
+
27
+ u = bitly.shorten('http://www.google.com') #=> Bitly::Url
28
+
29
+ u.long_url #=> "http://www.google.com"
30
+ u.short_url #=> "http://bit.ly/Ywd1"
31
+ u.user_hash #=> "Ywd1"
32
+ u.hash #=> "2V6CFi"
33
+ u.info #=> a ruby hash of the JSON returned from the API
34
+ u.stats #=> a ruby hash of the JSON returned from the API
35
+
36
+ You should be able to specify a keyword when shortening (though at last test, this didn't seem to be working http://code.google.com/p/bitly-api/issues/detail?id=5). To do so, just add a keyword parameter:
37
+
38
+ bitly.shorten('http://www.google.com', 'keyword')
39
+
40
+ == LICENSE:
41
+
42
+ (The MIT License)
43
+
44
+ Copyright (c) 2009 Phil Nash
45
+
46
+ Permission is hereby granted, free of charge, to any person obtaining
47
+ a copy of this software and associated documentation files (the
48
+ 'Software'), to deal in the Software without restriction, including
49
+ without limitation the rights to use, copy, modify, merge, publish,
50
+ distribute, sublicense, and/or sell copies of the Software, and to
51
+ permit persons to whom the Software is furnished to do so, subject to
52
+ the following conditions:
53
+
54
+ The above copyright notice and this permission notice shall be
55
+ included in all copies or substantial portions of the Software.
56
+
57
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
58
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
59
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
60
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
61
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
62
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
63
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+ require 'echoe'
6
+ require './lib/bitly.rb'
7
+
8
+ # modified by coryosborn to remove native JSON dependency
9
+
10
+ Echoe.new('bitly', Bitly::VERSION) do |p|
11
+ p.description = "Use the bit.ly API to shorten or expand URLs"
12
+ p.url = "http://github.com/philnash/bitly"
13
+ p.author = "Phil Nash"
14
+ p.email = "philnash@gmail.com"
15
+ p.extra_deps = [['crack', '>= 0.1.1']]
16
+ p.development_dependencies = []
17
+ end
18
+
19
+ # vim: syntax=Ruby
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{bitly}
5
+ s.version = "0.2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Phil Nash"]
9
+ s.date = %q{2009-06-23}
10
+ s.description = %q{Use the bit.ly API to shorten or expand URLs}
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/test_bitly.rb"]
14
+ s.homepage = %q{http://github.com/philnash/bitly}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Bitly", "--main", "README.txt"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{bitly}
18
+ s.rubygems_version = %q{1.3.4}
19
+ s.summary = %q{Use the bit.ly API to shorten or expand URLs}
20
+ s.test_files = ["test/test_bitly.rb"]
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 3
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ s.add_runtime_dependency(%q<crack>, [">= 0.1.1"])
28
+ else
29
+ s.add_dependency(%q<crack>, [">= 0.1.1"])
30
+ end
31
+ else
32
+ s.add_dependency(%q<crack>, [">= 0.1.1"])
33
+ end
34
+ end
@@ -0,0 +1,10 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'rubygems'
4
+ gem 'crack'
5
+ require 'crack'
6
+
7
+ require 'bitly/utils'
8
+ require 'bitly/client'
9
+ require 'bitly/url'
10
+ require 'bitly/version'
@@ -0,0 +1,148 @@
1
+ require 'rubygems'
2
+ require 'net/http'
3
+ require 'uri'
4
+
5
+ module Bitly
6
+ API_URL = 'http://api.bit.ly/'
7
+ API_VERSION = '2.0.1'
8
+
9
+ def self.new(login, api_key)
10
+ Bitly::Client.new(login,api_key)
11
+ end
12
+
13
+ class Client
14
+
15
+ include Bitly::Utils
16
+
17
+ def initialize(login,api_key)
18
+ @login = login
19
+ @api_key = api_key
20
+ end
21
+
22
+ def shorten(input, keyword=nil)
23
+ if input.is_a? String
24
+ request = create_url "shorten", :longUrl => input, :keyword => keyword
25
+ result = get_result(request)
26
+ result = {:long_url => input}.merge result[input]
27
+ Bitly::Url.new(@login,@api_key,result)
28
+ elsif input.is_a? Array
29
+ request = create_url "shorten"
30
+ request.query << "&" + input.map { |long_url| "longUrl=#{CGI.escape(long_url)}" }.join("&") unless input.nil?
31
+ result = get_result(request)
32
+ input.map do |long_url|
33
+ new_url = {:long_url => long_url}.merge result[long_url]
34
+ long_url = Bitly::Url.new(@login,@api_key,new_url)
35
+ end
36
+ else
37
+ raise ArgumentError
38
+ end
39
+ end
40
+
41
+ def expand(input)
42
+ if input.is_a? String
43
+ if input.include? "bit.ly/"
44
+ hash = input.gsub(/^.*bit.ly\//,'')
45
+ request = create_url "expand", :hash => hash
46
+ result = get_result(request)
47
+ result = { :short_url => input, :hash => hash }.merge result[hash]
48
+ else
49
+ request = create_url "expand", :hash => input
50
+ result = get_result(request)
51
+ result = { :hash => input, :short_url => "http://bit.ly/#{input}" }.merge result[input]
52
+ end
53
+ Bitly::Url.new(@login,@api_key,result)
54
+ elsif input.is_a? Array
55
+ request = create_url "expand", :hash => input.join(',')
56
+ result = get_result(request)
57
+ input.map do |hsh|
58
+ new_url = {:hash => hsh, :short_url => "http://bit.ly/#{hsh}"}.merge result[hsh]
59
+ hsh = Bitly::Url.new(@login,@api_key,new_url)
60
+ end
61
+ else
62
+ raise ArgumentError
63
+ end
64
+ end
65
+
66
+ def info(input)
67
+ if input.is_a? String
68
+ if input.include? "bit.ly/"
69
+ hash = input.gsub(/^.*bit.ly\//,'')
70
+ request = create_url 'info', :hash => hash
71
+ result = get_result(request)
72
+ result = { :short_url => "http://bit.ly/#{hash}", :hash => hash }.merge result[hash]
73
+ else
74
+ request = create_url 'info', :hash => input
75
+ result = get_result(request)
76
+ result = { :short_url => "http://bit.ly/#{input}", :hash => input }.merge result[input]
77
+ end
78
+ Bitly::Url.new(@login,@api_key,result)
79
+ elsif input.is_a? Array
80
+ request = create_url "info", :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,:info => new_url)
85
+ end
86
+ end
87
+ end
88
+
89
+ def stats(input)
90
+ if input.is_a? String
91
+ if input.include? "bit.ly/"
92
+ hash = input.gsub(/^.*bit.ly\//,'')
93
+ request = create_url 'stats', :hash => hash
94
+ result = get_result(request)
95
+ result = { :short_url => "http://bit.ly/#{hash}", :hash => hash }.merge result
96
+ else
97
+ request = create_url 'stats', :hash => input
98
+ result = get_result(request)
99
+ result = { :short_url => "http://bit.ly/#{input}", :hash => input }.merge result
100
+ end
101
+ Bitly::Url.new(@login,@api_key,:stats => result)
102
+ else
103
+ raise ArgumentError
104
+ end
105
+ end
106
+
107
+ end
108
+
109
+ end
110
+
111
+ class BitlyError < StandardError
112
+ attr_reader :code
113
+ alias :msg :message
114
+ def initialize(msg, code, req)
115
+ @code = code
116
+ super("'#{req}' - #{msg}")
117
+ end
118
+ end
119
+
120
+
121
+ # How it should work
122
+ # ==================
123
+ # bitly = Bitly::Base.new('philnash','R_7776acc394294b2b0ad2c261a91c483d')
124
+ # bitly.shorten("http://www.google.com")
125
+ # #=> Bitly::Url
126
+ # bitly.shorten(["http://www.google.com","http://cnn.com"])
127
+ # #=> [Bitly::Url,Bitly::Url]
128
+ #
129
+ # bitly.expand("http://bit.ly/wIRm")
130
+ # #=> Bitly::Url
131
+ # bitly.expand("wIRm")
132
+ # #=> Bitly::Url
133
+ # bitly.expand(["wIRm","sdfsd"])
134
+ # #=> [Bitly::Url,Bitly::Url]
135
+ #
136
+ # bitly.info("http://bit.ly/wIRm") || bitly.info("wIRm")
137
+ # #=> b = Bitly::Url
138
+ # #=> b.info #=> hash of data back from info
139
+ # bitly.info(['wIRm','qsads'])
140
+ # #=> [Bitly::Url, Bitly::Url]
141
+ # also, with any url = Bitly::Url
142
+ # url.info #=> hash of info data
143
+
144
+ # bitly.stats("http://bit.ly/wIRm") || bitly.stats("wIRm")
145
+ # #=> b = Bitly::Url
146
+ # #=> b.stats #=> hash of stats
147
+ # also, any url = Bitly::Url
148
+ # url.stats #=> hash of stats
@@ -0,0 +1,57 @@
1
+ module Bitly
2
+
3
+ class Url
4
+ include Bitly::Utils
5
+
6
+ VARIABLES = ['long_url', 'short_url', 'hash', 'user_hash', 'short_keyword_url']
7
+
8
+ def initialize(login,api_key,obj=nil)
9
+ unless obj.nil?
10
+
11
+ raise BitlyError.new(obj['errorMessage'],obj['errorCode'],'expand') if obj['statusCode'] == "ERROR"
12
+
13
+ instance_variablise(obj, VARIABLES)
14
+ @info = obj[:info] if obj[:info]
15
+ @stats = obj[:stats] if obj[:stats]
16
+ end
17
+ @login = login
18
+ @api_key = api_key
19
+ end
20
+
21
+ def info
22
+ if @info.nil?
23
+ if @hash
24
+ request = create_url "info", :hash => @hash
25
+ result = get_result(request)[@hash]
26
+ instance_variablise(result, VARIABLES)
27
+ @info = result
28
+ elsif @short_url
29
+ hash = @short_url.gsub(/^.*bit.ly\//,'')
30
+ request = create_url "info", :hash => hash
31
+ result = get_result(request)[hash]
32
+ instance_variablise(result, VARIABLES)
33
+ @info = result
34
+ else
35
+ nil
36
+ end
37
+ else
38
+ @info
39
+ end
40
+ end
41
+
42
+ def stats
43
+ if @stats.nil?
44
+ if @hash
45
+ request = create_url "stats", :hash => @hash
46
+ elsif @short_url
47
+ request = create_url "stats", :shortUrl => @short_url
48
+ end
49
+ @stats = get_result(request)
50
+ else
51
+ @stats
52
+ end
53
+ end
54
+
55
+ end
56
+
57
+ end
@@ -0,0 +1,55 @@
1
+ require 'cgi'
2
+
3
+ module Bitly
4
+ module Utils
5
+ private
6
+ def underscore(camel_cased_word) # stolen from rails
7
+ camel_cased_word.to_s.gsub(/::/, '/').
8
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
9
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
10
+ tr("-", "_").
11
+ downcase
12
+ end
13
+
14
+ def attr_define(k,v)
15
+ instance_variable_set("@#{k}", v)
16
+ meta = class << self; self; end
17
+ meta.class_eval { attr_reader k.to_sym }
18
+ end
19
+
20
+ def instance_variablise(obj,variables)
21
+ if obj.is_a? Hash
22
+ obj.each do |k,v|
23
+ if v.is_a? Hash
24
+ instance_variablise(v,variables)
25
+ else
26
+ attr_define(underscore(k),v) if variables.include?(underscore(k))
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ def create_url(resource="",args={})
33
+ args = args.merge({:login => @login, :apiKey => @api_key, :version => API_VERSION})
34
+ url = URI.join(API_URL,resource)
35
+ long_urls = args.delete(:long_urls)
36
+ url.query = args.map { |k,v| "%s=%s" % [CGI.escape(k.to_s), CGI.escape(v.to_s)] }.join("&")
37
+ url.query << "&" + long_urls.map { |long_url| "longUrl=#{CGI.escape(long_url)}" }.join("&") unless long_urls.nil?
38
+ url
39
+ end
40
+
41
+ def get_result(request)
42
+ begin
43
+ result = Crack::JSON.parse(Net::HTTP.get(request))
44
+ rescue
45
+ result = {'statusCode' => 'JSON Parse Error(Bit.ly messed up)', 'errorCode' => 69}
46
+ end
47
+ if result['statusCode'] == "OK"
48
+ result = result['results']
49
+ else
50
+ raise BitlyError.new(result['errorMessage'],result['errorCode'],'expand')
51
+ end
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,3 @@
1
+ module Bitly
2
+ VERSION = '0.2'
3
+ end
@@ -0,0 +1,65 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'bitly'
4
+
5
+ class TestBitly < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @api_key = 'R_7776acc394294b2b0ad2c261a91c483d'
9
+ @login = 'philnash'
10
+ @bitly = Bitly.new(@login,@api_key)
11
+ end
12
+
13
+ # not a good test, but it makes sure things are working for now.
14
+ def test_returns_short_url
15
+ url = @bitly.shorten("http://google.com")
16
+ assert_kind_of Bitly::Url, url
17
+ assert_equal "http://google.com", url.long_url
18
+ assert_equal "http://bit.ly/wQaT", url.short_url
19
+ urls = @bitly.shorten(["http://google.com","http://cnn.com"])
20
+ assert_equal "http://google.com", urls[0].long_url
21
+ assert_equal "http://bit.ly/wQaT", urls[0].short_url
22
+ url = @bitly.shorten("http://www.google.com/search?hl=en&q=url&btnG=Google+Search&aq=f&oq=")
23
+ assert_kind_of Bitly::Url, url
24
+ assert_equal "http://www.google.com/search?hl=en&q=url&btnG=Google+Search&aq=f&oq=", url.long_url
25
+ assert_equal "http://bit.ly/NqK6i", url.short_url
26
+ end
27
+
28
+ def test_returns_a_long_url
29
+ urls = @bitly.expand(["2bYgqR","1RmnUT"])
30
+ assert_kind_of Bitly::Url, urls[0]
31
+ assert_equal "http://cnn.com", urls[0].long_url
32
+ assert_equal "2bYgqR", urls[0].hash
33
+ assert_equal "http://google.com", urls[1].long_url
34
+ assert_equal "1RmnUT", urls[1].hash
35
+ url = @bitly.expand("http://bit.ly/wQaT")
36
+ assert_kind_of Bitly::Url, url
37
+ assert_equal "http://bit.ly/wQaT", url.short_url
38
+ assert_equal "http://google.com/", url.long_url
39
+ assert_equal "wQaT", url.hash
40
+ url2 = @bitly.expand("wQaT")
41
+ assert_kind_of Bitly::Url, url2
42
+ assert_equal "wQaT", url2.hash
43
+ assert_equal "http://bit.ly/wQaT", url2.short_url
44
+ assert_equal "http://google.com/", url2.long_url
45
+ end
46
+
47
+ def test_returns_keyword_url
48
+ #kind of ghetto test but we need it to be different every time
49
+ require 'digest/sha1'
50
+ keyword = Digest::SHA1.hexdigest(DateTime.now.to_s)
51
+
52
+ url = @bitly.shorten("http://google.com", keyword)
53
+ assert_equal url.short_keyword_url, "http://bit.ly/#{keyword}"
54
+ end
55
+
56
+ def test_returns_error_on_existing_keyword
57
+ keyword = 'apple'
58
+ assert_raise BitlyError do
59
+ @bitly.shorten("http://apple.com/itunes", keyword)
60
+ end
61
+ end
62
+
63
+
64
+
65
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bitly
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.2"
5
+ platform: ruby
6
+ authors:
7
+ - Phil Nash
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-23 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: crack
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.1.1
24
+ version:
25
+ description: Use the bit.ly API to shorten or expand URLs
26
+ email: philnash@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - lib/bitly/client.rb
33
+ - lib/bitly/url.rb
34
+ - lib/bitly/utils.rb
35
+ - lib/bitly/version.rb
36
+ - lib/bitly.rb
37
+ - README.txt
38
+ files:
39
+ - bitly.gemspec
40
+ - History.txt
41
+ - lib/bitly/client.rb
42
+ - lib/bitly/url.rb
43
+ - lib/bitly/utils.rb
44
+ - lib/bitly/version.rb
45
+ - lib/bitly.rb
46
+ - Manifest
47
+ - Rakefile
48
+ - README.txt
49
+ - test/test_bitly.rb
50
+ has_rdoc: true
51
+ homepage: http://github.com/philnash/bitly
52
+ licenses: []
53
+
54
+ post_install_message:
55
+ rdoc_options:
56
+ - --line-numbers
57
+ - --inline-source
58
+ - --title
59
+ - Bitly
60
+ - --main
61
+ - README.txt
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ version:
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "1.2"
75
+ version:
76
+ requirements: []
77
+
78
+ rubyforge_project: bitly
79
+ rubygems_version: 1.3.4
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: Use the bit.ly API to shorten or expand URLs
83
+ test_files:
84
+ - test/test_bitly.rb