nokogiri-happymapper 0.3.5 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|