garb 0.7.3 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -200,8 +200,8 @@ TODOS
200
200
  Requirements
201
201
  ------------
202
202
 
203
- * happymapper >= 0.3.0 (should also install libxml)
204
- * active_support >= 2.3.0
203
+ * crack >= 0.1.6
204
+ * active_support >= 2.2.0
205
205
 
206
206
  Requirements for Testing
207
207
  ------------------------
data/Rakefile CHANGED
@@ -18,7 +18,7 @@ spec = Gem::Specification.new do |s|
18
18
  s.files = %w(README.md Rakefile) + Dir.glob("lib/**/*")
19
19
  s.test_files = Dir.glob("test/**/*")
20
20
 
21
- s.add_dependency("happymapper", [">= 0.3.0"])
21
+ s.add_dependency("crack", [">= 0.1.6"])
22
22
  s.add_dependency("activesupport", [">= 2.2.0"])
23
23
  end
24
24
 
data/lib/garb.rb CHANGED
@@ -5,7 +5,7 @@ require 'net/https'
5
5
 
6
6
  require 'cgi'
7
7
  require 'ostruct'
8
- require 'happymapper'
8
+ require 'crack'
9
9
  require 'active_support'
10
10
 
11
11
  require 'garb/version'
@@ -25,14 +25,18 @@ require 'support'
25
25
 
26
26
  module Garb
27
27
  GA = "http://schemas.google.com/analytics/2008"
28
-
29
- def self.to_google_analytics(thing)
28
+
29
+ extend self
30
+
31
+ def to_google_analytics(thing)
30
32
  return thing.to_google_analytics if thing.respond_to?(:to_google_analytics)
31
33
 
32
34
  "ga:#{thing.to_s.camelize(:lower)}"
33
35
  end
36
+ alias :to_ga :to_google_analytics
34
37
 
35
- def self.from_google_analytics(thing)
38
+ def from_google_analytics(thing)
36
39
  thing.to_s.gsub(/^ga\:/, '').underscore
37
40
  end
41
+ alias :from_ga :from_google_analytics
38
42
  end
data/lib/garb/profile.rb CHANGED
@@ -4,54 +4,34 @@ module Garb
4
4
  include ProfileReports
5
5
 
6
6
  attr_reader :session, :table_id, :title, :account_name, :account_id, :web_property_id
7
-
8
- class Property
9
- include HappyMapper
10
-
11
- tag 'property'
12
- namespace 'http://schemas.google.com/analytics/2009'
13
-
14
- attribute :name, String
15
- attribute :value, String
16
-
17
- def instance_name
18
- Garb.from_google_analytics(name)
19
- end
20
- end
21
-
22
- class Entry
23
- include HappyMapper
24
-
25
- tag 'entry'
26
-
27
- element :title, String
28
- element :tableId, String, :namespace => 'http://schemas.google.com/analytics/2009'
29
-
30
- has_many :properties, Property
31
- end
32
7
 
33
8
  def initialize(entry, session)
34
9
  @session = session
35
- @title = entry.title
36
- @table_id = entry.tableId
10
+ @title = entry['title']
11
+ @table_id = entry['dxp:tableId']
37
12
 
38
- entry.properties.each do |p|
39
- instance_variable_set :"@#{p.instance_name}", p.value
13
+ entry['dxp:property'].each do |p|
14
+ instance_variable_set :"@#{Garb.from_ga(p['name'])}", p['value']
40
15
  end
41
16
  end
42
17
 
43
18
  def id
44
- Garb.from_google_analytics(@table_id)
19
+ Garb.from_ga(@table_id)
45
20
  end
46
21
 
47
22
  def self.all(session = Session)
48
23
  url = "https://www.google.com/analytics/feeds/accounts/default"
49
- response = DataRequest.new(session, url).send_request
50
- Entry.parse(response.body).map {|entry| new(entry, session)}
24
+ response = DataRequest.new(session, url).send_request
25
+ parse(response.body).map {|entry| new(entry, session)}
51
26
  end
