google_url_shortener 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,5 +1,6 @@
1
1
  source :gemcutter
2
2
  gemspec
3
3
 
4
+ gem "fakeweb"
4
5
  gem "json", "1.4.6"
5
6
  gem "rest-client", "1.6.1", :require => "restclient"
data/Gemfile.lock CHANGED
@@ -1,13 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- google_url_shortener (0.0.2)
4
+ google_url_shortener (0.0.3)
5
5
  json (= 1.4.6)
6
6
  rest-client (= 1.6.1)
7
7
 
8
8
  GEM
9
9
  remote: http://rubygems.org/
10
10
  specs:
11
+ fakeweb (1.3.0)
11
12
  json (1.4.6)
12
13
  mime-types (1.16)
13
14
  rest-client (1.6.1)
@@ -18,6 +19,7 @@ PLATFORMS
18
19
 
19
20
  DEPENDENCIES
20
21
  bundler (>= 1.0.0)
22
+ fakeweb
21
23
  google_url_shortener!
22
24
  json (= 1.4.6)
23
25
  rest-client (= 1.6.1)
@@ -9,11 +9,10 @@ Gem::Specification.new do |s|
9
9
  s.email = ["josh@josh-nesbitt.net"]
10
10
  s.homepage = "http://rubygems.org/gems/google_url_shortener"
11
11
  s.summary = "A simple library to shorten and expand goo.gl URL's."
12
- s.description = "Google URL Shortener is a library to compress and expand goo.gl URL's. It also provides an interface to view analytics of any given URL."
12
+ s.description = "Google URL Shortener is a library to compress and expand goo.gl URL's. It also provides an interface to review the analytics of a short URL."
13
13
 
14
14
  s.required_rubygems_version = ">= 1.3.6"
15
- s.rubyforge_project = "google_url_shortener"
16
-
15
+ s.rubyforge_project = "google_url_shortener"
17
16
  s.add_dependency "json", "1.4.6"
18
17
  s.add_dependency "rest-client", "1.6.1"
19
18
  s.add_development_dependency "bundler", ">= 1.0.0"
@@ -1,21 +1,20 @@
1
1
  require 'restclient'
2
2
  require 'json'
3
+ require 'date'
3
4
 
4
- %w{ version request base url }.each do |f|
5
+ %w{ version request base url analytics analytics_group errors }.each do |f|
5
6
  require("#{GEM_ROOT}/lib/google/url_shortener/#{f}")
6
7
  end
7
8
 
8
9
  module Google
9
10
  module UrlShortener
10
- class << self
11
-
12
- def shorten!(url)
13
- Url.new(:long_url => url).shorten!
14
- end
15
-
16
- def expand!(url)
17
- Url.new(:short_url => url).expand!
18
- end
11
+
12
+ def self.shorten!(url)
13
+ Url.new(:long_url => url).shorten!
14
+ end
15
+
16
+ def self.expand!(url)
17
+ Url.new(:short_url => url).expand!
19
18
  end
20
19
  end
21
20
  end
@@ -0,0 +1,28 @@
1
+ module Google
2
+ module UrlShortener
3
+ class Analytics
4
+ PROJECTION_LEVEL = "FULL"
5
+ attr_reader :raw, :all, :month, :week, :day, :two_hours
6
+
7
+ class << self
8
+ def from_hash(hash)
9
+ a = new(hash)
10
+ a.parse_all!
11
+ a
12
+ end
13
+ end
14
+
15
+ def initialize(raw={})
16
+ @raw = raw.dup
17
+ end
18
+
19
+ def parse_all!
20
+ @all = AnalyticsGroup.from_hash(self.raw["allTime"])
21
+ @month = AnalyticsGroup.from_hash(self.raw["month"])
22
+ @week = AnalyticsGroup.from_hash(self.raw["week"])
23
+ @day = AnalyticsGroup.from_hash(self.raw["day"])
24
+ @two_hours = AnalyticsGroup.from_hash(self.raw["twoHours"])
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,46 @@
1
+ module Google
2
+ module UrlShortener
3
+ class AnalyticsGroup
4
+ attr_reader :raw,
5
+ :short_url_clicks,
6
+ :long_url_clicks,
7
+ :referrers,
8
+ :countries,
9
+ :browsers,
10
+ :platforms
11
+
12
+ class << self
13
+ def from_hash(hash)
14
+ a = new(hash)
15
+ a.parse_all!
16
+ a
17
+ end
18
+ end
19
+
20
+ def initialize(raw={})
21
+ @raw = raw.dup
22
+ @short_url_clicks = self.raw["shortUrlClicks"].to_i
23
+ @long_url_clicks = self.raw["longUrlClicks"].to_i
24
+ end
25
+
26
+ def parse_all!
27
+ %w{ referrers countries browsers platforms }.each do |g|
28
+ self.instance_variable_set(:"@#{g}", reverse_array(self.raw[g]))
29
+ end
30
+ end
31
+
32
+ private
33
+ def reverse_array(array=[])
34
+ hash = {}
35
+
36
+ return hash if array.nil?
37
+
38
+ array.each do |entry|
39
+ hash[entry["id"]] = entry["count"].to_i
40
+ end
41
+
42
+ hash
43
+ end
44
+ end
45
+ end
46
+ end
@@ -12,7 +12,11 @@ module Google
12
12
  end
