diff --git a/.gitignore b/.gitignore index 016916a..402de30 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ spec/dummy/tmp/ .rspec .rvmrc .rbenv-version +Gemfile.lock diff --git a/.travis.yml b/.travis.yml index bb6d718..b2b0ec6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,9 @@ language: ruby rvm: - - 1.8.7 - - 1.9.2 - 1.9.3 - 2.0.0 + - 2.1 + - 2.2 branches: only: - master diff --git a/Gemfile b/Gemfile index 75ec925..31ca2d6 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,11 @@ source "http://rubygems.org" -gem "httparty", "~> 0.10.0" +gem "httparty", "~> 0.10" gem "json", ">= 1.4.6" group :development do - gem "rspec", "~> 2.10.0" - gem "bundler", "~> 1.3.5" - gem "jeweler", "~> 1.8.3" + gem "rspec", "~> 2.10" + gem "jeweler", ">= 1.8.3" gem "webmock", "~> 1.8.6" + gem "timecop", "~> 0.7.1" end diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index a982026..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,74 +0,0 @@ -GEM - remote: http://rubygems.org/ - specs: - addressable (2.3.5) - builder (3.2.2) - crack (0.4.1) - safe_yaml (~> 0.9.0) - diff-lcs (1.1.3) - faraday (0.8.8) - multipart-post (~> 1.2.0) - git (1.2.5) - github_api (0.10.1) - addressable - faraday (~> 0.8.1) - hashie (>= 1.2) - multi_json (~> 1.4) - nokogiri (~> 1.5.2) - oauth2 - hashie (2.0.5) - highline (1.6.19) - httparty (0.10.2) - multi_json (~> 1.0) - multi_xml (>= 0.5.2) - httpauth (0.2.0) - jeweler (1.8.6) - builder - bundler (~> 1.0) - git (>= 1.2.5) - github_api (= 0.10.1) - highline (>= 1.6.15) - nokogiri (= 1.5.10) - rake - rdoc - json (1.8.0) - jwt (0.1.8) - multi_json (>= 1.5) - multi_json (1.7.7) - multi_xml (0.5.4) - multipart-post (1.2.0) - nokogiri (1.5.10) - oauth2 (0.9.2) - faraday (~> 0.8) - httpauth (~> 0.2) - jwt (~> 0.1.4) - multi_json (~> 1.0) - multi_xml (~> 0.5) - rack (~> 1.2) - rack (1.5.2) - rake (10.1.0) - rdoc (4.0.1) - json (~> 1.4) - rspec (2.10.0) - rspec-core (~> 2.10.0) - rspec-expectations (~> 2.10.0) - rspec-mocks (~> 2.10.0) - rspec-core (2.10.1) - rspec-expectations (2.10.0) - diff-lcs (~> 1.1.3) - rspec-mocks (2.10.1) - safe_yaml (0.9.4) - webmock (1.8.11) - addressable (>= 2.2.7) - crack (>= 0.1.7) - -PLATFORMS - ruby - -DEPENDENCIES - bundler (~> 1.3.5) - httparty (~> 0.10.0) - jeweler (~> 1.8.3) - json (>= 1.4.6) - rspec (~> 2.10.0) - webmock (~> 1.8.6) diff --git a/README.markdown b/README.markdown index 30767ee..4610450 100644 --- a/README.markdown +++ b/README.markdown @@ -14,6 +14,9 @@ Google URL Shortener API in Ruby ``` ruby url = Googl.shorten('http://www.zigotto.com') +# Optional - provide a user_ip and your google api_key to bypass Google's request rate limits +url = Googl.shorten('http://www.zigotto.com', "213.57.23.49", "google_api_key") + url.short_url #=> "http://goo.gl/ump4S" @@ -246,4 +249,4 @@ gem install googl ## License -MIT License. Copyright 2011-2014 Zigotto®. http://www.zigotto.com.br +MIT License. Copyright 2011-2015 Zigotto®. http://www.zigotto.com.br diff --git a/VERSION b/VERSION index a0a1517..7deb86f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.6.3 \ No newline at end of file +0.7.1 \ No newline at end of file diff --git a/googl.gemspec b/googl.gemspec index ae4f496..554c60f 100644 --- a/googl.gemspec +++ b/googl.gemspec @@ -2,31 +2,33 @@ # DO NOT EDIT THIS FILE DIRECTLY # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' # -*- encoding: utf-8 -*- +# stub: googl 0.7.1 ruby lib Gem::Specification.new do |s| s.name = "googl" - s.version = "0.6.3" + s.version = "0.7.1" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib"] s.authors = ["Jesus Lopes"] - s.date = "2013-01-21" + s.date = "2015-05-21" s.description = "Small library for Google URL Shortener API" s.email = "jlopes@zigotto.com.br" s.extra_rdoc_files = [ - "README.rdoc" + "README.markdown" ] s.files = [ ".travis.yml", "Gemfile", - "Gemfile.lock", "MIT-LICENSE", - "README.rdoc", + "README.markdown", "Rakefile", "VERSION", "googl.gemspec", "lib/googl.rb", "lib/googl/base.rb", "lib/googl/client_login.rb", + "lib/googl/error.rb", "lib/googl/expand.rb", "lib/googl/oauth2/native.rb", "lib/googl/oauth2/server.rb", @@ -65,38 +67,34 @@ Gem::Specification.new do |s| ] s.homepage = "http://github.com/zigotto/googl" s.licenses = ["MIT"] - s.require_paths = ["lib"] - s.rubygems_version = "1.8.23" + s.rubygems_version = "2.4.5" s.summary = "Wrapper for Google URL Shortener API" if s.respond_to? :specification_version then - s.specification_version = 3 + s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_runtime_dependency(%q, ["~> 0.10.0"]) + s.add_runtime_dependency(%q, ["~> 0.10"]) s.add_runtime_dependency(%q, [">= 1.4.6"]) - s.add_development_dependency(%q, ["~> 2.10.0"]) - s.add_development_dependency(%q, ["~> 1.2.3"]) - s.add_development_dependency(%q, ["~> 1.8.3"]) - s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, ["~> 2.10"]) + s.add_development_dependency(%q, [">= 1.8.3"]) s.add_development_dependency(%q, ["~> 1.8.6"]) + s.add_development_dependency(%q, ["~> 0.7.1"]) else - s.add_dependency(%q, ["~> 0.10.0"]) + s.add_dependency(%q, ["~> 0.10"]) s.add_dependency(%q, [">= 1.4.6"]) - s.add_dependency(%q, ["~> 2.10.0"]) - s.add_dependency(%q, ["~> 1.2.3"]) - s.add_dependency(%q, ["~> 1.8.3"]) - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.10"]) + s.add_dependency(%q, [">= 1.8.3"]) s.add_dependency(%q, ["~> 1.8.6"]) + s.add_dependency(%q, ["~> 0.7.1"]) end else - s.add_dependency(%q, ["~> 0.10.0"]) + s.add_dependency(%q, ["~> 0.10"]) s.add_dependency(%q, [">= 1.4.6"]) - s.add_dependency(%q, ["~> 2.10.0"]) - s.add_dependency(%q, ["~> 1.2.3"]) - s.add_dependency(%q, ["~> 1.8.3"]) - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 2.10"]) + s.add_dependency(%q, [">= 1.8.3"]) s.add_dependency(%q, ["~> 1.8.6"]) + s.add_dependency(%q, ["~> 0.7.1"]) end end diff --git a/lib/googl.rb b/lib/googl.rb index e31ab12..aa0e357 100644 --- a/lib/googl.rb +++ b/lib/googl.rb @@ -2,6 +2,7 @@ require 'ostruct' require 'json' +require 'googl/error' require 'googl/utils' require 'googl/base' require 'googl/request' @@ -23,9 +24,9 @@ module Googl # url.short_url # => "http://goo.gl/ump4S" # - def shorten(url=nil) + def shorten(url=nil, user_ip = nil, api_key = nil) raise ArgumentError.new("URL to shorten is required") if url.nil? || url.strip.empty? - Googl::Shorten.new(url) + Googl::Shorten.new(url, user_ip, api_key) end # Expands a short URL or gets creation time and analytics diff --git a/lib/googl/error.rb b/lib/googl/error.rb new file mode 100644 index 0000000..da7125d --- /dev/null +++ b/lib/googl/error.rb @@ -0,0 +1,4 @@ +module Googl + class Error < StandardError + end +end \ No newline at end of file diff --git a/lib/googl/shorten.rb b/lib/googl/shorten.rb index 5227e81..1ed938a 100644 --- a/lib/googl/shorten.rb +++ b/lib/googl/shorten.rb @@ -8,10 +8,20 @@ class Shorten < Base # Creates a new short URL, see Googl.shorten # - def initialize(long_url) + def initialize(long_url, user_ip = nil, api_key = nil) modify_headers('Content-Type' => 'application/json') - options = {"longUrl" => long_url}.to_json - resp = post(API_URL, :body => options) + options = {"longUrl" => long_url} + shorten_url = API_URL + + if (user_ip != nil && !user_ip.empty?) + options["userIp"] = user_ip + end + if (api_key != nil && !api_key.empty?) + shorten_url += "?key=#{api_key}" + end + + options_json = options.to_json + resp = post(shorten_url, :body => options_json) if resp.code == 200 self.short_url = resp['id'] self.long_url = resp['longUrl'] diff --git a/lib/googl/utils.rb b/lib/googl/utils.rb index 9e09abf..fc2c204 100644 --- a/lib/googl/utils.rb +++ b/lib/googl/utils.rb @@ -22,7 +22,7 @@ def get(url, params={}) end def exception(msg) - Exception.new(msg) + Googl::Error.new(msg) end end diff --git a/spec/googl/client_spec.rb b/spec/googl/client_spec.rb index 0d4e341..c327b72 100644 --- a/spec/googl/client_spec.rb +++ b/spec/googl/client_spec.rb @@ -44,7 +44,7 @@ describe "#short_url" do it "should return a short URL" do - subject.short_url.start_with?("http://goo.gl/").should be_true + subject.short_url.start_with?("http://goo.gl/").should be true end end diff --git a/spec/googl/oauth2/native_spec.rb b/spec/googl/oauth2/native_spec.rb index 0377618..84e2b72 100644 --- a/spec/googl/oauth2/native_spec.rb +++ b/spec/googl/oauth2/native_spec.rb @@ -85,7 +85,7 @@ before do @now = Time.now - Time.stub!(:now).and_return(@now) + Time.stub(:now).and_return(@now) end let(:native) { subject.request_access_token("4/SuSud6RqPojUXsPpeh-wSVCwnmTQ") } @@ -97,33 +97,36 @@ end describe "#expires?" do - - before :each do - Time.stub!(:now).and_return(Time.parse("2011-04-23 15:30:00")) + before do + Timecop.freeze(DateTime.parse("2011-04-23 15:30:00")) subject.request_access_token("4/SuSud6RqPojUXsPpeh-wSVCwnmTQ") end it "should be true if access token expires" do - Time.stub!(:now).and_return(Time.parse("2011-04-23 18:30:00")) - subject.expires?.should be_true + Timecop.freeze(DateTime.parse("2011-04-23 18:30:00")) do + subject.expires?.should be true + end end it "should be false if access token not expires" do - subject.expires?.should be_false + subject.expires?.should be false end + after do + Timecop.return + end end describe "#authorized?" do it "should return false if client is not authorized" do - subject.authorized?.should be_false + subject.authorized?.should be false end let(:native) { subject.request_access_token("4/SuSud6RqPojUXsPpeh-wSVCwnmTQ") } it "should return true if client is authorized" do - native.authorized?.should be_true + native.authorized?.should be true end end diff --git a/spec/googl/oauth2/server_spec.rb b/spec/googl/oauth2/server_spec.rb index c8e7dcc..1dfc238 100644 --- a/spec/googl/oauth2/server_spec.rb +++ b/spec/googl/oauth2/server_spec.rb @@ -86,10 +86,9 @@ end describe "#expires_at" do - before do @now = Time.now - Time.stub!(:now).and_return(@now) + Timecop.freeze(@now) end let(:server) { subject.request_access_token("4/z43CZpNmqd0IO3dR1Y_ouase13CH") } @@ -98,36 +97,42 @@ server.expires_at.should == (@now + 3600) end + after do + Timecop.return + end end describe "#expires?" do - before :each do - Time.stub!(:now).and_return(Time.parse("2011-04-23 15:30:00")) + Timecop.freeze(DateTime.parse("2011-04-23 15:30:00")) subject.request_access_token("4/z43CZpNmqd0IO3dR1Y_ouase13CH") end it "should be true if access token expires" do - Time.stub!(:now).and_return(Time.parse("2011-04-23 18:30:00")) - subject.expires?.should be_true + Timecop.freeze(DateTime.parse("2011-04-23 18:30:00")) do + subject.expires?.should be true + end end it "should be false if access token not expires" do - subject.expires?.should be_false + subject.expires?.should be false end + after do + Timecop.return + end end describe "#authorized?" do it "should return false if client is not authorized" do - subject.authorized?.should be_false + subject.authorized?.should be false end let(:server) { subject.request_access_token("4/z43CZpNmqd0IO3dR1Y_ouase13CH") } it "should return true if client is authorized" do - server.authorized?.should be_true + server.authorized?.should be true end end diff --git a/spec/googl/shorten_spec.rb b/spec/googl/shorten_spec.rb index b005c25..3d16d4d 100644 --- a/spec/googl/shorten_spec.rb +++ b/spec/googl/shorten_spec.rb @@ -53,6 +53,36 @@ end + context "with user_ip" do + subject { Googl.shorten('http://www.zigotto.com', "54.154.97.74") } + + describe "#short_url" do + it "should return a short URL" do + subject.short_url.should == 'http://goo.gl/ump4S' + end + end + end + + context "with api_key" do + subject { Googl.shorten('http://www.zigotto.com', nil, "Abc123") } + + describe "#short_url" do + it "should return a short URL" do + subject.short_url.should == 'http://goo.gl/ump4S' + end + end + end + + context "with user_ip and api_key" do + subject { Googl.shorten('http://www.zigotto.com', nil, "Abc123") } + + describe "#short_url" do + it "should return a short URL" do + subject.short_url.should == 'http://goo.gl/ump4S' + end + end + end + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1486f27..d6c2335 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -4,6 +4,7 @@ require "rubygems" require "rspec" require 'webmock/rspec' +require 'timecop' require 'googl' require 'shared_examples' @@ -30,6 +31,30 @@ def fake_urls?(status) with(:body => params). to_return(load_fixture('shorten_invalid_content_type.json')) + # Shorten with user_ip + url_shorten = "https://www.googleapis.com/urlshortener/v1/url" + params = "{\"longUrl\":\"http://www.zigotto.com\",\"userIp\":\"54.154.97.74\"}" #json + stub_request(:post, url_shorten). + with(:body => params, + :headers => {'Content-Type'=>'application/json'}). + to_return(load_fixture('shorten.json')) + + # Shorten with api_key + url_shorten_with_key = "https://www.googleapis.com/urlshortener/v1/url?key=Abc123" + params = "{\"longUrl\":\"http://www.zigotto.com\"}" #json + stub_request(:post, url_shorten_with_key). + with(:body => params, + :headers => {'Content-Type'=>'application/json'}). + to_return(load_fixture('shorten.json')) + + # Shorten with user_ip and api_key + url_shorten_with_key = "https://www.googleapis.com/urlshortener/v1/url?key=Abc123" + params = "{\"longUrl\":\"http://www.zigotto.com\",\"userIp\":\"54.154.97.74\"}" #json + stub_request(:post, url_shorten_with_key). + with(:body => params, + :headers => {'Content-Type'=>'application/json'}). + to_return(load_fixture('shorten.json')) + # Expand url_expand = "https://www.googleapis.com/urlshortener/v1/url?shortUrl=http://goo.gl/7lob" stub_request(:get, url_expand).to_return(load_fixture('expand.json'))