52
27
 
53
28
  def self.first(id, session = Session)
54
29
  all(session).detect {|profile| profile.id == id || profile.web_property_id == id }
55
30
  end
31
+
32
+ def self.parse(response_body)
33
+ entry_hash = Crack::XML.parse(response_body)
34
+ entry_hash ? [entry_hash['feed']['entry']].flatten : []
35
+ end
56
36
  end
57
37
  end
@@ -1,62 +1,33 @@
1
1
  module Garb
2
2
  class ReportResponse
3
- # include Enumerable
3
+ KEYS = ['dxp:metric', 'dxp:dimension']
4
4
 
5
5
  def initialize(response_body)
6
6
  @xml = response_body
7
7
  end
8
-
9
- def parse
10
- entries = Entry.parse(@xml)
11
-
12
- @results = entries.collect do |entry|
13
- hash = {}
14
-
15
- entry.metrics.each do |m|
16
- name = m.name.sub(/^ga\:/,'').underscore
17
- hash.merge!({name => m.value})
18
- end
19
-
20
- entry.dimensions.each do |d|
21
- name = d.name.sub(/^ga\:/,'').underscore
22
- hash.merge!({name => d.value})
23
- end
24
-
25
- OpenStruct.new(hash)
26
- end
27
- end
28
8
 
29
9
  def results
30
- @results || parse
10
+ @results ||= parse
31
11
  end
32
-
33
- class Metric
34
- include HappyMapper
35
12
 
36
- tag 'metric'
37
- namespace 'http://schemas.google.com/analytics/2009'
13
+ private
14
+ def parse
15
+ entries.map do |entry|
16
+ hash = values_for(entry).inject({}) do |h, v|
17
+ h.merge(Garb.from_ga(v['name']) => v['value'])
18
+ end
38
19
 
39
- attribute :name, String
40
- attribute :value, String
20
+ OpenStruct.new(hash)
21
+ end
41
22
  end
42
-
43
- class Dimension
44
- include HappyMapper
45
-
46
- tag 'dimension'
47
- namespace 'http://schemas.google.com/analytics/2009'
48
23
 
49
- attribute :name, String
50
- attribute :value, String
24
+ def entries
25
+ entry_hash = Crack::XML.parse(@xml)
26
+ entry_hash ? [entry_hash['feed']['entry']].flatten : []
51
27
  end
52
-
53
- class Entry
54
- include HappyMapper
55
-
56
- tag 'entry'
57
28
 
58
- has_many :metrics, Metric
59
- has_many :dimensions, Dimension
29
+ def values_for(entry)
30
+ KEYS.map {|k| entry[k]}.flatten.compact
60
31
  end
61
32
  end
62
- end
33
+ end
data/lib/garb/version.rb CHANGED
@@ -3,7 +3,7 @@ module Garb
3
3
 
4
4
  MAJOR = 0
5
5
  MINOR = 7
6
- TINY = 3
6
+ TINY = 4
7
7
 
8
8
  def self.to_s # :nodoc:
9
9
  [MAJOR, MINOR, TINY].join('.')