13
13
 
14
14
  def api_key
15
- @@api_key
15
+ begin
16
+ @@api_key
17
+ rescue NameError
18
+ raise MissingApiKey, "No API key has been set!"
19
+ end
16
20
  end
17
21
  end
18
22
  end
@@ -0,0 +1,14 @@
1
+ module Google
2
+ module UrlShortener
3
+ class UrlShortenerError < StandardError
4
+ attr_accessor :data
5
+
6
+ def initialize(data)
7
+ self.data = data
8
+ super
9
+ end
10
+ end
11
+
12
+ class MissingApiKey < UrlShortenerError;end
13
+ end
14
+ end
@@ -2,7 +2,7 @@ module Google
2
2
  module UrlShortener
3
3
  class Url < Base
4
4
  include Request
5
- attr_reader :long_url, :short_url, :status
5
+ attr_reader :long_url, :short_url, :status, :created_at, :analytics
6
6
 
7
7
  def initialize(opts={})
8
8
  opts.each_pair do |k, v|
@@ -11,11 +11,12 @@ module Google
11
11
  end
12
12
 
13
13
  def decode!
14
- params = validate_and_prepare_params(:shortUrl => self.short_url, :projection => "FULL")
14
+ params = validate_and_prepare_params(:shortUrl => self.short_url, :projection => Analytics::PROJECTION_LEVEL)
15
15
  response = get(params)
16
16
 
17
- # TODO: get more info from response
18
- @long_url = response["longUrl"]
17
+ @created_at = Date.parse(response["created"])
18
+ @analytics = Analytics.from_hash(response["analytics"])
19
+ @long_url = response["longUrl"]
19
20
  end
20
21
  alias_method :expand!, :decode!
21
22
 
@@ -1,6 +1,6 @@
1
1
  module Google
2
2
  module UrlShortener
3
- VERSION = "0.0.3"
3
+ VERSION = "0.0.4"
4
4
 
5
5
  end
6
6
  end
data/readme.textile CHANGED
@@ -9,6 +9,8 @@ h1. Google Url Shortener.
9
9
 
10
10
  h2. Overview
11
11
 
12
+ Google URL Shortener is a library to compress and expand goo.gl URL's. It also provides an interface to review the analytics of a short URL.
13
+
12
14
 
13
15
 
14
16
  h2. Installation
@@ -24,7 +26,7 @@ h2. Usage
24
26
 
25
27
  h3. Setup
26
28
 
27
- You need to provide an API to use the URL shortener service. To do this set the @api_key@ class variable:
29
+ You need to provide an API key to use the URL shortener service. To do this set the @api_key@ class variable:
28
30
 
29
31
  pre. Google::UrlShortener::Base.api_key = "KEY"
30
32
 
@@ -54,6 +56,32 @@ Or the shorthand form:
54
56
  pre. Google::UrlShortener.expand!("http://goo.gl/r5akx") # => http://blog.josh-nesbitt.net
55
57
 
56
58
 
