googlecontacts 0.1.5 → 0.1.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/VERSION +1 -1
- data/lib/google_contacts/base.rb +44 -23
- data/lib/google_contacts/contact.rb +4 -15
- data/lib/google_contacts/group.rb +5 -7
- data/spec/assets/groups_full.xml +1 -0
- data/spec/contact_spec.rb +23 -23
- data/spec/group_spec.rb +8 -4
- metadata +3 -5
- data/README.md +0 -52
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.6
|
data/lib/google_contacts/base.rb
CHANGED
@@ -22,6 +22,7 @@ module GoogleContacts
|
|
22
22
|
end
|
23
23
|
|
24
24
|
@proxies = HashWithIndifferentAccess.new
|
25
|
+
register_base_proxies
|
25
26
|
end
|
26
27
|
|
27
28
|
def attributes=(attrs)
|
@@ -29,19 +30,19 @@ module GoogleContacts
|
|
29
30
|
send("#{key}=", value)
|
30
31
|
end
|
31
32
|
end
|
32
|
-
|
33
|
+
|
33
34
|
def insert_xml(tag, attributes = {}, &blk)
|
34
35
|
self.class.insert_xml(@xml, tag, attributes, &blk)
|
35
36
|
end
|
36
|
-
|
37
|
+
|
37
38
|
def remove_xml(tag)
|
38
39
|
@xml.xpath(tag).remove
|
39
40
|
end
|
40
|
-
|
41
|
+
|
41
42
|
def self.feed_for_batch
|
42
43
|
new_xml_document('feed').root
|
43
44
|
end
|
44
|
-
|
45
|
+
|
45
46
|
# Create new XML::Document that can be used in a
|
46
47
|
# Google Contacts batch operation.
|
47
48
|
def entry_for_batch(operation)
|
@@ -52,54 +53,74 @@ module GoogleContacts
|
|
52
53
|
if operation == :update || operation == :delete
|
53
54
|
root.at('./xmlns:id').content = url(:edit)
|
54
55
|
end
|
55
|
-
|
56
|
+
|
56
57
|
self.class.insert_xml(root, 'batch:id')
|
57
58
|
self.class.insert_xml(root, 'batch:operation', :type => operation)
|
58
|
-
|
59
|
+
|
59
60
|
root
|
60
61
|
end
|
61
|
-
|
62
|
+
|
62
63
|
def new?
|
63
64
|
xml.at_xpath('./xmlns:id').nil?
|
64
65
|
end
|
65
|
-
|
66
|
-
def
|
66
|
+
|
67
|
+
def href
|
67
68
|
xml.at_xpath('./xmlns:id').text.strip unless new?
|
68
69
|
end
|
69
|
-
|
70
|
+
|
70
71
|
def updated_at
|
71
72
|
Time.parse xml.at_xpath('./xmlns:updated').text.strip unless new?
|
72
73
|
end
|
73
|
-
|
74
|
+
|
74
75
|
def url(rel)
|
75
76
|
rel = 'http://schemas.google.com/contacts/2008/rel#photo' if rel == :photo
|
76
77
|
xml.at_xpath(%{xmlns:link[@rel="#{rel}"]})[:href]
|
77
78
|
end
|
78
|
-
|
79
|
+
|
79
80
|
def changed?
|
80
81
|
@proxies.values.any?(&:changed?)
|
81
82
|
end
|
82
|
-
|
83
|
+
|
83
84
|
def save
|
84
85
|
return unless changed?
|
85
86
|
synchronize_proxies
|
86
87
|
@wrapper.append_operation(self, new? ? :insert : :update)
|
87
88
|
end
|
88
|
-
|
89
|
+
|
89
90
|
def delete
|
90
91
|
return if new?
|
91
92
|
@wrapper.append_operation(self, :delete)
|
92
93
|
end
|
93
|
-
|
94
|
+
|
95
|
+
# Hash-like access to extended properties of both contacts and groups.
|
96
|
+
def [](prop)
|
97
|
+
properties[prop]
|
98
|
+
end
|
99
|
+
|
100
|
+
def []=(prop, value)
|
101
|
+
properties[prop] = value
|
102
|
+
end
|
103
|
+
|
104
|
+
# Alias the xmlns:title tag be be accessible using #name(=)?
|
105
|
+
alias_attribute :name, :title
|
106
|
+
|
94
107
|
protected
|
95
108
|
def register_proxy(name, proxy)
|
96
109
|
@proxies[name.to_sym] = proxy
|
97
110
|
end
|
98
|
-
|
111
|
+
|
99
112
|
def synchronize_proxies
|
100
113
|
@proxies.values.map(&:synchronize)
|
101
114
|
end
|
102
|
-
|
115
|
+
|
116
|
+
def register_base_proxies
|
117
|
+
register_proxy :title, Proxies::Tag.new(self, :tag => 'xmlns:title')
|
118
|
+
register_proxy :properties, Proxies::Hash.new(self,
|
119
|
+
:tag => 'gd:extendedProperty',
|
120
|
+
:key => 'name',
|
121
|
+
:value => 'value')
|
122
|
+
end
|
123
|
+
|
103
124
|
# Try to proxy missing method to one of the proxies
|
104
125
|
def method_missing(sym, *args, &blk)
|
105
126
|
if sym.to_s =~ /^(\w+)(=)?$/ && @proxies[$1]
|
@@ -112,13 +133,13 @@ module GoogleContacts
|
|
112
133
|
super
|
113
134
|
end
|
114
135
|
end
|
115
|
-
|
136
|
+
|
116
137
|
def self.namespace(node, prefix)
|
117
138
|
node.namespace_definitions.find do |ns|
|
118
139
|
ns.prefix == prefix
|
119
140
|
end
|
120
141
|
end
|
121
|
-
|
142
|
+
|
122
143
|
def self.insert_xml(parent, tag, attributes = {}, &blk)
|
123
144
|
# Construct new node with the right namespace
|
124
145
|
matches = tag.match /^((\w+):)?(\w+)$/
|
@@ -130,12 +151,12 @@ module GoogleContacts
|
|
130
151
|
attributes.each_pair do |k,v|
|
131
152
|
node[k.to_s] = v.to_s
|
132
153
|
end
|
133
|
-
|
154
|
+
|
134
155
|
parent << node
|
135
156
|
yield node if block_given?
|
136
157
|
node
|
137
158
|
end
|
138
|
-
|
159
|
+
|
139
160
|
def self.new_xml_document(root)
|
140
161
|
doc = Nokogiri::XML::Document.new
|
141
162
|
if root.is_a?(Nokogiri::XML::Element)
|
@@ -146,7 +167,7 @@ module GoogleContacts
|
|
146
167
|
decorate_document_with_namespaces(doc)
|
147
168
|
doc
|
148
169
|
end
|
149
|
-
|
170
|
+
|
150
171
|
def self.initialize_xml_document
|
151
172
|
doc = new_xml_document('entry')
|
152
173
|
insert_xml(doc.root, 'atom:category', {
|
@@ -155,7 +176,7 @@ module GoogleContacts
|
|
155
176
|
})
|
156
177
|
doc
|
157
178
|
end
|
158
|
-
|
179
|
+
|
159
180
|
def self.decorate_document_with_namespaces(doc)
|
160
181
|
doc.root.default_namespace = NAMESPACES['atom']
|
161
182
|
NAMESPACES.each_pair do |prefix, href|
|
@@ -5,33 +5,22 @@ module GoogleContacts
|
|
5
5
|
alias_attribute :name, :title
|
6
6
|
def initialize(*args)
|
7
7
|
super
|
8
|
-
|
9
|
-
register_proxy :title, Proxies::Tag.new(self, :tag => 'xmlns:title')
|
10
8
|
register_proxy :emails, Proxies::Emails.new(self)
|
11
9
|
register_proxy :groups, Proxies::Array.new(self,
|
12
10
|
:tag => 'gContact:groupMembershipInfo',
|
13
11
|
:attr => 'href')
|
14
|
-
register_proxy :properties, Proxies::Hash.new(self,
|
15
|
-
:tag => 'gd:extendedProperty',
|
16
|
-
:key => 'name',
|
17
|
-
:value => 'value')
|
18
|
-
end
|
19
|
-
|
20
|
-
def [](prop)
|
21
|
-
properties[prop]
|
22
12
|
end
|
23
13
|
|
24
|
-
def []=(prop, value)
|
25
|
-
properties[prop] = value
|
26
|
-
end
|
27
|
-
|
28
14
|
def email
|
29
15
|
emails.primary.try(:address)
|
30
16
|
end
|
31
|
-
|
17
|
+
|
32
18
|
def email=(address)
|
33
19
|
emails[address].primary!
|
34
20
|
end
|
35
21
|
|
22
|
+
def inspect
|
23
|
+
"\#<GoogleContacts::Contact name=#{name.inspect} email=#{email.inspect}>"
|
24
|
+
end
|
36
25
|
end # class Contact
|
37
26
|
end # module GoogleContacts
|
@@ -1,15 +1,13 @@
|
|
1
1
|
module GoogleContacts
|
2
2
|
class Group < Base
|
3
3
|
CATEGORY_TERM = 'http://schemas.google.com/g/2005#group'
|
4
|
-
|
5
|
-
alias_attribute :name, :title
|
6
|
-
def initialize(*args)
|
7
|
-
super
|
8
|
-
register_proxy :title, Proxies::Tag.new(self, :tag => 'xmlns:title')
|
9
|
-
end
|
10
4
|
|
11
5
|
def system_group?
|
12
|
-
@xml.xpath('
|
6
|
+
@xml.xpath('./gContact:systemGroup').size > 0
|
7
|
+
end
|
8
|
+
|
9
|
+
def inspect
|
10
|
+
"\#<GoogleContacts::Group name=#{name.inspect} system_group=#{system_group?.inspect}>"
|
13
11
|
end
|
14
12
|
end
|
15
13
|
end
|
data/spec/assets/groups_full.xml
CHANGED
@@ -42,6 +42,7 @@
|
|
42
42
|
<link rel='self' type='application/atom+xml'
|
43
43
|
href='http://www.google.com/m8/feeds/groups/jo%40gmail.com/thin/6' />
|
44
44
|
<gContact:systemGroup id='Contacts' />
|
45
|
+
<gd:extendedProperty name='foo' value='bar' />
|
45
46
|
</entry>
|
46
47
|
<entry gd:etag='"Rn05fDVSLyp7ImA9WxRbGEUORQM."'>
|
47
48
|
<id>http://www.google.com/m8/feeds/groups/jo%40gmail.com/base/68f415478ba1aa69</id>
|
data/spec/contact_spec.rb
CHANGED
@@ -8,8 +8,8 @@ describe GoogleContacts::Contact do
|
|
8
8
|
@contact = @contacts.first
|
9
9
|
end
|
10
10
|
|
11
|
-
it "should know its
|
12
|
-
@contact.
|
11
|
+
it "should know its href" do
|
12
|
+
@contact.href.should == 'http://www.google.com/m8/feeds/contacts/liz%40gmail.com/base/c9012de'
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should know when it was updated" do
|
@@ -20,15 +20,15 @@ describe GoogleContacts::Contact do
|
|
20
20
|
@contact.groups.should have(1).group
|
21
21
|
@contact.groups[0].should == 'http://www.google.com/m8/feeds/groups/liz%40gmail.com/base/270f'
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
it "should initialize extended properties" do
|
25
25
|
@contact[:pet].should == 'hamster'
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
it "should initialize the title tag" do
|
29
29
|
@contact.title.should == 'Fitzwilliam Darcy'
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
it "should not be changed? initially" do
|
33
33
|
@contact.changed?.should be_false
|
34
34
|
end
|
@@ -46,7 +46,7 @@ describe GoogleContacts::Contact do
|
|
46
46
|
@contact.url(:photo).should == 'http://www.google.com/m8/feeds/photos/media/liz%40gmail.com/c9012de'
|
47
47
|
end
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
describe "updating" do
|
51
51
|
it "should update the title-tag" do
|
52
52
|
@contact.xml.at('./atom:title').content.should == 'Fitzwilliam Darcy'
|
@@ -56,54 +56,54 @@ describe GoogleContacts::Contact do
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
describe "from scratch" do
|
61
61
|
before(:each) do
|
62
62
|
@contact = GoogleContacts::Contact.new(wrapper)
|
63
63
|
@root = @contact.xml.document.root
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
it "should create a new xml root node" do
|
67
67
|
@root.name.should == 'entry'
|
68
68
|
@root.namespace.href.should == 'http://www.w3.org/2005/Atom'
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
it "should set the right category term" do
|
72
72
|
@root.at_xpath('./atom:category')['term'].should == 'http://schemas.google.com/contact/2008#contact'
|
73
73
|
end
|
74
|
-
|
75
|
-
it "should not have an
|
76
|
-
@contact.
|
74
|
+
|
75
|
+
it "should not have an href" do
|
76
|
+
@contact.href.should be_nil
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
it "should not have an updated entry" do
|
80
80
|
@contact.updated_at.should be_nil
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
it "should be new" do
|
84
84
|
@contact.new?.should be_true
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
87
|
it "should not be changed" do
|
88
88
|
@contact.changed?.should be_false
|
89
89
|
end
|
90
|
-
|
90
|
+
|
91
91
|
it "should have no groups" do
|
92
92
|
@contact.groups.should be_empty
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
it "should be possible to set the default email address" do
|
96
96
|
@contact.email = 'foo@bar.com'
|
97
97
|
@contact.emails['foo@bar.com'].should be_primary
|
98
98
|
@contact.emails.size.should == 1
|
99
99
|
end
|
100
|
-
|
100
|
+
|
101
101
|
it "should provide access to the contact's primary email address" do
|
102
102
|
@contact.email.should be_nil
|
103
103
|
@contact.email = 'foo@bar.com'
|
104
104
|
@contact.email.should == 'foo@bar.com'
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
107
|
describe "when updating" do
|
108
108
|
it "should update the title-tag" do
|
109
109
|
@contact.xml.at('./atom:title').should be_nil
|
@@ -113,18 +113,18 @@ describe GoogleContacts::Contact do
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
end
|
116
|
-
|
116
|
+
|
117
117
|
describe "operations" do
|
118
118
|
before(:each) do
|
119
119
|
@contact = GoogleContacts::Contact.new(wrapper)
|
120
120
|
@root = @contact.xml.document.root
|
121
121
|
end
|
122
|
-
|
122
|
+
|
123
123
|
describe "on groups" do
|
124
124
|
before(:each) do
|
125
125
|
@groups = [stub('group1', :href => 'foo'), stub('group2', :href => 'bar')]
|
126
126
|
end
|
127
|
-
|
127
|
+
|
128
128
|
it "should be possible to add an array of groups" do
|
129
129
|
@contact.groups += @groups
|
130
130
|
@contact.groups.should == ['foo', 'bar'].sort
|
@@ -134,7 +134,7 @@ describe GoogleContacts::Contact do
|
|
134
134
|
@contact.groups += ['foo', 'bar']
|
135
135
|
@contact.groups.should == ['foo', 'bar'].sort
|
136
136
|
end
|
137
|
-
|
137
|
+
|
138
138
|
describe "with initial content" do
|
139
139
|
before(:each) do
|
140
140
|
@contact.groups = ['foo', 'bar', 'quux']
|
data/spec/group_spec.rb
CHANGED
@@ -7,16 +7,20 @@ describe GoogleContacts::Group do
|
|
7
7
|
@group = @groups.first
|
8
8
|
end
|
9
9
|
|
10
|
-
it "should know its
|
11
|
-
@group.
|
10
|
+
it "should know its href" do
|
11
|
+
@group.href.should == 'http://www.google.com/m8/feeds/groups/jo%40gmail.com/base/6'
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
it "should initialize the title tag" do
|
15
15
|
@group.title.should == 'System Group: My Contacts'
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
it "should know when it is a system group" do
|
19
19
|
@groups[0].system_group?.should be_true
|
20
20
|
@groups[1].system_group?.should be_false
|
21
21
|
end
|
22
|
+
|
23
|
+
it "should initialize extended properties" do
|
24
|
+
@group[:foo].should == 'bar'
|
25
|
+
end
|
22
26
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 6
|
9
|
+
version: 0.1.6
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Pieter Noordhuis
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-03-
|
17
|
+
date: 2010-03-15 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -109,7 +109,6 @@ extensions: []
|
|
109
109
|
|
110
110
|
extra_rdoc_files:
|
111
111
|
- LICENSE
|
112
|
-
- README.md
|
113
112
|
- README.rdoc
|
114
113
|
files:
|
115
114
|
- .autotest
|
@@ -144,7 +143,6 @@ files:
|
|
144
143
|
- spec/spec.opts
|
145
144
|
- spec/spec_helper.rb
|
146
145
|
- spec/wrapper_spec.rb
|
147
|
-
- README.md
|
148
146
|
has_rdoc: true
|
149
147
|
homepage: http://github.com/pietern/googlecontacts
|
150
148
|
licenses: []
|
data/README.md
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
*foo*
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
gc = GoogleContacts::Wrapper.new
|
7
|
-
|
8
|
-
gc.batch do
|
9
|
-
john = gc.contacts.find_by_email!('john@doe.com')
|
10
|
-
|
11
|
-
# Set this email as primary, overwriting other addresses
|
12
|
-
john.email = 'johnny@walker.com'
|
13
|
-
|
14
|
-
# return primary email address (string)
|
15
|
-
puts john.email
|
16
|
-
|
17
|
-
# Add email to the list
|
18
|
-
john.emails << 'fuckinghipster@hotmail.com'
|
19
|
-
|
20
|
-
john.emails.push('fuckinghipster@hotmail.com', attrs)
|
21
|
-
|
22
|
-
john.emails['fuckinghipster@hotmail.com'] = attrs
|
23
|
-
|
24
|
-
# this removes any existing label
|
25
|
-
john.emails['fuckinghipster@hotmail.com'].rel = 'blaat'
|
26
|
-
|
27
|
-
# this removes any existing rel
|
28
|
-
john.emails['fuckinghipster@hotmail.com'].label = 'personal use'
|
29
|
-
|
30
|
-
# access new email address. this can be used as a factory
|
31
|
-
# method to add new addresses
|
32
|
-
john.emails['thisonedidntexistyet@gmail.com'].primary!
|
33
|
-
|
34
|
-
john.emails.delete('thisonedidntexistyet@gmail.com')
|
35
|
-
|
36
|
-
|
37
|
-
[:rel] = 'foo'
|
38
|
-
|
39
|
-
# Set the last one as primary
|
40
|
-
john.emails.primary('fuckinghipster@hotmail.com')
|
41
|
-
end
|
42
|
-
|
43
|
-
|
44
|
-
@wrapper.batch do
|
45
|
-
1000.times do |i|
|
46
|
-
c = @wrapper.contacts.build
|
47
|
-
c.name = "John %03d" % i
|
48
|
-
c.email = "foo%03d@bar.com" % i
|
49
|
-
c.save
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|