@@ -1,40 +1,38 @@
1
- <?xml version='1.0' encoding='UTF-8'?>
2
- <feed xmlns='http://www.w3.org/2005/Atom' xmlns:dxp='http://schemas.google.com/analytics/2009' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'>
3
- <id>http://www.google.com/analytics/feeds/accounts/tpitale@gmail.com</id>
4
- <updated>2009-10-02T07:47:35.000-07:00</updated>
5
- <title type='text'>Profile list for tpitale@gmail.com</title><link rel='self' type='application/atom+xml' href='http://www.google.com/analytics/feeds/accounts/default'/>
6
- <author>
7
- <name>Google Analytics</name>
8
- </author>
9
- <generator version='1.0'>Google Analytics</generator>
10
- <openSearch:totalResults>2</openSearch:totalResults>
11
- <openSearch:startIndex>1</openSearch:startIndex>
12
- <openSearch:itemsPerPage>2</openSearch:itemsPerPage>
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <feed xmlns="http://www.w3.org/2005/Atom" xmlns:dxp="http://schemas.google.com/analytics/2009" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/">
3
+ <id>http://www.google.com/analytics/feeds/accounts/tpitale@gmail.com</id>
4
+ <updated>2009-10-02T07:47:35.000-07:00</updated>
5
+ <title type="text">Profile list for tpitale@gmail.com</title>
6
+ <link rel="self" type="application/atom+xml" href="http://www.google.com/analytics/feeds/accounts/default"/>
7
+ <author><name>Google Analytics</name></author>
8
+ <generator version="1.0">Google Analytics</generator>
9
+ <openSearch:totalResults>2</openSearch:totalResults>
10
+ <openSearch:startIndex>1</openSearch:startIndex>
11
+ <openSearch:itemsPerPage>2</openSearch:itemsPerPage>
13
12
  <entry>
14
13
  <id>http://www.google.com/analytics/feeds/accounts/ga:12345</id>
15
14
  <updated>2008-07-21T14:05:57.000-07:00</updated>
16
- <title type='text'>Historical</title>
17
- <link rel='alternate' type='text/html' href='http://www.google.com/analytics'/>
18
- <dxp:property name='ga:accountId' value='1111'/>
19
- <dxp:property name='ga:accountName' value='Blog Beta'/>
20
- <dxp:property name='ga:profileId' value='1212'/>
21
- <dxp:property name='ga:webPropertyId' value='UA-1111-1'/>
22
- <dxp:property name='ga:currency' value='USD'/>
23
- <dxp:property name='ga:timezone' value='America/New_York'/>
24
- <dxp:tableId>ga:12345</dxp:tableId>
15
+ <title type="text">Historical</title>
16
+ <link rel="alternate" type="text/html" href="http://www.google.com/analytics"/>
17
+ <dxp:property name="ga:accountId" value="1111"/>
18
+ <dxp:property name="ga:accountName" value="Blog Beta"/>
19
+ <dxp:property name="ga:profileId" value="1212"/>
20
+ <dxp:property name="ga:webPropertyId" value="UA-1111-1"/>
21
+ <dxp:property name="ga:currency" value="USD"/>
22
+ <dxp:property name="ga:timezone" value="America/New_York"/>
23
+ <dxp:tableId>ga:12345</dxp:tableId>
25
24
  </entry>
26
25
  <entry>
27
26
  <id>http://www.google.com/analytics/feeds/accounts/ga:12346</id>
28
27
  <updated>2008-11-24T11:51:07.000-08:00</updated>
29
- <title type='text'>Presently</title>
30
- <link rel='alternate' type='text/html' href='http://www.google.com/analytics'/>
31
- <dxp:property name='ga:accountId' value='1111'/>
32
- <dxp:property name='ga:accountName' value='Blog Beta'/>
33
- <dxp:property name='ga:profileId' value='1213'/>
34
- <dxp:property name='ga:webPropertyId' value='UA-1111-2'/>
35
- <dxp:property name='ga:currency' value='USD'/>
36
- <dxp:property name='ga:timezone' value='America/New_York'/>
37
- <dxp:tableId>ga:12346</dxp:tableId>
28
+ <title type="text">Presently</title>
29
+ <link rel="alternate" type="text/html" href="http://www.google.com/analytics"/>
30
+ <dxp:property name="ga:accountId" value="1111"/>
31
+ <dxp:property name="ga:accountName" value="Blog Beta"/>
32
+ <dxp:property name="ga:profileId" value="1213"/>
33
+ <dxp:property name="ga:webPropertyId" value="UA-1111-2"/>
34
+ <dxp:property name="ga:currency" value="USD"/>
35
+ <dxp:property name="ga:timezone" value="America/New_York"/>
36
+ <dxp:tableId>ga:12346</dxp:tableId>
38
37
  </entry>
