googlecontacts 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
|