google_short_links 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ bin/*
2
+ lib/**/*.rb
3
+ LICENSE.txt
4
+ README.rdoc
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.3@google-short-links
@@ -0,0 +1,4 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - ree
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source :rubygems
2
+
3
+ gem 'httparty'
4
+ gem 'multi_json'
5
+
6
+ group :development do
7
+ gem 'jeweler'
8
+ gem 'rcov'
9
+ gem 'rdoc'
10
+ gem 'rspec'
11
+ gem 'timecop'
12
+ end
@@ -0,0 +1,40 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.3)
5
+ git (1.2.5)
6
+ httparty (0.8.1)
7
+ multi_json
8
+ multi_xml
9
+ jeweler (1.6.4)
10
+ bundler (~> 1.0)
11
+ git (>= 1.2.5)
12
+ rake
13
+ json (1.6.1)
14
+ multi_json (1.0.3)
15
+ multi_xml (0.4.1)
16
+ rake (0.9.2.2)
17
+ rcov (0.9.11)
18
+ rdoc (3.11)
19
+ json (~> 1.4)
20
+ rspec (2.7.0)
21
+ rspec-core (~> 2.7.0)
22
+ rspec-expectations (~> 2.7.0)
23
+ rspec-mocks (~> 2.7.0)
24
+ rspec-core (2.7.1)
25
+ rspec-expectations (2.7.0)
26
+ diff-lcs (~> 1.1.2)
27
+ rspec-mocks (2.7.0)
28
+ timecop (0.3.5)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ httparty
35
+ jeweler
36
+ multi_json
37
+ rcov
38
+ rdoc
39
+ rspec
40
+ timecop
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Benjamin Manns
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,40 @@
1
+ = google-short-links
2
+
3
+ Ruby wrapper for Google Short Links.
4
+
5
+ == Installation
6
+
7
+ To install Google Short Links, run
8
+
9
+ gem install google-short-links
10
+
11
+ To load the library, use
12
+
13
+ require 'google_short_links'
14
+
15
+ Or, with Bundler, add to your Gemfile
16
+
17
+ gem 'google-short-links', :require => 'google_short_links'
18
+
19
+ == Examples
20
+
21
+ This example creates a new client, creates a hash
22
+
23
+ client = GoogleShortLinks::Client.new :server => 'short.example.com', :secret => 'abcdef1234567890', :email => 'ben@example.com'
24
+ link = client.get_or_create_hash 'http://example.com/parent/child/long_document_name.html', :is_public => true
25
+ link # => {"status"=>"ok", "url"=>"http://example.com/parent/child/long_document_name.html", "estimated_api_calls_remaining"=>98, "shortcut"=>"abc12", "usage_count"=>0, "owner"=>"ben@example.com", "is_public"=>true, "is_hash"=>true}
26
+ short_url = "http://short.example.com/#{link['shortcut']}" # => "http://short.example.com/abc12"
27
+
28
+ == Contributing to google-short-links
29
+
30
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
31
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
32
+ * Fork the project
33
+ * Start a feature/bugfix branch
34
+ * Commit and push until you are happy with your contribution
35
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
36
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
37
+
38
+ == Copyright
39
+
40
+ Copyright (c) 2011 Benjamin Manns. See LICENSE.txt for further details.
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler'
4
+ begin
5
+ Bundler.setup :default, :development
6
+ rescue Bundler::BundlerError => e
7
+ $stderr.puts e.message
8
+ $stderr.puts 'Run `bundle install` to install missing gems'
9
+ exit e.status_code
10
+ end
11
+ require 'rake'
12
+
13
+ require 'jeweler'
14
+ Jeweler::Tasks.new do |gem|
15
+ gem.name = 'google_short_links'
16
+ gem.homepage = 'https://github.com/benmanns/google_short_links'
17
+ gem.license = 'MIT'
18
+ gem.summary = 'Ruby wrapper for Google Short Links.'
19
+ gem.description = 'Ruby wrapper for Google Short Links.'
20
+ gem.email = 'benmanns@gmail.com'
21
+ gem.authors = 'Benjamin Manns'
22
+ end
23
+ Jeweler::RubygemsDotOrgTasks.new
24
+
25
+ require 'rspec/core'
26
+ require 'rspec/core/rake_task'
27
+ RSpec::Core::RakeTask.new :spec do |spec|
28
+ spec.pattern = FileList[File.join('spec', '**', '*_spec.rb')]
29
+ end
30
+
31
+ RSpec::Core::RakeTask.new :rcov do |spec|
32
+ spec.pattern = File.join('spec', '**', '*_spec.rb')
33
+ spec.rcov = true
34
+ end
35
+
36
+ task :default => :spec
37
+
38
+ require 'rdoc/task'
39
+ RDoc::Task.new do |rdoc|
40
+ version = File.exist?('VERSION') ? File.read('VERSION') : ''
41
+
42
+ rdoc.rdoc_dir = 'rdoc'
43
+ rdoc.title = "google_short_links #{version}"
44
+ rdoc.rdoc_files.include('README*')
45
+ rdoc.rdoc_files.include(File.join('lib', '**', '*.rb'))
46
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.2
@@ -0,0 +1,75 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{google-short-links}
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Benjamin Manns"]
12
+ s.date = %q{2011-11-18}
13
+ s.description = %q{Ruby wrapper for Google Short Links.}
14
+ s.email = %q{benmanns@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ ".rvmrc",
23
+ ".travis.yml",
24
+ "Gemfile",
25
+ "Gemfile.lock",
26
+ "LICENSE.txt",
27
+ "README.rdoc",
28
+ "Rakefile",
29
+ "VERSION",
30
+ "google-short-links.gemspec",
31
+ "lib/google_short_links.rb",
32
+ "lib/google_short_links/client.rb",
33
+ "lib/google_short_links/parser.rb",
34
+ "spec/google_short_links/client_spec.rb",
35
+ "spec/google_short_links/parser_spec.rb",
36
+ "spec/google_short_links_spec.rb",
37
+ "spec/spec_helper.rb"
38
+ ]
39
+ s.homepage = %q{https://github.com/benmanns/google-short-links}
40
+ s.licenses = ["MIT"]
41
+ s.require_paths = ["lib"]
42
+ s.rubygems_version = %q{1.6.2}
43
+ s.summary = %q{Ruby wrapper for Google Short Links.}
44
+
45
+ if s.respond_to? :specification_version then
46
+ s.specification_version = 3
47
+
48
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
49
+ s.add_runtime_dependency(%q<httparty>, [">= 0"])
50
+ s.add_runtime_dependency(%q<multi_json>, [">= 0"])
51
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
52
+ s.add_development_dependency(%q<rcov>, [">= 0"])
53
+ s.add_development_dependency(%q<rdoc>, [">= 0"])
54
+ s.add_development_dependency(%q<rspec>, [">= 0"])
55
+ s.add_development_dependency(%q<timecop>, [">= 0"])
56
+ else
57
+ s.add_dependency(%q<httparty>, [">= 0"])
58
+ s.add_dependency(%q<multi_json>, [">= 0"])
59
+ s.add_dependency(%q<jeweler>, [">= 0"])
60
+ s.add_dependency(%q<rcov>, [">= 0"])
61
+ s.add_dependency(%q<rdoc>, [">= 0"])
62
+ s.add_dependency(%q<rspec>, [">= 0"])
63
+ s.add_dependency(%q<timecop>, [">= 0"])
64
+ end
65
+ else
66
+ s.add_dependency(%q<httparty>, [">= 0"])
67
+ s.add_dependency(%q<multi_json>, [">= 0"])
68
+ s.add_dependency(%q<jeweler>, [">= 0"])
69
+ s.add_dependency(%q<rcov>, [">= 0"])
70
+ s.add_dependency(%q<rdoc>, [">= 0"])
71
+ s.add_dependency(%q<rspec>, [">= 0"])
72
+ s.add_dependency(%q<timecop>, [">= 0"])
73
+ end
74
+ end
75
+
@@ -0,0 +1,77 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "google_short_links"
8
+ s.version = "0.1.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Benjamin Manns"]
12
+ s.date = "2012-02-24"
13
+ s.description = "Ruby wrapper for Google Short Links."
14
+ s.email = "benmanns@gmail.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ ".rvmrc",
23
+ ".travis.yml",
24
+ "Gemfile",
25
+ "Gemfile.lock",
26
+ "LICENSE.txt",
27
+ "README.rdoc",
28
+ "Rakefile",
29
+ "VERSION",
30
+ "google-short-links.gemspec",
31
+ "google_short_links.gemspec",
32
+ "lib/google_short_links.rb",
33
+ "lib/google_short_links/client.rb",
34
+ "lib/google_short_links/parser.rb",
35
+ "spec/examples/google_short_links/client_spec.rb",
36
+ "spec/google_short_links/client_spec.rb",
37
+ "spec/google_short_links/parser_spec.rb",
38
+ "spec/google_short_links_spec.rb",
39
+ "spec/spec_helper.rb"
40
+ ]
41
+ s.homepage = "https://github.com/benmanns/google_short_links"
42
+ s.licenses = ["MIT"]
43
+ s.require_paths = ["lib"]
44
+ s.rubygems_version = "1.8.15"
45
+ s.summary = "Ruby wrapper for Google Short Links."
46
+
47
+ if s.respond_to? :specification_version then
48
+ s.specification_version = 3
49
+
50
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
51
+ s.add_runtime_dependency(%q<httparty>, [">= 0"])
52
+ s.add_runtime_dependency(%q<multi_json>, [">= 0"])
53
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
54
+ s.add_development_dependency(%q<rcov>, [">= 0"])
55
+ s.add_development_dependency(%q<rdoc>, [">= 0"])
56
+ s.add_development_dependency(%q<rspec>, [">= 0"])
57
+ s.add_development_dependency(%q<timecop>, [">= 0"])
58
+ else
59
+ s.add_dependency(%q<httparty>, [">= 0"])
60
+ s.add_dependency(%q<multi_json>, [">= 0"])
61
+ s.add_dependency(%q<jeweler>, [">= 0"])
62
+ s.add_dependency(%q<rcov>, [">= 0"])
63
+ s.add_dependency(%q<rdoc>, [">= 0"])
64
+ s.add_dependency(%q<rspec>, [">= 0"])
65
+ s.add_dependency(%q<timecop>, [">= 0"])
66
+ end
67
+ else
68
+ s.add_dependency(%q<httparty>, [">= 0"])
69
+ s.add_dependency(%q<multi_json>, [">= 0"])
70
+ s.add_dependency(%q<jeweler>, [">= 0"])
71
+ s.add_dependency(%q<rcov>, [">= 0"])
72
+ s.add_dependency(%q<rdoc>, [">= 0"])
73
+ s.add_dependency(%q<rspec>, [">= 0"])
74
+ s.add_dependency(%q<timecop>, [">= 0"])
75
+ end
76
+ end
77
+
@@ -0,0 +1,6 @@
1
+ # Holds the client class for Google Short Links.
2
+ # See GoogleShortLinks::Client.
3
+ module GoogleShortLinks
4
+ autoload :Client, 'google_short_links/client'
5
+ autoload :Parser, 'google_short_links/parser'
6
+ end
@@ -0,0 +1,205 @@
1
+ require 'cgi'
2
+ require 'base64'
3
+ require 'digest/sha1'
4
+ require 'openssl'
5
+ require 'uri'
6
+
7
+ require 'httparty'
8
+
9
+ # Client for Google Short Links.
10
+ #
11
+ # ==== Examples
12
+ #
13
+ # client = GoogleShortLinks::Client.new :server => 'short.example.com', :secret => 'abcdef1234567890', :email => 'ben@example.com'
14
+ # link = client.get_or_create_hash 'http://example.com/parent/child/long_document_name.html', :is_public => true
15
+ # link # => {"status"=>"ok", "url"=>"http://example.com/parent/child/long_document_name.html", "estimated_api_calls_remaining"=>98, "shortcut"=>"abc12", "usage_count"=>0, "owner"=>"ben@example.com", "is_public"=>true, "is_hash"=>true}
16
+ class GoogleShortLinks::Client
17
+ include HTTParty
18
+
19
+ # The domain name where Google Short Links is hosted.
20
+ attr_accessor :server
21
+
22
+ # Your HMAC-SHA1 secret.
23
+ attr_accessor :secret
24
+
25
+ # The email for the account under which the links will be created.
26
+ attr_accessor :email
27
+
28
+ parser GoogleShortLinks::Parser
29
+
30
+ # Initializes a new Client.
31
+ #
32
+ # ==== Parameters
33
+ #
34
+ # [<tt>options</tt>] Optional Hash containing configuration values.
35
+ #
36
+ # ==== Options
37
+ #
38
+ # [:server]
39
+ # The domain name where Google Short Links is hosted.
40
+ # [:secret]
41
+ # Your HMAC-SHA1 secret.
42
+ # [:email]
43
+ # The email for the account under which the links will be created.
44
+ def initialize options={}
45
+ self.server = options[:server]
46
+ self.secret = options[:secret]
47
+ self.email = options[:email]
48
+ end
49
+
50
+ # Creates a URL that is used to create a hash.
51
+ #
52
+ # ==== Parameters
53
+ #
54
+ # [<tt>url</tt>] Required String containing the URL to be shortened.
55
+ # [<tt>params</tt>] Optional Hash that will add or override GET parameters in the URL.
56
+ #
57
+ # ==== Parameters
58
+ #
59
+ # [:is_public]
60
+ # Boolean for whether or not the short link can be accessed without logging in to Google Apps.
61
+ #
62
+ # ==== Examples
63
+ #
64
+ # link_url = client.get_or_create_hash_url 'http://example.com/parent/child/long_document_name.html', :is_public => true
65
+ # link_url # => "http://short.example.com/js/get_or_create_hash?is_public=true&oauth_signature_method=HMAC-SHA1&timestamp=1321663459.0&url=http%3A%2F%2Fexample.com%2Fparent%2Fchild%2Flong_document_name.html&user=ben%40example.com&oauth_signature=JElQ0Oq59q%2BOsinYuMzGX%2F8Tn2U%3D"
66
+ def get_or_create_hash_url url, params={}
67
+ request_path = request_path(:get_or_create_hash)
68
+
69
+ query = params_to_query(base_params.merge(:url => url).merge(params))
70
+
71
+ digest_url(request_path, query)
72
+ end
73
+
74
+ # Creates a URL that is used to create a shortlink with a customized shortcut.
75
+ #
76
+ # ==== Parameters
77
+ #
78
+ # [<tt>url</tt>] Required String containing the URL to be shortened.
79
+ # [<tt>shortcut</tt>] Required String containing the custom shortcut.
80
+ # [<tt>params</tt>] Optional Hash that will add or override GET parameters in the URL.
81
+ #
82
+ # ==== Parameters
83
+ #
84
+ # [:is_public]
85
+ # Boolean for whether or not the short link can be accessed without logging in to Google Apps.
86
+ #
87
+ # ==== Examples
88
+ #
89
+ # link_url = client.get_or_create_shortlink_url 'http://example.com/parent/child/long_document_name.html', 'example', :is_public => true
90
+ # link_url # => "http://short.example.com/js/get_or_create_shortlink?is_public=true&oauth_signature_method=HMAC-SHA1&shortcut=example&timestamp=1321663613.0&url=http%3A%2F%2Fexample.com%2Fparent%2Fchild%2Flong_document_name.html&user=ben%40example.com&oauth_signature=FsOEjCDw3qpz%2B59Pdi4d1Qvv0Os%3D"
91
+ def get_or_create_shortlink_url url, shortcut, params={}
92
+ request_path = request_path(:get_or_create_shortlink)
93
+
94
+ query = params_to_query(base_params.merge(:url => url, :shortcut => shortcut).merge(params))
95
+
96
+ digest_url(request_path, query)
97
+ end
98
+
99
+ # Creates a URL that is used to get details about a link from its shortcut.
100
+ #
101
+ # ==== Parameters
102
+ #
103
+ # [<tt>shortcut</tt>] Required String containing the URL to be shortened.
104
+ # [<tt>params</tt>] Optional Hash that will add or override GET parameters in the URL.
105
+ #
106
+ # ==== Examples
107
+ #
108
+ # link_url = client.get_details_url 'example'
109
+ # link_url # => "http://short.example.com/js/get_details?oauth_signature_method=HMAC-SHA1&shortcut=example&timestamp=1321663629.0&user=ben%40example.com&oauth_signature=p8XqzF0lITupKN3Ta0qu2E8hqBI%3D"
110
+ def get_details_url shortcut, params={}
111
+ request_path = request_path(:get_details)
112
+
113
+ query = params_to_query(base_params.merge(:shortcut => shortcut).merge(params))
114
+
115
+ digest_url(request_path, query)
116
+ end
117
+
118
+ # Shortens a URL.
119
+ #
120
+ # ==== Parameters
121
+ #
122
+ # [<tt>url</tt>] Required String containing the URL to be shortened.
123
+ # [<tt>params</tt>] Optional Hash that will add or override GET parameters in the URL.
124
+ #
125
+ # ==== Parameters
126
+ #
127
+ # [:is_public]
128
+ # Boolean for whether or not the short link can be accessed without logging in to Google Apps.
129
+ #
130
+ # ==== Examples
131
+ #
132
+ # link = client.get_or_create_hash 'http://example.com/parent/child/long_document_name.html', :is_public => true
133
+ # link # => {"status"=>"ok", "url"=>"http://example.com/parent/child/long_document_name.html", "estimated_api_calls_remaining"=>98, "shortcut"=>"abc12", "usage_count"=>0, "owner"=>"ben@example.com", "is_public"=>true, "is_hash"=>true}
134
+ def get_or_create_hash url, params={}
135
+ self.class.get(get_or_create_hash_url(url, params)).parsed_response
136
+ end
137
+
138
+ # Creates a shortlink with a customized shortcut.
139
+ #
140
+ # ==== Parameters
141
+ #
142
+ # [<tt>url</tt>] Required String containing the URL to be shortened.
143
+ # [<tt>shortcut</tt>] Required String containing the custom shortcut.
144
+ # [<tt>params</tt>] Optional Hash that will add or override GET parameters in the URL.
145
+ #
146
+ # ==== Parameters
147
+ #
148
+ # [:is_public]
149
+ # Boolean for whether or not the short link can be accessed without logging in to Google Apps.
150
+ #
151
+ # ==== Examples
152
+ #
153
+ # link = client.get_or_create_shortlink 'http://example.com/parent/child/long_document_name.html', 'example', :is_public => true
154
+ # link # => {"status"=>"ok", "url"=>"http://example.com/parent/child/long_document_name.html", "estimated_api_calls_remaining"=>99, "shortcut"=>"example", "usage_count"=>0, "owner"=>"ben@example.com", "is_public"=>true, "is_hash"=>false}
155
+ def get_or_create_shortlink url, shortcut, params={}
156
+ self.class.get(get_or_create_shortlink_url(url, shortcut, params)).parsed_response
157
+ end
158
+
159
+ # Gets details about a link from its shortcut.
160
+ #
161
+ # ==== Parameters
162
+ #
163
+ # [<tt>shortcut</tt>] Required String containing the URL to be shortened.
164
+ # [<tt>params</tt>] Optional Hash that will add or override GET parameters in the URL.
165
+ #
166
+ # ==== Examples
167
+ #
168
+ # link = client.get_details 'example'
169
+ # link # => {"status"=>"ok", "url"=>"http://example.com/parent/child/long_document_name.html", "estimated_api_calls_remaining"=>100, "shortcut"=>"example", "usage_count"=>0, "owner"=>"ben@example.com", "is_public"=>true, "is_hash"=>false}
170
+ def get_details shortcut, params={}
171
+ self.class.get(get_details_url(shortcut, params)).parsed_response
172
+ end
173
+
174
+ protected
175
+
176
+ def request_path action #:nodoc:
177
+ "http://#{server}/js/#{action}"
178
+ end
179
+
180
+ def base_params #:nodoc:
181
+ {
182
+ :oauth_signature_method => 'HMAC-SHA1',
183
+ :timestamp => Time.now.to_i.to_f,
184
+ :user => email,
185
+ }
186
+ end
187
+
188
+ def params_to_query params #:nodoc:
189
+ params.to_a.sort_by { |param| param.to_s }.map { |(key, value)| "#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}" }.join('&')
190
+ end
191
+
192
+ def digest request_path, query #:nodoc:
193
+ content = "GET&#{CGI.escape(request_path)}&#{CGI.escape(query)}"
194
+
195
+ digest = OpenSSL::Digest::Digest.new('sha1')
196
+ digest_raw = OpenSSL::HMAC.digest(digest, secret, content)
197
+ CGI.escape(Base64.encode64(digest_raw).chomp)
198
+ end
199
+
200
+ def digest_url request_path, query #:nodoc:
201
+ request_uri = URI.parse(request_path)
202
+ request_uri.query = "#{query}&oauth_signature=#{digest(request_path, query)}"
203
+ request_uri.to_s
204
+ end
205
+ end
@@ -0,0 +1,14 @@
1
+ require 'httparty'
2
+ require 'multi_json'
3
+
4
+ # Parses the JSON that Google Short Links returns.
5
+ class GoogleShortLinks::Parser < HTTParty::Parser
6
+ # Google returns the JSON response as a text/html mime type.
7
+ # This class only supports JSON currently.
8
+ SupportedFormats = { 'text/html' => :json }
9
+
10
+ # Decodes JSON into a hash.
11
+ def json
12
+ MultiJson.decode(body)
13
+ end
14
+ end
@@ -0,0 +1,70 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ describe GoogleShortLinks::Client do
4
+ if ENV['GOOGLE_SHORT_LINKS_SERVER'] && ENV['GOOGLE_SHORT_LINKS_SECRET'] && ENV['GOOGLE_SHORT_LINKS_EMAIL']
5
+ let(:client) { GoogleShortLinks::Client.new(:server => ENV['GOOGLE_SHORT_LINKS_SERVER'], :secret => ENV['GOOGLE_SHORT_LINKS_SECRET'], :email => ENV['GOOGLE_SHORT_LINKS_EMAIL']) }
6
+
7
+ specify 'creating a hash' do
8
+ require 'securerandom'
9
+ url = "http://www.example.org/#{SecureRandom.uuid}"
10
+
11
+ response = client.get_or_create_hash(url)
12
+ response = client.get_or_create_hash(url) if response['status'] == 'not found'
13
+
14
+ response.should include 'url' => url
15
+ response.should have_key 'shortcut'
16
+ response.should include 'owner' => ENV['GOOGLE_SHORT_LINKS_EMAIL']
17
+ response.should include 'is_public' => false
18
+ response.should include 'is_hash' => true
19
+
20
+ shortcut = response['shortcut']
21
+
22
+ response = client.get_or_create_hash(url)
23
+
24
+ response.should include 'url' => url
25
+ response.should include 'shortcut' => shortcut
26
+ response.should include 'owner' => ENV['GOOGLE_SHORT_LINKS_EMAIL']
27
+ response.should include 'is_public' => false
28
+ response.should include 'is_hash' => true
29
+
30
+ response = client.get_details(shortcut)
31
+
32
+ response.should include 'url' => url
33
+ response.should include 'shortcut' => shortcut
34
+ response.should include 'owner' => ENV['GOOGLE_SHORT_LINKS_EMAIL']
35
+ response.should include 'is_public' => false
36
+ response.should include 'is_hash' => true
37
+ end
38
+
39
+ specify 'creating a shortcut' do
40
+ require 'securerandom'
41
+ url = "http://www.example.org/#{SecureRandom.uuid}"
42
+ shortcut = SecureRandom.uuid
43
+
44
+ response = client.get_or_create_shortlink(url, shortcut)
45
+ response = client.get_or_create_shortlink(url, shortcut) if response['status'] == 'not found'
46
+
47
+ response.should include 'url' => url
48
+ response.should include 'shortcut' => shortcut
49
+ response.should include 'owner' => ENV['GOOGLE_SHORT_LINKS_EMAIL']
50
+ response.should include 'is_public' => false
51
+ response.should include 'is_hash' => false
52
+
53
+ response = client.get_or_create_shortlink(url, shortcut)
54
+
55
+ response.should include 'url' => url
56
+ response.should include 'shortcut' => shortcut
57
+ response.should include 'owner' => ENV['GOOGLE_SHORT_LINKS_EMAIL']
58
+ response.should include 'is_public' => false
59
+ response.should include 'is_hash' => false
60
+
61
+ response = client.get_details(shortcut)
62
+
63
+ response.should include 'url' => url
64
+ response.should include 'shortcut' => shortcut
65
+ response.should include 'owner' => ENV['GOOGLE_SHORT_LINKS_EMAIL']
66
+ response.should include 'is_public' => false
67
+ response.should include 'is_hash' => false
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,287 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe GoogleShortLinks::Client do
4
+ subject { GoogleShortLinks::Client }
5
+
6
+ it { should <= HTTParty }
7
+
8
+ describe '#initialize' do
9
+ subject { GoogleShortLinks::Client.new @params }
10
+
11
+ context 'with options { :server => "a", :secret => "b", :email => "c" }' do
12
+ before :each do
13
+ @params = { :server => 'a', :secret => 'b', :email => 'c' }
14
+ end
15
+
16
+ it 'sets server to a' do
17
+ subject.server.should == 'a'
18
+ end
19
+
20
+ it 'sets secret to b' do
21
+ subject.secret.should == 'b'
22
+ end
23
+
24
+ it 'sets email to c' do
25
+ subject.email.should == 'c'
26
+ end
27
+ end
28
+
29
+ context 'with options { :email => "c" }' do
30
+ before :each do
31
+ @params = { :email => 'c' }
32
+ end
33
+
34
+ it 'leaves server nil' do
35
+ subject.server.should be_nil
36
+ end
37
+
38
+ it 'leaves secret nil' do
39
+ subject.secret.should be_nil
40
+ end
41
+
42
+ it 'sets email to c' do
43
+ subject.email.should == 'c'
44
+ end
45
+ end
46
+
47
+ context 'with options {}' do
48
+ before :each do
49
+ @params = {}
50
+ end
51
+
52
+ it 'leaves server nil' do
53
+ subject.server.should be_nil
54
+ end
55
+
56
+ it 'leaves secret nil' do
57
+ subject.secret.should be_nil
58
+ end
59
+
60
+ it 'leaves email nil' do
61
+ subject.email.should be_nil
62
+ end
63
+ end
64
+ end
65
+
66
+ describe '#get_or_create_hash_url' do
67
+ subject { GoogleShortLinks::Client.new(@options).get_or_create_hash_url(@url, @params) }
68
+
69
+ context 'at 2011-11-17 13:04:15 -0500' do
70
+ before :each do
71
+ @now = Time.at(1321553055)
72
+ Timecop.freeze(@now)
73
+ end
74
+
75
+ after :each do
76
+ Timecop.return
77
+ end
78
+
79
+ context 'with server a, secret b, and email c' do
80
+ before :each do
81
+ @options = { :server => 'a', :secret => 'b', :email => 'c' }
82
+ end
83
+
84
+ context 'with url d' do
85
+ before :each do
86
+ @url = 'd'
87
+ end
88
+
89
+ context 'with empty params' do
90
+ before :each do
91
+ @params = {}
92
+ end
93
+
94
+ it 'should return a url with host a, path get_or_create_hash, signature method HMAC-SHA1, a current timestamp, url d, and user c, that is signed' do
95
+ subject.should == "http://a/js/get_or_create_hash?oauth_signature_method=HMAC-SHA1&timestamp=#{Time.now.to_f}&url=d&user=c&oauth_signature=H8ugo%2B8%2FHLIORPo9LjntVSClZXY%3D"
96
+ end
97
+ end
98
+
99
+ context 'with params oauth_signature_method HMAC-MD5, blah 123' do
100
+ before :each do
101
+ @params = { :oauth_signature_method => 'HMAC-MD5', :blah => 123 }
102
+ end
103
+
104
+ it 'should return a url with host a, path get_or_create_hash, signature method HMAC-MD5, a current timestamp, url d, user c, and extra parameter blah 123, that is signed' do
105
+ subject.should == "http://a/js/get_or_create_hash?blah=123&oauth_signature_method=HMAC-MD5&timestamp=#{Time.now.to_f}&url=d&user=c&oauth_signature=SHidraLOaaGtSP08qTXITZRk4nk%3D"
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ describe '#get_or_create_shortlink_url' do
114
+ subject { GoogleShortLinks::Client.new(@options).get_or_create_shortlink_url(@url, @shortcut, @params) }
115
+
116
+ context 'at 2011-11-17 13:04:15 -0500' do
117
+ before :each do
118
+ @now = Time.at(1321553055)
119
+ Timecop.freeze(@now)
120
+ end
121
+
122
+ after :each do
123
+ Timecop.return
124
+ end
125
+
126
+ context 'with server a, secret b, and email c' do
127
+ before :each do
128
+ @options = { :server => 'a', :secret => 'b', :email => 'c' }
129
+ end
130
+
131
+ context 'with url d' do
132
+ before :each do
133
+ @url = 'd'
134
+ end
135
+
136
+ context 'with a shortcut e' do
137
+ before :each do
138
+ @shortcut = 'e'
139
+ end
140
+
141
+ context 'with empty params' do
142
+ before :each do
143
+ @params = {}
144
+ end
145
+
146
+ it 'should return a url with host a, path get_or_create_shortlink, signature method HMAC-SHA1, shortcut e, a current timestamp, url d, and user c, that is signed' do
147
+ subject.should == "http://a/js/get_or_create_shortlink?oauth_signature_method=HMAC-SHA1&shortcut=e&timestamp=#{Time.now.to_f}&url=d&user=c&oauth_signature=Hf23Wj%2FoHARH4oyqy7FCgzUQrSk%3D"
148
+ end
149
+ end
150
+
151
+ context 'with params oauth_signature_method HMAC-MD5, blah 123' do
152
+ before :each do
153
+ @params = { :oauth_signature_method => 'HMAC-MD5', :blah => 123 }
154
+ end
155
+
156
+ it 'should return a url with host a, path get_or_create_shortlink, signature method HMAC-MD5, shortcut e, a current timestamp, url d, user c, and extra parameter blah 123, that is signed' do
157
+ subject.should == "http://a/js/get_or_create_shortlink?blah=123&oauth_signature_method=HMAC-MD5&shortcut=e&timestamp=#{Time.now.to_f}&url=d&user=c&oauth_signature=bdfkqZPbuqsKqalwou08oImutV0%3D"
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
165
+
166
+ describe '#get_details_url' do
167
+ subject { GoogleShortLinks::Client.new(@options).get_details_url(@shortcut, @params) }
168
+
169
+ context 'at 2011-11-17 13:04:15 -0500' do
170
+ before :each do
171
+ @now = Time.at(1321553055)
172
+ Timecop.freeze(@now)
173
+ end
174
+
175
+ after :each do
176
+ Timecop.return
177
+ end
178
+
179
+ context 'with server a, secret b, and email c' do
180
+ before :each do
181
+ @options = { :server => 'a', :secret => 'b', :email => 'c' }
182
+ end
183
+
184
+ context 'with a shortcut e' do
185
+ before :each do
186
+ @shortcut = 'e'
187
+ end
188
+
189
+ context 'with empty params' do
190
+ before :each do
191
+ @params = {}
192
+ end
193
+
194
+ it 'should return a url with host a, path get_details, signature method HMAC-SHA1, shortcut e, a current timestamp, and user c, that is signed' do
195
+ subject.should == "http://a/js/get_details?oauth_signature_method=HMAC-SHA1&shortcut=e&timestamp=#{Time.now.to_f}&user=c&oauth_signature=4uyxm8VBpvqEjoorn9Z60OhNsr8%3D"
196
+ end
197
+ end
198
+
199
+ context 'with params oauth_signature_method HMAC-MD5, blah 123' do
200
+ before :each do
201
+ @params = { :oauth_signature_method => 'HMAC-MD5', :blah => 123 }
202
+ end
203
+
204
+ it 'should return a url with host a, path get_details, signature method HMAC-MD5, shortcut e, a current timestamp, user c, and extra parameter blah 123, that is signed' do
205
+ subject.should == "http://a/js/get_details?blah=123&oauth_signature_method=HMAC-MD5&shortcut=e&timestamp=#{Time.now.to_f}&user=c&oauth_signature=iXvjBSxA87X45ShYk4JRb7W%2BcOw%3D"
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
211
+ end
212
+
213
+ describe '#get_or_create_hash' do
214
+ let(:client) { GoogleShortLinks::Client.new }
215
+
216
+ subject { client.get_or_create_hash(nil) }
217
+
218
+ context 'with get_or_create_hash_url returning http://www.example.org/' do
219
+ before :each do
220
+ client.stub!(:get_or_create_hash_url).and_return('http://www.example.org/')
221
+ end
222
+
223
+ it 'should call get with http://www.example.org/' do
224
+ GoogleShortLinks::Client.should_receive(:get).with('http://www.example.org/').and_return(mock(:parsed_response => nil))
225
+ subject
226
+ end
227
+
228
+ context 'when get returns a parsed response { "a" => "b" }' do
229
+ before :each do
230
+ GoogleShortLinks::Client.stub!(:get).with('http://www.example.org/').and_return(mock(:parsed_response => { 'a' => 'b'}))
231
+ end
232
+
233
+ it { should == { 'a' => 'b' } }
234
+ end
235
+ end
236
+ end
237
+
238
+ describe '#get_or_create_shortlink' do
239
+ let(:client) { GoogleShortLinks::Client.new }
240
+
241
+ subject { client.get_or_create_shortlink(nil, nil) }
242
+
243
+ context 'with get_or_create_shortlink_url returning http://www.example.org/' do
244
+ before :each do
245
+ client.stub!(:get_or_create_shortlink_url).and_return('http://www.example.org/')
246
+ end
247
+
248
+ it 'should call get with http://www.example.org/' do
249
+ GoogleShortLinks::Client.should_receive(:get).with('http://www.example.org/').and_return(mock(:parsed_response => nil))
250
+ subject
251
+ end
252
+
253
+ context 'when get returns a parsed response { "a" => "b" }' do
254
+ before :each do
255
+ GoogleShortLinks::Client.stub!(:get).with('http://www.example.org/').and_return(mock(:parsed_response => { 'a' => 'b'}))
256
+ end
257
+
258
+ it { should == { 'a' => 'b' } }
259
+ end
260
+ end
261
+ end
262
+
263
+ describe '#get_details' do
264
+ let(:client) { GoogleShortLinks::Client.new }
265
+
266
+ subject { client.get_details(nil) }
267
+
268
+ context 'with get_details_url returning http://www.example.org/' do
269
+ before :each do
270
+ client.stub!(:get_details_url).and_return('http://www.example.org/')
271
+ end
272
+
273
+ it 'should call get with http://www.example.org/' do
274
+ GoogleShortLinks::Client.should_receive(:get).with('http://www.example.org/').and_return(mock(:parsed_response => nil))
275
+ subject
276
+ end
277
+
278
+ context 'when get returns a parsed response { "a" => "b" }' do
279
+ before :each do
280
+ GoogleShortLinks::Client.stub!(:get).with('http://www.example.org/').and_return(mock(:parsed_response => { 'a' => 'b'}))
281
+ end
282
+
283
+ it { should == { 'a' => 'b' } }
284
+ end
285
+ end
286
+ end
287
+ end
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe GoogleShortLinks::Parser do
4
+ subject { GoogleShortLinks::Parser }
5
+
6
+ it { should <= HTTParty::Parser }
7
+
8
+ it('should support format :json') { should be_supports_format :json }
9
+
10
+ describe '#call' do
11
+ subject { GoogleShortLinks::Parser.call @body, @format }
12
+
13
+ context 'with a format of :json' do
14
+ before :each do
15
+ @format = :json
16
+ end
17
+
18
+ context 'with an body of {"a":"b"}' do
19
+ before :each do
20
+ @body = '{"a":"b"}'
21
+ end
22
+
23
+ it { should == {'a' => 'b'} }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,4 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
2
+
3
+ describe GoogleShortLinks do
4
+ end
@@ -0,0 +1,11 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'google_short_links'
5
+
6
+ require 'timecop'
7
+
8
+ Dir[File.join(File.dirname(__FILE__), 'support', '**', '*.rb')].each { |f| require f }
9
+
10
+ RSpec.configure do |config|
11
+ end
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: google_short_links
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Benjamin Manns
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: httparty
16
+ requirement: &8478620 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *8478620
25
+ - !ruby/object:Gem::Dependency
26
+ name: multi_json
27
+ requirement: &8487320 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *8487320
36
+ - !ruby/object:Gem::Dependency
37
+ name: jeweler
38
+ requirement: &8481700 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *8481700
47
+ - !ruby/object:Gem::Dependency
48
+ name: rcov
49
+ requirement: &8496100 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *8496100
58
+ - !ruby/object:Gem::Dependency
59
+ name: rdoc
60
+ requirement: &8494500 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *8494500
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: &8490100 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *8490100
80
+ - !ruby/object:Gem::Dependency
81
+ name: timecop
82
+ requirement: &8503320 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *8503320
91
+ description: Ruby wrapper for Google Short Links.
92
+ email: benmanns@gmail.com
93
+ executables: []
94
+ extensions: []
95
+ extra_rdoc_files:
96
+ - LICENSE.txt
97
+ - README.rdoc
98
+ files:
99
+ - .document
100
+ - .rspec
101
+ - .rvmrc
102
+ - .travis.yml
103
+ - Gemfile
104
+ - Gemfile.lock
105
+ - LICENSE.txt
106
+ - README.rdoc
107
+ - Rakefile
108
+ - VERSION
109
+ - google-short-links.gemspec
110
+ - google_short_links.gemspec
111
+ - lib/google_short_links.rb
112
+ - lib/google_short_links/client.rb
113
+ - lib/google_short_links/parser.rb
114
+ - spec/examples/google_short_links/client_spec.rb
115
+ - spec/google_short_links/client_spec.rb
116
+ - spec/google_short_links/parser_spec.rb
117
+ - spec/google_short_links_spec.rb
118
+ - spec/spec_helper.rb
119
+ homepage: https://github.com/benmanns/google_short_links
120
+ licenses:
121
+ - MIT
122
+ post_install_message:
123
+ rdoc_options: []
124
+ require_paths:
125
+ - lib
126
+ required_ruby_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ segments:
133
+ - 0
134
+ hash: -2353519240381542062
135
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
+ none: false
137
+ requirements:
138
+ - - ! '>='
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ requirements: []
142
+ rubyforge_project:
143
+ rubygems_version: 1.8.15
144
+ signing_key:
145
+ specification_version: 3
146
+ summary: Ruby wrapper for Google Short Links.
147
+ test_files: []