39
- </feed>
40
-
38
+ </feed>
@@ -1,8 +1,8 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <feed xmlns='http://www.w3.org/2005/Atom'
3
- xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'
4
- xmlns:dxp='http://schemas.google.com/analytics/2009'
5
- xmlns:ga='http://schemas.google.com/analytics/2008'>
2
+ <feed xmlns="http://www.w3.org/2005/Atom"
3
+ xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/"
4
+ xmlns:dxp="http://schemas.google.com/analytics/2009"
5
+ xmlns:ga="http://schemas.google.com/analytics/2008">
6
6
  <id>http://www.google.com/analytics/feeds/data?ids=ga:983247&amp;dimensions=ga:country,ga:city&amp;metrics=ga:pageViews&amp;start-date=2008-01-01&amp;end-date=2008-01-02</id>
7
7
  <updated>2008-01-02T15:59:59.999-08:00 </updated>
8
8
  <title type="text">Google Analytics Data for Profile 983247</title>
@@ -5,29 +5,19 @@ module Garb
5
5
 
6
6
  context "The Profile class" do
7
7
  setup {@session = Session.new}
8
-
8
+
9
9
  should "be able to return a list of all profiles" do
10
10
  url = 'https://www.google.com/analytics/feeds/accounts/default'
11
-
11
+
12
12
  xml = read_fixture('profile_feed.xml')
13
-
14
- data_request = mock
15
- data_request.expects(:send_request).with().returns(stub(:body => xml))
16
-
17
- DataRequest.expects(:new).with(@session, url).returns(data_request)
18
-
19
- entries = [stub]
20
-
21
- Profile::Entry.expects(:parse).with(xml).returns(entries)
22
-
23
- profiles = []
24
- entries.each do |entry|
25
- profile = stub
26
- profiles << profile
27
- Garb::Profile.expects(:new).with(entry, @session).returns(profile)
28
- end
29
-
30
- assert_equal profiles, Profile.all(@session)
13
+
14
+ data_request = stub
15
+ data_request.stubs(:send_request).returns(stub(:body => xml))
16
+ DataRequest.stubs(:new).returns(data_request)
17
+
18
+ assert_equal ['12345', '12346'], Profile.all(@session).map(&:id)
19
+ assert_received(DataRequest, :new) {|e| e.with(@session, url)}
20
+ assert_received(data_request, :send_request)
31
21
  end
32
22
 
33
23
  should "return the first profile for a given web property id" do
@@ -35,11 +25,11 @@ module Garb
35
25
  profile2 = stub(:web_property_id => '67890', :id => 'ghijkl')
36
26
  entries = [profile1, profile2]
37
27
 
38
- Garb::Profile.stubs(:all).returns(entries)
28
+ Profile.stubs(:all).returns(entries)
39
29
 
40
- assert_equal profile1, Garb::Profile.first('12345', @session)
30
+ assert_equal profile1, Profile.first('12345', @session)
41
31
 
42
- assert_received(Garb::Profile, :all) {|e| e.with(@session)}
32
+ assert_received(Profile, :all) {|e| e.with(@session)}
43
33
  end
44
34
 
45
35
  should "return the first profile for a given table id" do
@@ -47,41 +37,39 @@ module Garb
47
37
  profile2 = stub(:id => '67890', :web_property_id => 'ghijkl')
48
38
  entries = [profile1, profile2]
49
39
 
50
- Garb::Profile.stubs(:all).returns(entries)
40
+ Profile.stubs(:all).returns(entries)
51
41
 
52
- assert_equal profile2, Garb::Profile.first('67890', @session)
42
+ assert_equal profile2, Profile.first('67890', @session)
53
43
 
54
- assert_received(Garb::Profile, :all) {|e| e.with(@session)}
44
+ assert_received(Profile, :all) {|e| e.with(@session)}
55
45
  end
56
46
  end
57
47
 
58
48
  context "An instance of the Profile class" do
