nokogiri-happymapper 0.3.5 → 0.3.6
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/happymapper.rb +7 -0
- data/spec/fixtures/analytics_profile.xml +127 -0
- data/spec/happymapper_spec.rb +45 -0
- metadata +10 -8
data/lib/happymapper.rb
CHANGED
@@ -12,6 +12,8 @@ module HappyMapper
|
|
12
12
|
def self.included(base)
|
13
13
|
base.instance_variable_set("@attributes", {})
|
14
14
|
base.instance_variable_set("@elements", {})
|
15
|
+
base.instance_variable_set("@registered_namespaces", {})
|
16
|
+
|
15
17
|
base.extend ClassMethods
|
16
18
|
end
|
17
19
|
|
@@ -27,6 +29,10 @@ module HappyMapper
|
|
27
29
|
@attributes[to_s] || []
|
28
30
|
end
|
29
31
|
|
32
|
+
def register_namespace(namespace, ns)
|
33
|
+
@registered_namespaces.merge!({namespace => ns})
|
34
|
+
end
|
35
|
+
|
30
36
|
def element(name, type, options={})
|
31
37
|
element = Element.new(name, type, options)
|
32
38
|
@elements[to_s] ||= []
|
@@ -93,6 +99,7 @@ module HappyMapper
|
|
93
99
|
namespaces = options[:namespaces]
|
94
100
|
namespaces ||= {}
|
95
101
|
namespaces = namespaces.merge(xml.collect_namespaces) if xml.respond_to?(:collect_namespaces)
|
102
|
+
namespaces = namespaces.merge(@registered_namespaces)
|
96
103
|
|
97
104
|
if namespaces.has_key?("xmlns")
|
98
105
|
namespace ||= DEFAULT_NS
|
@@ -0,0 +1,127 @@
|
|
1
|
+
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:dxp='http://schemas.google.com/analytics/2009' xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/' xmlns:gd='http://schemas.google.com/g/2005' gd:etag='W/"CU4CSXo_cCp7I2A9Wx9RGU0."' gd:kind='analytics#accounts'>
|
2
|
+
<id>http://www.google.com/analytics/feeds/accounts/someuser@gmail.com</id>
|
3
|
+
<updated>2010-12-20T19:59:28.448-08:00</updated>
|
4
|
+
<title>Profile list for someuser@gmail.com</title>
|
5
|
+
<link rel='self' type='application/atom+xml' href='https://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>9</openSearch:totalResults>
|
11
|
+
<openSearch:startIndex>1</openSearch:startIndex>
|
12
|
+
<openSearch:itemsPerPage>9</openSearch:itemsPerPage>
|
13
|
+
<dxp:segment id='gaid::-1' name='All Visits'>
|
14
|
+
<dxp:definition> </dxp:definition>
|
15
|
+
</dxp:segment>
|
16
|
+
<dxp:segment id='gaid::-2' name='New Visitors'>
|
17
|
+
<dxp:definition>ga:visitorType==New Visitor</dxp:definition>
|
18
|
+
</dxp:segment>
|
19
|
+
<dxp:segment id='gaid::-3' name='Returning Visitors'>
|
20
|
+
<dxp:definition>ga:visitorType==Returning Visitor</dxp:definition>
|
21
|
+
</dxp:segment>
|
22
|
+
<dxp:segment id='gaid::-4' name='Paid Search Traffic'>
|
23
|
+
<dxp:definition>ga:medium==cpa,ga:medium==cpc,ga:medium==cpm,ga:medium==cpp,ga:medium==cpv,ga:medium==ppc</dxp:definition>
|
24
|
+
</dxp:segment>
|
25
|
+
<dxp:segment id='gaid::-5' name='Non-paid Search Traffic'>
|
26
|
+
<dxp:definition>ga:medium==organic</dxp:definition>
|
27
|
+
</dxp:segment>
|
28
|
+
<dxp:segment id='gaid::-6' name='Search Traffic'>
|
29
|
+
<dxp:definition>ga:medium==cpa,ga:medium==cpc,ga:medium==cpm,ga:medium==cpp,ga:medium==cpv,ga:medium==organic,ga:medium==ppc</dxp:definition>
|
30
|
+
</dxp:segment>
|
31
|
+
<dxp:segment id='gaid::-7' name='Direct Traffic'>
|
32
|
+
<dxp:definition>ga:medium==(none)</dxp:definition>
|
33
|
+
</dxp:segment>
|
34
|
+
<dxp:segment id='gaid::-8' name='Referral Traffic'>
|
35
|
+
<dxp:definition>ga:medium==referral</dxp:definition>
|
36
|
+
</dxp:segment>
|
37
|
+
<dxp:segment id='gaid::-9' name='Visits with Conversions'>
|
38
|
+
<dxp:definition>ga:goalCompletionsAll>0</dxp:definition>
|
39
|
+
</dxp:segment>
|
40
|
+
<dxp:segment id='gaid::-10' name='Visits with Transactions'>
|
41
|
+
<dxp:definition>ga:transactions>0</dxp:definition>
|
42
|
+
</dxp:segment>
|
43
|
+
<dxp:segment id='gaid::-11' name='Mobile Traffic'>
|
44
|
+
<dxp:definition>ga:isMobile==Yes</dxp:definition>
|
45
|
+
</dxp:segment>
|
46
|
+
<dxp:segment id='gaid::-12' name='Non-bounce Visits'>
|
47
|
+
<dxp:definition>ga:bounces==0</dxp:definition>
|
48
|
+
</dxp:segment>
|
49
|
+
<entry gd:etag='W/"CkENQXs9fip7I2A9Wx5SE0w."' gd:kind='analytics#account'>
|
50
|
+
<id>http://www.google.com/analytics/feeds/accounts/ga:123456</id>
|
51
|
+
<updated>2010-08-08T16:38:10.566-07:00</updated>
|
52
|
+
<title>www.homedepot.com</title>
|
53
|
+
<link rel='alternate' type='text/html' href='http://www.google.com/analytics'/>
|
54
|
+
<dxp:property name='ga:accountId' value='254087'/>
|
55
|
+
<dxp:property name='ga:accountName' value='www.homechefdepot.com'/>
|
56
|
+
<dxp:property name='ga:profileId' value='123456'/>
|
57
|
+
<dxp:property name='ga:webPropertyId' value='UA-254087-1'/>
|
58
|
+
<dxp:property name='ga:currency' value='USD'/>
|
59
|
+
<dxp:property name='ga:timezone' value='America/Los_Angeles'/>
|
60
|
+
<dxp:tableId>ga:123456</dxp:tableId>
|
61
|
+
</entry>
|
62
|
+
<entry gd:etag='W/"C0YESXcyfyp7I2A9Wx9SFkU."' gd:kind='analytics#account'>
|
63
|
+
<id>http://www.google.com/analytics/feeds/accounts/ga:8575980</id>
|
64
|
+
<updated>2010-12-06T16:18:28.997-08:00</updated>
|
65
|
+
<title>www.pda.org</title>
|
66
|
+
<link rel='alternate' type='text/html' href='http://www.google.com/analytics'/>
|
67
|
+
<dxp:property name='ga:accountId' value='4277553'/>
|
68
|
+
<dxp:property name='ga:accountName' value='www.pdma.org'/>
|
69
|
+
<dxp:property name='ga:profileId' value='8575980'/>
|
70
|
+
<dxp:property name='ga:webPropertyId' value='UA-4277553-1'/>
|
71
|
+
<dxp:property name='ga:currency' value='USD'/>
|
72
|
+
<dxp:property name='ga:timezone' value='America/Los_Angeles'/>
|
73
|
+
<dxp:tableId>ga:8575980</dxp:tableId>
|
74
|
+
</entry>
|
75
|
+
<entry gd:etag='W/"CU4CSXo_cCp7I2A9Wx9RGU0."' gd:kind='analytics#account'>
|
76
|
+
<id>http://www.google.com/analytics/feeds/accounts/ga:25620226</id>
|
77
|
+
<updated>2010-12-20T19:59:28.448-08:00</updated>
|
78
|
+
<title>business.com</title>
|
79
|
+
<link rel='alternate' type='text/html' href='http://www.google.com/analytics'/>
|
80
|
+
<dxp:property name='ga:accountId' value='12312214'/>
|
81
|
+
<dxp:property name='ga:accountName' value='business.com'/>
|
82
|
+
<dxp:property name='ga:profileId' value='25620226'/>
|
83
|
+
<dxp:property name='ga:webPropertyId' value='UA-12312214-1'/>
|
84
|
+
<dxp:property name='ga:currency' value='USD'/>
|
85
|
+
<dxp:property name='ga:timezone' value='America/Los_Angeles'/>
|
86
|
+
<dxp:tableId>ga:25620226</dxp:tableId>
|
87
|
+
</entry>
|
88
|
+
<entry gd:etag='W/"CU4CSX0yfCp7I2A9Wx9RGU0."' gd:kind='analytics#account'>
|
89
|
+
<id>http://www.google.com/analytics/feeds/accounts/ga:12123131</id>
|
90
|
+
<updated>2010-12-20T19:59:28.394-08:00</updated>
|
91
|
+
<title>blog.com</title>
|
92
|
+
<link rel='alternate' type='text/html' href='http://www.google.com/analytics'/>
|
93
|
+
<dxp:property name='ga:accountId' value='12312214'/>
|
94
|
+
<dxp:property name='ga:accountName' value='business.com'/>
|
95
|
+
<dxp:property name='ga:profileId' value='12123131'/>
|
96
|
+
<dxp:property name='ga:webPropertyId' value='UA-12345678-1'/>
|
97
|
+
<dxp:property name='ga:currency' value='USD'/>
|
98
|
+
<dxp:property name='ga:timezone' value='America/Los_Angeles'/>
|
99
|
+
<dxp:tableId>ga:12123131</dxp:tableId>
|
100
|
+
</entry>
|
101
|
+
<entry gd:etag='W/"DUMNQHk_fSp7I2A9Wx5bEE4."' gd:kind='analytics#account'>
|
102
|
+
<id>http://www.google.com/analytics/feeds/accounts/ga:37685582</id>
|
103
|
+
<updated>2010-10-25T13:11:31.745-07:00</updated>
|
104
|
+
<title>The Social</title>
|
105
|
+
<link rel='alternate' type='text/html' href='http://www.google.com/analytics'/>
|
106
|
+
<dxp:property name='ga:accountId' value='12312214'/>
|
107
|
+
<dxp:property name='ga:accountName' value='business.com'/>
|
108
|
+
<dxp:property name='ga:profileId' value='37685582'/>
|
109
|
+
<dxp:property name='ga:webPropertyId' value='UA-12312214-1'/>
|
110
|
+
<dxp:property name='ga:currency' value='USD'/>
|
111
|
+
<dxp:property name='ga:timezone' value='America/Los_Angeles'/>
|
112
|
+
<dxp:tableId>ga:37685582</dxp:tableId>
|
113
|
+
</entry>
|
114
|
+
<entry gd:etag='W/"DE8HR3o4eCp7I2A9Wx5UF0w."' gd:kind='analytics#account'>
|
115
|
+
<id>http://www.google.com/analytics/feeds/accounts/ga:38132423</id>
|
116
|
+
<updated>2010-10-21T20:07:16.430-07:00</updated>
|
117
|
+
<title>Skyline</title>
|
118
|
+
<link rel='alternate' type='text/html' href='http://www.google.com/analytics'/>
|
119
|
+
<dxp:property name='ga:accountId' value='12312214'/>
|
120
|
+
<dxp:property name='ga:accountName' value='business.com'/>
|
121
|
+
<dxp:property name='ga:profileId' value='38132423'/>
|
122
|
+
<dxp:property name='ga:webPropertyId' value='UA-12312214-1'/>
|
123
|
+
<dxp:property name='ga:currency' value='USD'/>
|
124
|
+
<dxp:property name='ga:timezone' value='America/Los_Angeles'/>
|
125
|
+
<dxp:tableId>ga:38132423</dxp:tableId>
|
126
|
+
</entry>
|
127
|
+
</feed>
|
data/spec/happymapper_spec.rb
CHANGED
@@ -12,6 +12,41 @@ module Analytics
|
|
12
12
|
attribute :value, String
|
13
13
|
end
|
14
14
|
|
15
|
+
class Goal
|
16
|
+
include HappyMapper
|
17
|
+
|
18
|
+
# Google Analytics does a dirtry trick where a user with no goals
|
19
|
+
# returns a profile without any goals data or the declared namespace
|
20
|
+
# which means Nokogiri does not pick up the namespace automatically.
|
21
|
+
# To fix this, we manually register the namespace to avoid bad XPath
|
22
|
+
# expression. Dirty, but works.
|
23
|
+
|
24
|
+
register_namespace 'ga', 'http://schemas.google.com/ga/2009'
|
25
|
+
namespace 'ga'
|
26
|
+
|
27
|
+
tag 'goal'
|
28
|
+
attribute :active, Boolean
|
29
|
+
attribute :name, String
|
30
|
+
attribute :number, Integer
|
31
|
+
attribute :value, Float
|
32
|
+
|
33
|
+
def clean_name
|
34
|
+
name.gsub(/ga:/, '')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Profile
|
39
|
+
include HappyMapper
|
40
|
+
|
41
|
+
tag 'entry'
|
42
|
+
element :title, String
|
43
|
+
element :tableId, String, :namespace => 'dxp'
|
44
|
+
|
45
|
+
has_many :properties, Property
|
46
|
+
has_many :goals, Goal
|
47
|
+
end
|
48
|
+
|
49
|
+
|
15
50
|
class Entry
|
16
51
|
include HappyMapper
|
17
52
|
|
@@ -687,6 +722,16 @@ describe HappyMapper do
|
|
687
722
|
property.value.should == '85301'
|
688
723
|
end
|
689
724
|
|
725
|
+
it "should be able to parse google analytics profile xml with manually declared namespace" do
|
726
|
+
data = Analytics::Profile.parse(fixture_file('analytics_profile.xml'))
|
727
|
+
data.entries.size.should == 6
|
728
|
+
|
729
|
+
entry = data.entries[0]
|
730
|
+
entry.title.should == 'www.homedepot.com'
|
731
|
+
entry.properties.size.should == 6
|
732
|
+
entry.goals.size.should == 0
|
733
|
+
end
|
734
|
+
|
690
735
|
it "should allow instantiating with a string" do
|
691
736
|
module StringFoo
|
692
737
|
class Bar
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 0.3.
|
8
|
+
- 6
|
9
|
+
version: 0.3.6
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Damien Le Berrigaud
|
@@ -18,7 +18,7 @@ autorequire:
|
|
18
18
|
bindir: bin
|
19
19
|
cert_chain: []
|
20
20
|
|
21
|
-
date: 2010-12-
|
21
|
+
date: 2010-12-23 00:00:00 +01:00
|
22
22
|
default_executable:
|
23
23
|
dependencies:
|
24
24
|
- !ruby/object:Gem::Dependency
|
@@ -32,8 +32,8 @@ dependencies:
|
|
32
32
|
segments:
|
33
33
|
- 1
|
34
34
|
- 4
|
35
|
-
-
|
36
|
-
version: 1.4.
|
35
|
+
- 2
|
36
|
+
version: 1.4.2
|
37
37
|
type: :runtime
|
38
38
|
version_requirements: *id001
|
39
39
|
- !ruby/object:Gem::Dependency
|
@@ -46,9 +46,9 @@ dependencies:
|
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
segments:
|
48
48
|
- 1
|
49
|
-
-
|
50
|
-
-
|
51
|
-
version: 1.
|
49
|
+
- 3
|
50
|
+
- 0
|
51
|
+
version: 1.3.0
|
52
52
|
type: :development
|
53
53
|
version_requirements: *id002
|
54
54
|
description: Object to XML Mapping Library, using Nokogiri (fork from John Nunemaker's Happymapper)
|
@@ -71,6 +71,7 @@ files:
|
|
71
71
|
- spec/fixtures/address.xml
|
72
72
|
- spec/fixtures/ambigous_items.xml
|
73
73
|
- spec/fixtures/analytics.xml
|
74
|
+
- spec/fixtures/analytics_profile.xml
|
74
75
|
- spec/fixtures/commit.xml
|
75
76
|
- spec/fixtures/current_weather.xml
|
76
77
|
- spec/fixtures/dictionary.xml
|
@@ -129,6 +130,7 @@ test_files:
|
|
129
130
|
- spec/fixtures/address.xml
|
130
131
|
- spec/fixtures/ambigous_items.xml
|
131
132
|
- spec/fixtures/analytics.xml
|
133
|
+
- spec/fixtures/analytics_profile.xml
|
132
134
|
- spec/fixtures/commit.xml
|
133
135
|
- spec/fixtures/current_weather.xml
|
134
136
|
- spec/fixtures/dictionary.xml
|