59
+ h3. Getting more data from an expanded URL
60
+
61
+ More data is available from a URL once it's been expanded:
62
+
63
+ pre. url = Google::UrlShortener::Url.new(:short_url => "http://goo.gl/r5akx")
64
+ url.expand! # => http://blog.josh-nesbitt.net
65
+ url.created_at # => 2011-01-11
66
+ url.created_at.year # => 2011
67
+ url.analytics # => Google::UrlShortener::Analytics
68
+ url.analytics.all # => Google::UrlShortener::AnalyticsGroup
69
+ url.analytics.all.browsers # => { "Chrome" => 1 }
70
+ url.analytics.all.countries # => { "GB" => 1 }
71
+ url.analytics.all.platforms # => { "Macintosh" => 1 }
72
+ url.analytics.all.referrers # => { "Unknown/empty" => 1 }
73
+ url.analytics.all.long_url_clicks # => 23
74
+ url.analytics.all.short_url_clicks # => 3
75
+
76
+ Available scopes are:
77
+
78
+ pre. all
79
+ month
80
+ week
81
+ day
82
+ two_hours
83
+
84
+ E.g: @url.analytics.month@.
57
85
 
58
86
  h2. Bugs
59
87
 
@@ -0,0 +1,101 @@
1
+ {
2
+ "kind": "urlshortener#url",
3
+ "id": "http://goo.gl/r5akx",
4
+ "longUrl": "http://blog.josh-nesbitt.net/",
5
+ "status": "OK",
6
+ "created": "2011-01-11T20:53:38.778+00:00",
7
+ "analytics": {
8
+ "allTime": {
9
+ "shortUrlClicks": "1",
10
+ "longUrlClicks": "1",
11
+ "referrers": [
12
+ {
13
+ "count": "1",
14
+ "id": "Unknown/empty"
15
+ }
16
+ ],
17
+ "countries": [
18
+ {
19
+ "count": "1",
20
+ "id": "GB"
21
+ }
22
+ ],
23
+ "browsers": [
24
+ {
25
+ "count": "1",
26
+ "id": "Chrome"
27
+ }
28
+ ],
29
+ "platforms": [
30
+ {
31
+ "count": "1",
32
+ "id": "Macintosh"
33
+ }
34
+ ]
35
+ },
36
+ "month": {
37
+ "shortUrlClicks": "1",
38
+ "longUrlClicks": "1",
39
+ "referrers": [
40
+ {
41
+ "count": "1",
42
+ "id": "Unknown/empty"
43
+ }
44
+ ],
45
+ "countries": [
46
+ {
47
+ "count": "1",
48
+ "id": "GB"
49
+ }
50
+ ],
51
+ "browsers": [
52
+ {
53
+ "count": "1",
54
+ "id": "Chrome"
55
+ }
56
+ ],
57
+ "platforms": [
58
+ {
59
+ "count": "1",
60
+ "id": "Macintosh"
61
+ }
62
+ ]
63
+ },
64
+ "week": {
65
+ "shortUrlClicks": "1",
66
+ "longUrlClicks": "1",
67
+ "referrers": [
68
+ {
69
+ "count": "1",
70
+ "id": "Unknown/empty"
71
+ }
72
+ ],
73
+ "countries": [
74
+ {
75
+ "count": "1",
76
+ "id": "GB"
77
+ }
78
+ ],
79
+ "browsers": [
80
+ {
81
+ "count": "1",
82
+ "id": "Chrome"
83
+ }
84
+ ],
85
+ "platforms": [
86
+ {
87
+ "count": "1",
88
+ "id": "Macintosh"
89
+ }
90
+ ]
91
+ },
92
+ "day": {
93
+ "shortUrlClicks": "0",
94
+ "longUrlClicks": "0"
95
+ },
96
+ "twoHours": {
97
+ "shortUrlClicks": "0",
98
+ "longUrlClicks": "0"
99
+ }
100
+ }
101
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "kind": "urlshorFAKEtener#url",
3
+ "id": "http://goo.gl/r5akx",
4
+ "longUrl": "http://blog.josh-nesbitt.net/"
5
+ }
@@ -0,0 +1,14 @@
1
+ module FakewebHelper
2
+
3
+ def stub_request(url, opts={})
4
+ method = opts[:method] || :get
5
+ fixture = opts[:fixture] || "Fakeweb request body"
6
+ body = begin
7
+ File.read(File.expand_path(File.dirname(__FILE__)) + "/../fixtures/#{fixture}.json")
8
+ rescue Errno::ENOENT
9
+ raise "Could not find fixture file named '#{fixture}'!"
10
+ end
11
+
12
+ FakeWeb.register_uri(method, url, :body => body)
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ module Google
2
+ module UrlShortener
3
+ describe Analytics do
4
+
5
+ before(:all) do
6
+ stub_request(Google::UrlShortener::Request::BASE_URL + "?shortUrl=#{@short_url}&projection=FULL&key=#{@key}", :fixture => "expand")
7
+ url = Google::UrlShortener::Url.new(:short_url => @short_url)
8
+ url.expand!
9
+
10
+ @analytics = url.analytics
11
+ end
12
+
13
+ it "should parse the analytics data correctly." do
14
+ @analytics.all.browsers.class.should == Hash
15
+ @analytics.all.referrers.class.should == Hash
16
+ @analytics.all.countries.class.should == Hash
17
+ @analytics.all.platforms.class.should == Hash
18
+
19
+ @analytics.all.browsers.should include("Chrome")
20
+ @analytics.all.referrers.should include("Unknown/empty")
21
+ @analytics.all.countries.should include("GB")
22
+ @analytics.all.platforms.should include("Macintosh")
23
+
24
+ @analytics.all.short_url_clicks.should == 1
25
+ @analytics.all.long_url_clicks.should == 1
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,22 @@
1
+ module Google
2
+ module UrlShortener
3
+ describe Base do
4
+
5
+ it "should allow an API key to be set" do
6
+ key = "apikey"
7
+ Base.api_key = key
8
+ Base.api_key.should == key
9
+ end
10
+
11
+ it "should allow a logger to be set" do
12
+ RestClient.log = nil
13
+ RestClient.log.should == nil
14
+
15
+ Base.log = $stdout
16
+ RestClient.log.should == $stdout
17
+
18
+ Base.log = nil
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ module Google
2
+ module UrlShortener
3
+ describe Url do
4
+
5
+ it "should have the correct attributes after shortening a URL" do
6
+ stub_request(Google::UrlShortener::Request::BASE_URL, :method => :post, :fixture => "shorten")
7
+
8
+ url = Google::UrlShortener::Url.new(:long_url => @long_url)
9
+ url.shorten!
10
+
11
+ url.long_url.should == @long_url
12
+ url.short_url.should == @short_url
13
+ end
14
+
15
+ it "should have the correct attributes after expanding a URL" do
16
+ stub_request(Google::UrlShortener::Request::BASE_URL + "?shortUrl=#{@short_url}&projection=FULL&key=#{@key}", :fixture => "expand")
17
+
18
+ url = Google::UrlShortener::Url.new(:short_url => @short_url)
19
+ url.expand!
20
+
21
+ url.long_url.should == @long_url
22
+ url.short_url.should == @short_url
23
+ url.created_at.year.should == 2011
24
+ url.created_at.month.should == 01
25
+ url.created_at.day.should == 11
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,18 @@
1
+ module Google
2
+ describe UrlShortener do
3
+
4
+ it "should shorten a URL" do
5
+ stub_request(Google::UrlShortener::Request::BASE_URL, :method => :post, :fixture => "shorten")
6
+
7
+ url = UrlShortener.shorten!(@long_url)
8
+ url.should == @short_url
9
+ end
10
+
11
+ it "should expand a URL" do
12
+ stub_request(Google::UrlShortener::Request::BASE_URL + "?shortUrl=#{@short_url}&projection=FULL&key=#{@key}", :fixture => "expand")
13
+
14
+ url = UrlShortener.expand!(@short_url)
15
+ url.should == @long_url
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ Dir[File.dirname(__FILE__) + "/helpers/*"].each { |f| require(f) }
4
+ require 'google_url_shortener'
5
+ require 'fakeweb'
6
+ require 'spec'
7
+ include FakewebHelper
8
+
9
+ Spec::Runner.configure do |config|
10
+
11
+ config.before(:all) do
12
+ Google::UrlShortener::Base.api_key = "TESTKEY"
13
+ @key = Google::UrlShortener::Base.api_key
14
+ @short_url = "http://goo.gl/r5akx"
15
+ @long_url = "http://blog.josh-nesbitt.net/"
16
+ end
17
+
18
+ end
data/spec/watch.rb ADDED
@@ -0,0 +1,28 @@
1
+ # A simple alternative to autotest that isnt painful
2
+
3
+ options = {
4
+ :options => "--require '#{File.expand_path(File.dirname(__FILE__)) + "/spec_helper"}' --format nested --color",
5
+ :binary => "spec"
6
+ }
7
+
8
+ watch("(lib|spec)/(.*)\.rb") do |match|
9
+ puts %x[ clear ]
10
+
11
+ file = match[match.size - 1]
12
+ opts = options[:options]
13
+ binary = options[:binary]
14
+
15
+ files = []
16
+
17
+ ["spec/lib/*.rb", "spec/lib/*/*.rb"].each do |glob|
18
+ Dir.glob(glob).each { |f| files << f }
19
+ end
20
+
21
+ puts "Found:"
22
+ files.each { |f| puts "+ #{f}" }
23
+ puts ""
24
+ command = "#{binary} #{files.collect! { |f| File.expand_path(f) }.join(" ")} #{opts}"
25
+
26
+ system(command)
27
+
28
+ end
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google_url_shortener
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
7
  - 0