59
-
60
49
  setup do
61
- @entry = (Profile::Entry.parse(read_fixture('profile_feed.xml'))).first
62
- @profile = Profile.new(@entry, Session)
50
+ entry = Profile.parse(read_fixture('profile_feed.xml')).first
51
+ @profile = Profile.new(entry, Session)
63
52
  end
64
53
 
65
54
  should "have a value for :title" do
66
55
  assert_equal "Historical", @profile.title
67
56
  end
68
-
57
+
69
58
  should "have a value for :table_id" do
70
59
  assert_equal 'ga:12345', @profile.table_id
71
60
  end
72
-
61
+
73
62
  should "have a value for :id" do
74
63
  assert_equal '12345', @profile.id
75
64
  end
76
-
65
+
77
66
  should "have a value for :account_id" do
78
67
  assert_equal '1111', @profile.account_id
79
68
  end
80
-
69
+
81
70
  should "have a value for :account_name" do
82
71
  assert_equal 'Blog Beta', @profile.account_name
83
72
  end
84
73
  end
85
-
86
74
  end
87
- end
75
+ end
@@ -2,27 +2,12 @@ require File.join(File.dirname(__FILE__), '..', '..', '/test_helper')
2
2
 
3
3
  module Garb
4
4
  class ReportResponseTest < MiniTest::Unit::TestCase
5
- context "An instance of the ReportResponse class" do
6
- setup do
7
- @xml = File.read(File.join(File.dirname(__FILE__), '..', '..', "/fixtures/report_feed.xml"))
8
- @response = ReportResponse.new(@xml)
9
- end
10
-
11
- should "parse xml response with happymapper" do
12
- h1 = {"city"=>"(not set)", "pageviews"=>"33", "country"=>"(not set)"}
13
- h2 = {"city"=>"Kabul", "pageviews"=>"2", "country"=>"Afghanistan"}
14
- h3 = {"city"=>"Tirana", "pageviews"=>"1", "country"=>"Albania"}
15
-
16
- OpenStruct.expects(:new).with(h1).returns('entry1')
17
- OpenStruct.expects(:new).with(h2).returns('entry2')
18
- OpenStruct.expects(:new).with(h3).returns('entry3')
5
+ context "A ReportResponse" do
6
+ should "parse results from atom xml" do
7
+ filename = File.join(File.dirname(__FILE__), '..', '..', "/fixtures/report_feed.xml")
8
+ response = ReportResponse.new(File.read(filename))
19
9
 
20
- assert_equal(['entry1', 'entry2', 'entry3'], @response.parse)
21
- end
22
-
23
- should "have results or parse them" do
24
- @response.expects(:parse)
25
- @response.results
10
+ assert_equal ['33', '2', '1'], response.results.map(&:pageviews)
26
11
  end
27
12
  end
28
13
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 7
8
- - 3
9
- version: 0.7.3
8
+ - 4
9
+ version: 0.7.4
10
10
  platform: ruby
11
11
  authors:
12
12
  - Tony Pitale
@@ -14,11 +14,11 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-03-18 00:00:00 -04:00
17
+ date: 2010-03-25 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: happymapper
21
+ name: crack
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
24
  requirements:
@@ -26,9 +26,9 @@ dependencies:
26
26
  - !ruby/object:Gem::Version
27
27
  segments:
28
28
  - 0
29
- - 3
30
- - 0
31
- version: 0.3.0
29
+ - 1
30
+ - 6
31
+ version: 0.1.6
32
32
  type: :runtime
33
33
  version_requirements: *id001
34
34
  - !ruby/object:Gem::Dependency
@@ -40,9 +40,9 @@ dependencies:
40
40
  - !ruby/object:Gem::Version
41
41
  segments:
42
42
  - 2
43
- - 3
43
+ - 2
44
44
  - 0
45
- version: 2.3.0
45
+ version: 2.2.0
46
46
  type: :runtime
47
47
  version_requirements: *id002
48
48
  description: