bitly4r 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +12 -0
- data/README.rdoc +17 -11
- data/Rakefile +67 -108
- data/bitly4r.gemspec +43 -0
- data/container +5 -0
- data/lib/bitly4r/client.rb +94 -119
- data/lib/bitly4r/definitions.rb +5 -19
- data/lib/bitly4r/objects.rb +16 -13
- data/lib/bitly4r.rb +3 -1
- data/test/client_test.rb +42 -81
- data/test/definitions_test.rb +14 -32
- data/test/objects_test.rb +7 -8
- data/test/test_helper.rb +10 -17
- metadata +36 -41
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8526b72584f4eeb4175cf447451f8aeb5db38d3d4285a98b710dc7d113147762
|
4
|
+
data.tar.gz: ab0137814f7761acf5c19c4eff4653d84e81a2f3276be962cd0edba94d44489d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6c170ec3149dc568e58b0efec03e55566d3fa53a6df8620eb241f0c583735daf8c777b15b3128a11b95887fd69f58e2dae40b2e67d3c0584cb0e7828bfa0c616
|
7
|
+
data.tar.gz: 87f9651ee1d6154015f2420950c6934f0bdb42c3b5208fcab516310d24f2e8b6894c2f88deaadc216bceabef3a83a2834b8920e13bfceb4cf52d9b6c5508915f
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
= 0.2.0
|
2
|
+
|
3
|
+
* upgrade to bit.ly API version 4.0.0
|
4
|
+
* upgrade to Ruby 3
|
5
|
+
* remove login + password + api_key, replace with Authentication Token (token)
|
6
|
+
* the 'stats' and 'errors' methods are obsolete
|
7
|
+
* a `TOKEN` environment variable must be passed to the Test Suite
|
8
|
+
|
9
|
+
= 0.1.1
|
10
|
+
|
11
|
+
* the build never included 'bitly4r.gemspec'
|
12
|
+
|
1
13
|
= 0.1.0
|
2
14
|
|
3
15
|
* Initial gem release of 0.1 coebase.
|
data/README.rdoc
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
A Ruby API for the http://bit.ly URL-shortening service
|
4
4
|
|
5
|
+
|
5
6
|
== SimpleClient
|
6
7
|
|
7
8
|
This example uses a simpler construction and invocation technique.
|
@@ -10,17 +11,19 @@ For when you just need the URLs, and not any additional data.
|
|
10
11
|
require 'rubygems'
|
11
12
|
require 'bitly4r'
|
12
13
|
|
13
|
-
|
14
|
+
access_token = ENV['TOKEN']
|
14
15
|
long_url = 'http://rubyforge.org/'
|
15
16
|
|
16
|
-
client = Bitly4R.
|
17
|
+
client = Bitly4R.Token(access_token)
|
17
18
|
|
18
19
|
# shorten
|
19
20
|
short_url = client.shorten(long_url)
|
21
|
+
puts "short_url = #{short_url}"
|
20
22
|
|
21
23
|
# re-expand
|
22
24
|
raise 'what the?' unless (long_url == client.expand(short_url))
|
23
25
|
|
26
|
+
|
24
27
|
== Client
|
25
28
|
|
26
29
|
This example uses a full-fledged construction and invocation technique.
|
@@ -29,36 +32,39 @@ The URLs are returned by the <tt>to_s</tt> methods of the Response objects, and
|
|
29
32
|
require 'rubygems'
|
30
33
|
require 'bitly4r'
|
31
34
|
|
32
|
-
|
35
|
+
access_token = ENV['TOKEN']
|
33
36
|
long_url = 'http://rubyforge.org/'
|
34
37
|
|
35
|
-
client = Bitly4R::Client.new(:
|
38
|
+
client = Bitly4R::Client.new(:token => access_token)
|
36
39
|
|
37
40
|
# shorten
|
38
41
|
short_url = client.shorten(long_url).to_s
|
42
|
+
puts "short_url = #{short_url}"
|
39
43
|
|
40
44
|
# re-expand
|
41
45
|
raise 'aww, cmon!' unless (long_url == client.expand(short_url).to_s)
|
42
46
|
|
47
|
+
|
43
48
|
== Support
|
44
49
|
|
50
|
+
This Client uses version 4.0.0 of the API (eg. '/v4/*').
|
51
|
+
It supports Access Token credentials.
|
52
|
+
|
45
53
|
This gem supports the following API commands:
|
46
54
|
|
47
|
-
* shorten
|
48
|
-
* expand
|
49
|
-
*
|
50
|
-
* stats
|
51
|
-
* errors
|
55
|
+
* `POST /v4/shorten`
|
56
|
+
* `POST /v4/expand`
|
57
|
+
* `GET /v4/bitlinks/:bitlink`
|
52
58
|
|
53
59
|
For more information, see the API documentation:
|
54
60
|
|
55
|
-
* http://
|
61
|
+
* http://cantremember.github.io/bitly4r/
|
56
62
|
|
57
63
|
== Contributing
|
58
64
|
|
59
65
|
=== Issue Tracking and Feature Requests
|
60
66
|
|
61
|
-
*
|
67
|
+
* https://github.com/cantremember/bitly4r
|
62
68
|
|
63
69
|
== Community
|
64
70
|
|
data/Rakefile
CHANGED
@@ -6,33 +6,30 @@ task :default => :test
|
|
6
6
|
|
7
7
|
# SPECS ===============================================================
|
8
8
|
|
9
|
-
desc 'Run specs with story style output'
|
10
|
-
task :spec do
|
11
|
-
sh 'specrb --specdox -Ilib:test test/*_test.rb'
|
12
|
-
end
|
13
|
-
|
14
9
|
desc 'Run specs with unit test style output'
|
15
10
|
task :test => FileList['test/*_test.rb'] do |t|
|
16
|
-
|
17
|
-
|
11
|
+
suite = t.prerequisites.join(' ')
|
12
|
+
sh "ruby -Ilib:test #{suite}", :verbose => false
|
18
13
|
end
|
19
14
|
|
20
15
|
# PACKAGING ============================================================
|
21
16
|
|
22
17
|
# Load the gemspec using the same limitations as github
|
23
18
|
def spec
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
19
|
+
@spec ||=
|
20
|
+
begin
|
21
|
+
require 'rubygems/specification'
|
22
|
+
data = File.read('bitly4r.gemspec')
|
23
|
+
spec = nil
|
24
|
+
# OS X didn't like SAFE = 2
|
25
|
+
# (eval):25:in `glob': Insecure operation - glob
|
26
|
+
Thread.new { spec = eval("$SAFE = 2\n#{data}") }.join
|
27
|
+
spec
|
28
|
+
end
|
32
29
|
end
|
33
30
|
|
34
31
|
def package(ext='')
|
35
|
-
|
32
|
+
"dist/bitly4r-#{spec.version}" + ext
|
36
33
|
end
|
37
34
|
|
38
35
|
desc 'Build packages'
|
@@ -40,123 +37,85 @@ task :package => %w[.gem .tar.gz].map {|e| package(e)}
|
|
40
37
|
|
41
38
|
desc 'Build and install as local gem'
|
42
39
|
task :install => package('.gem') do
|
43
|
-
|
40
|
+
sh "gem install #{package('.gem')}"
|
44
41
|
end
|
45
42
|
|
46
43
|
directory 'dist/'
|
47
44
|
|
48
|
-
file package('.gem') => %w[dist/
|
49
|
-
|
50
|
-
|
45
|
+
file package('.gem') => %w[dist/ bitly4r.gemspec] + spec.files do |f|
|
46
|
+
sh "gem build bitly4r.gemspec"
|
47
|
+
mv File.basename(f.name), f.name
|
51
48
|
end
|
52
49
|
|
53
50
|
file package('.tar.gz') => %w[dist/] + spec.files do |f|
|
54
|
-
|
51
|
+
sh "git archive --format=tar HEAD | gzip > #{f.name}"
|
55
52
|
end
|
56
53
|
|
57
|
-
#
|
54
|
+
# Release / Publish Tasks ==================================
|
58
55
|
|
59
56
|
desc 'Publish website to rubyforge'
|
60
|
-
task 'publish:doc' => 'doc/api/index.html' do
|
61
|
-
sh 'scp -rp doc/* rubyforge.org:/var/www/gforge-projects/sinatra/'
|
62
|
-
end
|
63
57
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
58
|
+
# https://guides.rubygems.org/publishing/#publishing-to-rubygemsorg
|
59
|
+
task 'publish:gem' => [package('.gem')] do |t|
|
60
|
+
sh <<-end
|
61
|
+
gem push #{package('.gem')}
|
62
|
+
end
|
69
63
|
end
|
70
64
|
|
71
65
|
# Website ============================================================
|
72
|
-
# Building docs
|
73
|
-
# gem install mislav-hanna --source=http://gems.github.com
|
66
|
+
# Building docs
|
74
67
|
|
75
|
-
|
68
|
+
=begin
|
69
|
+
NOTE: i honestly don't know how `rake doc` is working
|
70
|
+
but it does!
|
76
71
|
|
77
|
-
|
78
|
-
|
72
|
+
Manual process for publish to Github Pages
|
73
|
+
http://cantremember.github.io/bitly4r/
|
79
74
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
hanna --charset utf8 \
|
84
|
-
--fmt html \
|
85
|
-
--inline-source \
|
86
|
-
--line-numbers \
|
87
|
-
--main README.rdoc \
|
88
|
-
--op doc/api \
|
89
|
-
--title 'Sinatra API Documentation' \
|
90
|
-
#{rb_files.join(' ')}
|
91
|
-
end
|
92
|
-
end
|
93
|
-
CLEAN.include 'doc/api'
|
75
|
+
```bash
|
76
|
+
# no outstanding Git changes, then ...
|
77
|
+
rake doc
|
94
78
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
rdoc.convert(File.read(file_name))
|
99
|
-
end
|
79
|
+
git checkout gh-pages
|
80
|
+
cp -r doc/* .
|
81
|
+
git add .
|
100
82
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
haml = Haml::Engine.new(template, :format => :html4, :attr_wrapper => '"')
|
105
|
-
haml.render(Object.new, locals)
|
106
|
-
end
|
83
|
+
# commit & push
|
84
|
+
```
|
85
|
+
=end
|
107
86
|
|
108
|
-
|
109
|
-
task 'doc:site' => ['doc/index.html', 'doc/book.html']
|
87
|
+
task 'doc' => ['doc:api']
|
110
88
|
|
111
|
-
|
112
|
-
|
113
|
-
file << haml(:title => 'Sinatra', :content => rdoc_to_html('README.rdoc'))
|
114
|
-
end
|
115
|
-
end
|
116
|
-
CLEAN.include 'doc/index.html'
|
89
|
+
desc 'Generate RDoc under doc/api'
|
90
|
+
task 'doc:api' => ['doc/api/index.html']
|
117
91
|
|
118
|
-
file 'doc/
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
92
|
+
file 'doc/api/index.html' => FileList['lib/**/*.rb','README.rdoc','CHANGELOG','LICENSE'] do |f|
|
93
|
+
rb_files = f.prerequisites
|
94
|
+
sh((<<-end).gsub(/\s+/, ' '))
|
95
|
+
rdoc --line-numbers --inline-source --title Bitly4R --main README.rdoc
|
96
|
+
#{rb_files.join(' ')}
|
97
|
+
end
|
123
98
|
end
|
124
|
-
CLEAN.include 'doc/
|
125
|
-
|
126
|
-
file 'book/output/sinatra-book.html' => FileList['book/**'] do |f|
|
127
|
-
unless File.directory?('book')
|
128
|
-
sh 'git clone git://github.com/cschneid/sinatra-book.git book'
|
129
|
-
end
|
130
|
-
sh((<<-SH).strip.gsub(/\s+/, ' '))
|
131
|
-
cd book &&
|
132
|
-
git fetch origin &&
|
133
|
-
git rebase origin/master &&
|
134
|
-
thor book:build
|
135
|
-
SH
|
136
|
-
end
|
137
|
-
CLEAN.include 'book/output/sinatra-book.html'
|
138
|
-
|
139
|
-
desc 'Build the Sinatra book'
|
140
|
-
task 'doc:book' => ['book/output/sinatra-book.html']
|
99
|
+
CLEAN.include 'doc/api'
|
141
100
|
|
142
101
|
# Gemspec Helpers ====================================================
|
143
102
|
|
144
|
-
file '
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
103
|
+
file 'bitly4r.gemspec' => FileList['{lib,test}/**','Rakefile'] do |f|
|
104
|
+
# read spec file and split out manifest section
|
105
|
+
spec = File.read(f.name)
|
106
|
+
parts = spec.split("# = MANIFEST =\n")
|
107
|
+
fail 'bad spec' if parts.length != 3
|
108
|
+
# determine file list from git ls-files
|
109
|
+
files = `git ls-files`.
|
110
|
+
split("\n").
|
111
|
+
sort.
|
112
|
+
reject{ |file| file =~ /^\./ }.
|
113
|
+
reject { |file| file =~ /^doc/ }.
|
114
|
+
map{ |file| " #{file}" }.
|
115
|
+
join("\n")
|
116
|
+
# piece file back together and write...
|
117
|
+
parts[1] = " s.files = %w[\n#{files}\n ]\n"
|
118
|
+
spec = parts.join("# = MANIFEST =\n")
|
119
|
+
File.open(f.name, 'w') { |io| io.write(spec) }
|
120
|
+
puts "updated #{f.name}"
|
162
121
|
end
|
data/bitly4r.gemspec
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.required_ruby_version = '>= 3.0'
|
3
|
+
|
4
|
+
s.name = 'bitly4r'
|
5
|
+
s.version = '0.2.0'
|
6
|
+
# s.date = "2023-04-30"
|
7
|
+
|
8
|
+
s.description = "Bitly4R : A Ruby API for the http://bit.ly URL-shortening service"
|
9
|
+
s.summary = "#{s.name} #{s.version}"
|
10
|
+
|
11
|
+
s.homepage = "http://wiki.cantremember.com/Bitly4R"
|
12
|
+
s.authors = ["Dan Foley"]
|
13
|
+
s.email = 'admin@cantremember.com'
|
14
|
+
s.license = 'WTFPL'
|
15
|
+
|
16
|
+
# = MANIFEST =
|
17
|
+
s.files = %w[
|
18
|
+
CHANGELOG
|
19
|
+
LICENSE
|
20
|
+
README.rdoc
|
21
|
+
Rakefile
|
22
|
+
bitly4r.gemspec
|
23
|
+
container
|
24
|
+
lib/bitly4r.rb
|
25
|
+
lib/bitly4r/client.rb
|
26
|
+
lib/bitly4r/definitions.rb
|
27
|
+
lib/bitly4r/objects.rb
|
28
|
+
test/client_test.rb
|
29
|
+
test/definitions_test.rb
|
30
|
+
test/objects_test.rb
|
31
|
+
test/test_helper.rb
|
32
|
+
]
|
33
|
+
# = MANIFEST =
|
34
|
+
|
35
|
+
s.files += Dir.glob('lib/**/*.rb')
|
36
|
+
# s.test_files = Dir.glob('test/**/*.rb')
|
37
|
+
|
38
|
+
s.require_paths = %w{lib}
|
39
|
+
|
40
|
+
# only because there ain't no spaces in the title ...
|
41
|
+
s.rdoc_options = %w{ --line-numbers --inline-source --title Bitly4R --main README.rdoc }
|
42
|
+
s.extra_rdoc_files = %w{ README.rdoc CHANGELOG LICENSE }
|
43
|
+
end
|
data/container
ADDED
data/lib/bitly4r/client.rb
CHANGED
@@ -9,31 +9,20 @@ module Bitly4R
|
|
9
9
|
#
|
10
10
|
#A client object for accessing the bit.ly API.
|
11
11
|
#
|
12
|
-
|
13
|
-
#*
|
14
|
-
#* Uses XML for marshalling, for cheap & easy text parsing.
|
12
|
+
#* This Client uses version 4.0.0 of the API (eg. '/v4/*').
|
13
|
+
#* It supports Access Token credentials.
|
15
14
|
#
|
16
15
|
#See the API documentation:
|
17
|
-
#*
|
18
|
-
#* http://bit.ly
|
16
|
+
#* https://dev.bitly.com/docs/
|
19
17
|
class Client
|
20
|
-
|
21
|
-
|
22
|
-
BASE_PARAMS[:version] = '2.0.1'
|
23
|
-
BASE_PARAMS[:format] = 'xml'
|
24
|
-
|
25
|
-
#The login credential provided at construction.
|
26
|
-
attr_reader :login
|
27
|
-
#The password credential provided at construction.
|
28
|
-
attr_reader :password
|
29
|
-
#The API key credential provided at construction.
|
30
|
-
attr_reader :api_key
|
18
|
+
#The Access Token credential provided at construction.
|
19
|
+
attr_reader :token
|
31
20
|
|
32
21
|
#Constructs a new client.
|
33
22
|
#
|
34
23
|
#Any tuples provided in the optional Hash are injected into instance variables.
|
35
24
|
#
|
36
|
-
#You must provide
|
25
|
+
#You must provide an Access Token (<tt>token</tt>).
|
37
26
|
def initialize(ops={})
|
38
27
|
# for the readers
|
39
28
|
# not necessary, but polite
|
@@ -41,105 +30,77 @@ module Bitly4R
|
|
41
30
|
instance_variable_set "@#{k}".to_sym, v
|
42
31
|
end
|
43
32
|
|
44
|
-
raise Error.new("you must provide
|
45
|
-
raise Error.new("you must provide either an API key or a password") unless (self.api_key or self.password)
|
46
|
-
|
47
|
-
# now, a client-izec set of parameters
|
48
|
-
@client_params = BASE_PARAMS.clone.merge(ops)
|
33
|
+
raise Error.new("you must provide an Access Token") unless self.token
|
49
34
|
end
|
50
35
|
|
51
36
|
|
52
37
|
#Invokes the API's <b>shorten</b> method.
|
53
38
|
#That's pretty much what makes bit.ly a valuable service.
|
39
|
+
#
|
40
|
+
#https://dev.bitly.com/api-reference/#createBitlink
|
54
41
|
#
|
55
42
|
#A Response is returned.
|
56
|
-
#Response.to_s will return the <tt>
|
57
|
-
#
|
58
|
-
#You can take the shortened URL and re-
|
59
|
-
|
43
|
+
#Response.to_s will return the <tt>link</tt> value.
|
44
|
+
#
|
45
|
+
#You can take the shortened URL and re-expand it.
|
46
|
+
#
|
47
|
+
#<i>ops</i> allows for additional API parameters
|
48
|
+
#<ul>
|
49
|
+
# <li><tt>group_guid</tt></li>
|
50
|
+
# <li><tt>domain</tt></li>
|
51
|
+
#</ul>
|
52
|
+
def shorten(long_url, ops={})
|
60
53
|
return nil unless long_url
|
61
|
-
|
62
|
-
|
63
|
-
|
54
|
+
return execute_post('shorten', :link) do |params|
|
55
|
+
params[:long_url] = long_url
|
56
|
+
params.merge!(ops)
|
57
|
+
end
|
64
58
|
end
|
65
59
|
|
66
60
|
#Invokes the API's <b>expand</b> method.
|
67
61
|
#It reverses a shorten; the original full URL is re-hydrated.
|
62
|
+
#
|
63
|
+
#https://dev.bitly.com/api-reference/#expandBitlink
|
68
64
|
#
|
69
|
-
#For <i>
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
#In this case, provide <tt>:hash</tt> as the <i>param_type</i>.
|
65
|
+
#For <i>url</i>, you can provide a previously-shortened URL from the bit.ly service.
|
66
|
+
#
|
67
|
+
#The URL must provide both a domain (hostname) and a Bitlink ID (path).
|
68
|
+
#A minimum-viable URL would be something along the lines of 'bit.ly/3ADCPDo'.
|
74
69
|
#
|
75
70
|
#A Response is returned.
|
76
|
-
#Response.to_s will return the <tt>
|
77
|
-
def expand(
|
78
|
-
return nil unless
|
79
|
-
|
80
|
-
|
81
|
-
|
71
|
+
#Response.to_s will return the <tt>long_url</tt> value.
|
72
|
+
def expand(url)
|
73
|
+
return nil unless url
|
74
|
+
uri = URI.parse(url)
|
75
|
+
bitlink = "#{uri.host}#{uri.path}"
|
76
|
+
|
77
|
+
return execute_post('expand', :long_url) do |params|
|
78
|
+
params[:bitlink_id] = bitlink
|
79
|
+
end
|
82
80
|
end
|
83
81
|
|
84
82
|
#Invokes the API's <b>info</b> method.
|
85
83
|
#Information about the shortened URL is returned by the service.
|
84
|
+
#
|
85
|
+
#https://dev.bitly.com/api-reference/#getBitlink
|
86
86
|
#
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
#In this case, provide <tt>:hash</tt> as the <i>param_type</i>.
|
92
|
-
#
|
93
|
-
#You can optionally provide an arbitrary Hash of HTTP parameters.
|
94
|
-
#The one that bit.ly cares about is called <tt>:key</tt>.
|
95
|
-
#It should be an array of camel-cased or underscored element names which you would like to receive.
|
96
|
-
#In theory, this should limit the response content, but I haven't seen that work yet.
|
97
|
-
#The arbitrary Hash capability is left intact for future re-purposing.
|
87
|
+
#For <i>url</i>, you can provide a previously-shortened URL from the bit.ly service.
|
88
|
+
#
|
89
|
+
#The URL must provide both a domain (hostname) and a Bitlink ID (path).
|
90
|
+
#A minimum-viable URL would be something along the lines of 'bit.ly/3ADCPDo'.
|
98
91
|
#
|
99
92
|
#A Response is returned.
|
100
|
-
#Response.to_s will return the <tt>
|
93
|
+
#Response.to_s will return the <tt>long_url</tt> value.
|
101
94
|
#
|
102
95
|
#There is plenty of other data in the response besides the original full URL.
|
103
96
|
#Feel free to access the Response.body and use Response.method_missing to pull out specific element values.
|
104
|
-
def info(
|
105
|
-
return nil unless
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
# optional keys
|
110
|
-
if (keys = ops[:keys])
|
111
|
-
keys = [keys] unless Array === keys
|
112
|
-
params[:keys] = (keys.inject([]) do |a, key|
|
113
|
-
a << Utility::camelize(key)
|
114
|
-
a
|
115
|
-
end).join(',')
|
116
|
-
end
|
117
|
-
end)
|
118
|
-
end
|
97
|
+
def info(url)
|
98
|
+
return nil unless url
|
99
|
+
uri = URI.parse(url)
|
100
|
+
bitlink = "#{uri.host}#{uri.path}"
|
119
101
|
|
120
|
-
|
121
|
-
|
122
|
-
#
|
123
|
-
#For <i>param</i>, you can provide a previously-shortened URL from the bit.ly service.
|
124
|
-
#If so, you do not need to provide <i>param_type</i> (though <tt>:short_url</tt> would be the proper symbol).
|
125
|
-
#
|
126
|
-
#Alternately, you can provide a hash code returned by the bit.ly service.
|
127
|
-
#In this case, provide <tt>:hash</tt> as the <i>param_type</i>.
|
128
|
-
#
|
129
|
-
#A Response is returned.
|
130
|
-
#Response.to_s will return the <tt>longUrl</tt> / <tt>long_url</tt> value.
|
131
|
-
#
|
132
|
-
#There is plenty of other data in the response besides the original full URL.
|
133
|
-
#Feel free to access the Response.body and use Response.method_missing to pull out specific element values.
|
134
|
-
def stats(param, param_type=:short_url)
|
135
|
-
return nil unless param_type && param
|
136
|
-
assert_codes(execute(:info, :long_url) do |params|
|
137
|
-
params[Utility::camelize(param_type).to_sym] = param
|
138
|
-
end)
|
139
|
-
end
|
140
|
-
|
141
|
-
def errors
|
142
|
-
execute(:errors)
|
102
|
+
command = "bitlinks/#{bitlink}"
|
103
|
+
return execute_get(command, :long_url)
|
143
104
|
end
|
144
105
|
|
145
106
|
|
@@ -147,48 +108,62 @@ module Bitly4R
|
|
147
108
|
# - - - - -
|
148
109
|
protected
|
149
110
|
|
150
|
-
|
151
|
-
|
152
|
-
|
111
|
+
def execute_get(command, to_s_sym=nil) #:nodoc:
|
112
|
+
uri = URI.parse('https://api-ssl.bitly.com')
|
113
|
+
|
114
|
+
# the client-ized set
|
115
|
+
params = Params.new
|
116
|
+
|
117
|
+
# altered in whatever way the caller desires
|
118
|
+
yield params if block_given?
|
119
|
+
|
120
|
+
response = Net::HTTP.start(uri.host, uri.port,
|
121
|
+
:use_ssl => true,
|
122
|
+
:set_debug_output => $stdout,
|
123
|
+
) do |http|
|
124
|
+
path = "/v4/#{command}?#{params}"
|
125
|
+
request = Net::HTTP::Get.new(path)
|
126
|
+
request['Authorization'] = "Bearer #{self.token}"
|
127
|
+
request['Accept'] = 'application/json'
|
128
|
+
|
129
|
+
http.request request
|
130
|
+
end
|
131
|
+
|
132
|
+
# accept the HTTP 2XX range
|
133
|
+
raise Error.new('did not receive HTTP 200 OK') unless (/2\d{2}/ =~ response.code)
|
134
|
+
|
135
|
+
# a parsing response
|
136
|
+
Response.new(response, to_s_sym)
|
137
|
+
end
|
153
138
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
139
|
+
def execute_post(command, to_s_sym=nil) #:nodoc:
|
140
|
+
uri = URI.parse('https://api-ssl.bitly.com')
|
141
|
+
|
142
|
+
# the client-ized set
|
143
|
+
params = Params.new
|
158
144
|
|
159
145
|
# altered in whatever way the caller desires
|
160
146
|
yield params if block_given?
|
161
147
|
|
162
|
-
response = Net::HTTP.start(uri.host, uri.port
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
148
|
+
response = Net::HTTP.start(uri.host, uri.port,
|
149
|
+
:use_ssl => true,
|
150
|
+
# :set_debug_output => $stdout,
|
151
|
+
) do |http|
|
152
|
+
path = "/v4/#{command}"
|
153
|
+
request = Net::HTTP::Post.new(path)
|
154
|
+
request['Authorization'] = "Bearer #{self.token}"
|
155
|
+
request['Content-Type'] = 'application/json'
|
156
|
+
request.body = params.to_json
|
169
157
|
|
170
158
|
http.request request
|
171
159
|
end
|
172
160
|
|
173
|
-
|
161
|
+
# accept the HTTP 2XX range
|
162
|
+
raise Error.new('did not receive an HTTP 2XX') unless (/2\d{2}/ =~ response.code)
|
174
163
|
|
175
164
|
# a parsing response
|
176
165
|
Response.new(response, to_s_sym)
|
177
166
|
end
|
178
|
-
|
179
|
-
def assert_error_code(response) #:nodoc:
|
180
|
-
raise Error.new("errorCode #{response.errorCode} : #{response.errorMesage}") unless '0' == response.errorCode
|
181
|
-
response
|
182
|
-
end
|
183
|
-
|
184
|
-
def assert_status_code(response) #:nodoc:
|
185
|
-
raise Error.new("status #{response.statusCode}") unless 'OK' == response.statusCode
|
186
|
-
response
|
187
|
-
end
|
188
|
-
|
189
|
-
def assert_codes(response) #:nodoc:
|
190
|
-
assert_error_code(assert_status_code(response))
|
191
|
-
end
|
192
167
|
end
|
193
168
|
|
194
169
|
|
data/lib/bitly4r/definitions.rb
CHANGED
@@ -1,34 +1,20 @@
|
|
1
1
|
#Simple constructor methods, so that you don't have to deal directly with Client if you don't want to.
|
2
2
|
#
|
3
3
|
#See also:
|
4
|
-
#* Bitly4R.
|
5
|
-
#* Bitly4R.Authed
|
4
|
+
#* Bitly4R.Token
|
6
5
|
#
|
7
6
|
#--
|
8
7
|
#Many thanks to Hpricot for introducing me to this convention.
|
9
8
|
#++
|
10
9
|
|
11
10
|
#Constructs a SimpleClient with the usual Hash of arguments.
|
12
|
-
|
13
11
|
def Bitly4R(ops={})
|
14
12
|
# general options
|
15
13
|
Bitly4R::SimpleClient.new(ops)
|
16
14
|
end
|
17
15
|
|
18
|
-
#Constructs a SimpleClient with
|
19
|
-
|
20
|
-
#
|
21
|
-
|
22
|
-
def Bitly4R.Keyed(login, api_key)
|
23
|
-
# using an API key
|
24
|
-
Bitly4R::SimpleClient.new(:login => login, :api_key => api_key)
|
25
|
-
end
|
26
|
-
|
27
|
-
#Constructs a SimpleClient with login and password credentials.
|
28
|
-
#
|
29
|
-
#No API key is involved.
|
30
|
-
#HTTP GETs with HTTP Basic Auth will be the order of the day.
|
31
|
-
def Bitly4R.Authed(login, password)
|
32
|
-
# using an API key
|
33
|
-
Bitly4R::SimpleClient.new(:login => login, :password => password)
|
16
|
+
#Constructs a SimpleClient with an Access Token credential
|
17
|
+
def Bitly4R.Token(token)
|
18
|
+
# just token
|
19
|
+
Bitly4R::SimpleClient.new(:token => token)
|
34
20
|
end
|
data/lib/bitly4r/objects.rb
CHANGED
@@ -68,10 +68,10 @@ module Bitly4R
|
|
68
68
|
#Constructs a bit.ly API response wrapper.
|
69
69
|
#
|
70
70
|
#<i>response</i> can be:
|
71
|
-
#* a String, which becomes the body
|
72
|
-
#* a Net::HTTPResponse, in which case its body is extracted
|
71
|
+
#* a JSON String, which becomes the body
|
72
|
+
#* a Net::HTTPResponse, in which case its body is extracted and expected to be in JSON format
|
73
73
|
#
|
74
|
-
#<i>to_s_sym</i> is optional, and it references the
|
74
|
+
#<i>to_s_sym</i> is optional, and it references the property which will become the `#to_s` value of this Response.
|
75
75
|
#It can be either camel-case or underscored.
|
76
76
|
#See method_missing.
|
77
77
|
def initialize(response, to_s_sym=nil)
|
@@ -80,18 +80,19 @@ module Bitly4R
|
|
80
80
|
@to_s_sym = to_s_sym
|
81
81
|
end
|
82
82
|
|
83
|
-
#Provides access the other
|
83
|
+
#Provides access to the other properties of the response body via camel-case or underscored names.
|
84
84
|
#For example, <tt>longUrl</tt> and <tt>long_url</tt> are equivalent.
|
85
|
-
#If no such
|
85
|
+
#If no such property exists, you'll get nil.
|
86
86
|
def method_missing(sym, *args)
|
87
|
-
|
88
|
-
|
87
|
+
begin
|
88
|
+
json = JSON.parse(@body || '{}')
|
89
|
+
rescue JSON::ParserError => e
|
90
|
+
return nil
|
91
|
+
end
|
89
92
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
match[1].gsub(/^<!\[CDATA\[(.*)\]\]>$/, '\1')
|
94
|
-
end
|
93
|
+
# their 'v4/*' JSON convention is snake_case
|
94
|
+
sym = Utility::decamelize(sym.to_s)
|
95
|
+
return json[sym]
|
95
96
|
end
|
96
97
|
|
97
98
|
#Provides the 'likely' value from the response.
|
@@ -102,7 +103,9 @@ module Bitly4R
|
|
102
103
|
|
103
104
|
#Provides the 'likely' value from the response, as a symbol.
|
104
105
|
def to_sym
|
105
|
-
|
106
|
+
return super unless @to_s_sym
|
107
|
+
value = self.to_s
|
108
|
+
return value.nil? ? value : value.to_sym
|
106
109
|
end
|
107
110
|
end
|
108
111
|
|
data/lib/bitly4r.rb
CHANGED
data/test/client_test.rb
CHANGED
@@ -9,122 +9,83 @@ class ClientTest < Test::Unit::TestCase #:nodoc: all
|
|
9
9
|
any = 'any'
|
10
10
|
|
11
11
|
assert_raises Bitly4R::Error do
|
12
|
-
# no
|
12
|
+
# no token
|
13
13
|
Bitly4R::Client.new
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
|
-
# needs API key or password
|
18
|
-
Bitly4R::Client.new(:login => any)
|
19
|
-
end
|
20
|
-
|
21
|
-
Bitly4R::Client.new(:login => any, :api_key => any)
|
22
|
-
Bitly4R::Client.new(:login => any, :password => any)
|
16
|
+
Bitly4R::Client.new(:token => any)
|
23
17
|
end
|
24
18
|
|
25
19
|
def test_shorten
|
26
|
-
# shorten
|
20
|
+
# shorten with a full Client
|
27
21
|
client = new_client
|
28
22
|
response = client.shorten LONG_URL
|
29
23
|
|
30
|
-
|
24
|
+
assert (Bitly4R::Response === response)
|
31
25
|
|
32
26
|
# we get back what we provided
|
33
|
-
assert_equal LONG_URL, response.
|
27
|
+
assert_equal LONG_URL, response.long_url
|
34
28
|
|
35
29
|
# no assumption as to the value, just how they inter-relate
|
36
|
-
|
37
|
-
assert
|
38
|
-
|
39
|
-
|
30
|
+
id = response.id
|
31
|
+
assert id && (! id.empty?)
|
32
|
+
link = response.link
|
33
|
+
assert_equal "https://#{id}", link
|
34
|
+
assert_equal response.to_s, link
|
35
|
+
|
36
|
+
# shorten with a SimpleClient
|
37
|
+
simple_client = new_simple_client
|
38
|
+
simple_response = simple_client.shorten LONG_URL
|
39
|
+
assert (String === simple_response)
|
40
|
+
assert_equal link, simple_response
|
40
41
|
end
|
41
42
|
|
42
43
|
def test_expand
|
43
|
-
# shorten
|
44
|
+
# shorten with a full Client
|
44
45
|
client = new_client
|
45
|
-
|
46
46
|
response = client.shorten(LONG_URL)
|
47
|
-
assert_is_response_ok response
|
48
47
|
|
49
|
-
|
48
|
+
id = response.id
|
50
49
|
short = response.to_s
|
51
50
|
|
52
51
|
# ... and re-expand
|
53
|
-
|
52
|
+
# no assumption as to the value, just how they inter-relate
|
54
53
|
response = client.expand(short)
|
55
|
-
assert_is_response_ok response
|
56
54
|
|
57
55
|
assert_equal LONG_URL, response.to_s
|
56
|
+
assert_equal LONG_URL, response.long_url
|
58
57
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
# again, we don't have to know anything
|
65
|
-
response = client.expand(hash, :hash)
|
66
|
-
assert_is_response_ok response
|
67
|
-
|
68
|
-
assert_equal LONG_URL, response.to_s
|
69
|
-
|
70
|
-
# again...
|
71
|
-
assert ! response.__send__(hash.to_sym).empty?
|
58
|
+
# expand with a SimpleClient
|
59
|
+
simple_client = new_simple_client
|
60
|
+
simple_response = simple_client.expand short
|
61
|
+
assert (String === simple_response)
|
62
|
+
assert_equal LONG_URL, simple_response
|
72
63
|
end
|
73
64
|
|
74
65
|
def test_info
|
75
|
-
|
66
|
+
# shorten with a full Client
|
76
67
|
client = new_client
|
77
|
-
|
78
68
|
response = client.shorten(LONG_URL)
|
79
|
-
assert_is_response_ok response
|
80
69
|
|
81
|
-
hash = response.user_hash
|
82
70
|
short = response.to_s
|
83
71
|
|
84
|
-
#
|
72
|
+
# now, its info ...
|
85
73
|
response = client.info(short)
|
86
|
-
assert_is_response_ok response
|
87
|
-
|
88
|
-
assert_equal LONG_URL, response.long_url
|
89
|
-
|
90
|
-
# hash, key limit
|
91
|
-
response = client.info(hash, :hash, :keys => [:long_url, :html_title])
|
92
|
-
assert_is_response_ok response
|
93
|
-
|
94
|
-
# well, we're getting non-included keys back
|
95
|
-
# then again, the demo doesn't constrain the keys either
|
96
|
-
# http://code.google.com/p/bitly-api/wiki/ApiDocumentation
|
97
|
-
###assert response.thumbnail.empty?
|
98
|
-
###assert ! response.html_title.empty?
|
99
|
-
assert_equal LONG_URL, response.to_s
|
100
|
-
end
|
101
|
-
|
102
|
-
def test_stats
|
103
|
-
# shorten ...
|
104
|
-
client = new_client
|
105
|
-
|
106
|
-
response = client.shorten(LONG_URL)
|
107
|
-
assert_is_response_ok response
|
108
|
-
|
109
|
-
hash = response.user_hash
|
110
|
-
short = response.to_s
|
111
|
-
|
112
|
-
{ :hash => hash, :short_url => short }.each do |param_type, param|
|
113
|
-
response = client.info(param, param_type)
|
114
|
-
assert_is_response_ok response
|
115
|
-
|
116
|
-
# we could choose anything
|
117
|
-
assert_equal LONG_URL, response.to_s
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
def test_errors
|
122
|
-
# errors ...
|
123
|
-
client = new_client
|
124
74
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
75
|
+
assert_equal LONG_URL, response.to_s
|
76
|
+
assert_equal LONG_URL, response.long_url
|
77
|
+
|
78
|
+
# a few other accessable properties
|
79
|
+
# no assumption as to the value, just how they inter-relate
|
80
|
+
assert_equal "https://#{response.id}", response.link
|
81
|
+
assert_equal false, response.archived
|
82
|
+
|
83
|
+
# info with a SimpleClient
|
84
|
+
# which for this method is not "simple"; it provides a full Response
|
85
|
+
simple_client = new_simple_client
|
86
|
+
simple_response = simple_client.info short
|
87
|
+
assert (Bitly4R::Response === response)
|
88
|
+
assert_equal LONG_URL, simple_response.long_url
|
89
|
+
assert_equal false, response.archived
|
129
90
|
end
|
130
91
|
end
|
data/test/definitions_test.rb
CHANGED
@@ -5,46 +5,28 @@ require 'test_helper'
|
|
5
5
|
|
6
6
|
|
7
7
|
class DefinitionsTest < Test::Unit::TestCase #:nodoc: all
|
8
|
-
def
|
8
|
+
def test_with_token
|
9
9
|
# shorten ...
|
10
|
-
|
11
|
-
short = client.shorten(LONG_URL)
|
10
|
+
short = Bitly4R(:token => TOKEN).shorten(LONG_URL)
|
12
11
|
assert short && (! short.empty?)
|
12
|
+
assert (String === short)
|
13
13
|
|
14
|
-
# ... and expand
|
15
|
-
|
14
|
+
# ... and expand (with another Definition)
|
15
|
+
long = Bitly4R.Token(TOKEN).expand(short)
|
16
|
+
assert (String === long)
|
17
|
+
assert_equal LONG_URL, long
|
16
18
|
end
|
17
19
|
|
18
|
-
def
|
19
|
-
unless PASSWORD
|
20
|
-
puts %Q{
|
21
|
-
NOTE:
|
22
|
-
the text login (#{LOGIN}) did not publish a password
|
23
|
-
cannot be tested without that private information
|
24
|
-
}.strip
|
25
|
-
return
|
26
|
-
end
|
27
|
-
|
28
|
-
# http://code.google.com/p/bitly-api/wiki/ApiDocumentation
|
29
|
-
# sure, the documentation claims there's HTTP Auth support
|
30
|
-
# but i don't see it yet
|
31
|
-
short = nil
|
32
|
-
assert_raises Bitly4R::Error do
|
33
|
-
# shorten ...
|
34
|
-
client = Bitly4R(:login => LOGIN, :password => API_KEY)
|
35
|
-
short = client.shorten(LONG_URL)
|
36
|
-
assert short && (! short.empty?)
|
37
|
-
end
|
38
|
-
|
20
|
+
def test_without_token
|
39
21
|
# alright, let's use the API key
|
40
|
-
client = Bitly4R(:
|
41
|
-
|
42
|
-
|
22
|
+
client = Bitly4R(:token => 'INVALID')
|
23
|
+
|
24
|
+
assert_raises Bitly4R::Error do
|
25
|
+
client.shorten(LONG_URL)
|
26
|
+
end
|
43
27
|
|
44
|
-
# same deal. *sigh*
|
45
28
|
assert_raises Bitly4R::Error do
|
46
|
-
|
47
|
-
assert_equal LONG_URL, Bitly4R.Authed(LOGIN, PASSWORD).expand(short)
|
29
|
+
Bitly4R.Token('INVALID').shorten(LONG_URL)
|
48
30
|
end
|
49
31
|
end
|
50
32
|
end
|
data/test/objects_test.rb
CHANGED
@@ -81,21 +81,20 @@ class ObjectsTest < Test::Unit::TestCase #:nodoc: all
|
|
81
81
|
response = Bitly4R::Response.new('string', :bogus)
|
82
82
|
assert_equal 'string', response.body
|
83
83
|
assert_nil response.to_s
|
84
|
+
assert_nil response.to_sym
|
84
85
|
|
85
86
|
# simple
|
86
|
-
response = Bitly4R::Response.new('
|
87
|
-
assert_equal 'value', response.
|
88
|
-
|
87
|
+
response = Bitly4R::Response.new('{"key":"value"}', :key)
|
88
|
+
assert_equal 'value', response.key
|
89
|
+
assert_nil response.another_key
|
90
|
+
assert_equal 'value', response.to_s
|
91
|
+
assert_equal :value, response.to_sym
|
89
92
|
|
90
93
|
# camelization
|
91
|
-
response = Bitly4R::Response.new('
|
94
|
+
response = Bitly4R::Response.new('{"uD":"down","dU":"up"}', :d_u)
|
92
95
|
assert_equal 'down', response.uD
|
93
96
|
assert_equal 'down', response.u_d
|
94
97
|
assert_equal 'up', response.dU
|
95
98
|
assert_equal 'up', response.to_s
|
96
|
-
|
97
|
-
# CDATA, plus to_sym
|
98
|
-
response = Bitly4R::Response.new('<a><b>b</b><cData><![CDATA[data]]></cData><c>c</c></a>', :c_data)
|
99
|
-
assert_equal :data, response.to_sym
|
100
99
|
end
|
101
100
|
end
|
data/test/test_helper.rb
CHANGED
@@ -9,33 +9,26 @@ $LOAD_PATH.unshift File.dirname(File.dirname(__FILE__)) + "/../lib"
|
|
9
9
|
|
10
10
|
# if we're lucky...
|
11
11
|
begin
|
12
|
-
require '
|
13
|
-
rescue
|
12
|
+
require 'debug'
|
13
|
+
rescue Exception
|
14
14
|
end
|
15
15
|
|
16
16
|
|
17
17
|
|
18
18
|
class Test::Unit::TestCase #:nodoc: all
|
19
|
-
|
20
19
|
# trailing slash makes a difference! they normalize!
|
21
20
|
LONG_URL = 'http://rubyforge.org/'
|
22
21
|
|
23
|
-
#
|
24
|
-
|
25
|
-
|
26
|
-
LOGIN = 'bitlyapidemo'
|
27
|
-
API_KEY = 'R_0da49e0a9118ff35f52f629d2d71bf07'
|
28
|
-
PASSWORD = nil
|
29
|
-
|
22
|
+
# an Access Token credential is required
|
23
|
+
TOKEN = ENV['TOKEN']
|
24
|
+
raise Exception.new('You must provide an Access Token (TOKEN) from the environment') if (TOKEN.nil? || TOKEN.empty?)
|
30
25
|
|
31
26
|
|
32
|
-
|
33
|
-
|
34
|
-
|
27
|
+
def new_client
|
28
|
+
Bitly4R::Client.new(:token => TOKEN)
|
29
|
+
end
|
35
30
|
|
36
|
-
def
|
37
|
-
|
38
|
-
assert_equal '', response.error_message
|
39
|
-
assert_equal 'OK', response.status_code
|
31
|
+
def new_simple_client
|
32
|
+
Bitly4R.Token(TOKEN)
|
40
33
|
end
|
41
34
|
end
|
metadata
CHANGED
@@ -1,70 +1,65 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: bitly4r
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
|
-
authors:
|
6
|
+
authors:
|
7
7
|
- Dan Foley
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
|
12
|
-
date: 2009-02-02 00:00:00 -08:00
|
13
|
-
default_executable:
|
11
|
+
date: 2023-05-01 00:00:00.000000000 Z
|
14
12
|
dependencies: []
|
15
|
-
|
16
|
-
description: "Bitly4R : A Ruby API for the http://bit.ly URL-shortening service"
|
13
|
+
description: 'Bitly4R : A Ruby API for the http://bit.ly URL-shortening service'
|
17
14
|
email: admin@cantremember.com
|
18
15
|
executables: []
|
19
|
-
|
20
16
|
extensions: []
|
21
|
-
|
22
|
-
extra_rdoc_files:
|
17
|
+
extra_rdoc_files:
|
23
18
|
- README.rdoc
|
24
19
|
- CHANGELOG
|
25
20
|
- LICENSE
|
26
|
-
files:
|
21
|
+
files:
|
27
22
|
- CHANGELOG
|
28
23
|
- LICENSE
|
29
24
|
- README.rdoc
|
30
25
|
- Rakefile
|
26
|
+
- bitly4r.gemspec
|
27
|
+
- container
|
28
|
+
- lib/bitly4r.rb
|
31
29
|
- lib/bitly4r/client.rb
|
32
30
|
- lib/bitly4r/definitions.rb
|
33
31
|
- lib/bitly4r/objects.rb
|
34
|
-
-
|
35
|
-
|
32
|
+
- test/client_test.rb
|
33
|
+
- test/definitions_test.rb
|
34
|
+
- test/objects_test.rb
|
35
|
+
- test/test_helper.rb
|
36
36
|
homepage: http://wiki.cantremember.com/Bitly4R
|
37
|
+
licenses:
|
38
|
+
- WTFPL
|
39
|
+
metadata: {}
|
37
40
|
post_install_message:
|
38
|
-
rdoc_options:
|
39
|
-
- --line-numbers
|
40
|
-
- --inline-source
|
41
|
-
- --title
|
41
|
+
rdoc_options:
|
42
|
+
- "--line-numbers"
|
43
|
+
- "--inline-source"
|
44
|
+
- "--title"
|
42
45
|
- Bitly4R
|
43
|
-
- --main
|
46
|
+
- "--main"
|
44
47
|
- README.rdoc
|
45
|
-
require_paths:
|
48
|
+
require_paths:
|
46
49
|
- lib
|
47
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
-
requirements:
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
49
52
|
- - ">="
|
50
|
-
- !ruby/object:Gem::Version
|
51
|
-
version:
|
52
|
-
|
53
|
-
|
54
|
-
requirements:
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
55
57
|
- - ">="
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
version:
|
58
|
-
version:
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
59
60
|
requirements: []
|
60
|
-
|
61
|
-
rubyforge_project: bitly4r
|
62
|
-
rubygems_version: 1.3.1
|
61
|
+
rubygems_version: 3.3.26
|
63
62
|
signing_key:
|
64
|
-
specification_version:
|
65
|
-
summary: bitly4r 0.
|
66
|
-
test_files:
|
67
|
-
- test/client_test.rb
|
68
|
-
- test/definitions_test.rb
|
69
|
-
- test/objects_test.rb
|
70
|
-
- test/test_helper.rb
|
63
|
+
specification_version: 4
|
64
|
+
summary: bitly4r 0.2.0
|
65
|
+
test_files: []
|