9
- - 3
10
- version: 0.0.3
8
+ - 4
9
+ version: 0.0.4
11
10
  platform: ruby
12
11
  authors:
13
12
  - Josh Nesbitt
@@ -26,7 +25,6 @@ dependencies:
26
25
  requirements:
27
26
  - - "="
28
27
  - !ruby/object:Gem::Version
29
- hash: 11
30
28
  segments:
31
29
  - 1
32
30
  - 4
@@ -42,7 +40,6 @@ dependencies:
42
40
  requirements:
43
41
  - - "="
44
42
  - !ruby/object:Gem::Version
45
- hash: 13
46
43
  segments:
47
44
  - 1
48
45
  - 6
@@ -58,7 +55,6 @@ dependencies:
58
55
  requirements:
59
56
  - - ">="
60
57
  - !ruby/object:Gem::Version
61
- hash: 23
62
58
  segments:
63
59
  - 1
64
60
  - 0
@@ -66,7 +62,7 @@ dependencies:
66
62
  version: 1.0.0
67
63
  type: :development
68
64
  version_requirements: *id003
69
- description: Google URL Shortener is a library to compress and expand goo.gl URL's. It also provides an interface to view analytics of any given URL.
65
+ description: Google URL Shortener is a library to compress and expand goo.gl URL's. It also provides an interface to review the analytics of a short URL.
70
66
  email:
