bitly 0.2

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