71
67
  - josh@josh-nesbitt.net
72
68
  executables: []
@@ -84,12 +80,23 @@ files:
84
80
  - google_url_shortener.gemspec
85
81
  - lib/google/url_shortener.rb
86
82
  - lib/google/url_shortener/analytics.rb
83
+ - lib/google/url_shortener/analytics_group.rb
87
84
  - lib/google/url_shortener/base.rb
85
+ - lib/google/url_shortener/errors.rb
88
86
  - lib/google/url_shortener/request.rb
89
87
  - lib/google/url_shortener/url.rb
90
88
  - lib/google/url_shortener/version.rb
91
89
  - lib/google_url_shortener.rb
92
90
  - readme.textile
91
+ - spec/fixtures/expand.json
92
+ - spec/fixtures/shorten.json
93
+ - spec/helpers/fakeweb.rb
94
+ - spec/lib/google/analytics_spec.rb
95
+ - spec/lib/google/base_spec.rb
96
+ - spec/lib/google/url_spec.rb
97
+ - spec/lib/url_shortener_spec.rb
98
+ - spec/spec_helper.rb
99
+ - spec/watch.rb
93
100
  has_rdoc: true
94
101
  homepage: http://rubygems.org/gems/google_url_shortener
95
102
  licenses: []
@@ -104,7 +111,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
104
111
  requirements:
105
112
  - - ">="
106
113
  - !ruby/object:Gem::Version
107
- hash: 3
108
114
  segments:
109
115
  - 0
110
116
  version: "0"
@@ -113,7 +119,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
119
  requirements:
114
120
  - - ">="
115
121
  - !ruby/object:Gem::Version
116
- hash: 23
117
122
  segments:
118
123
  - 1
119
124
  - 3