simple_dav 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/simple_dav.rb +103 -22
- metadata +39 -22
data/lib/simple_dav.rb
CHANGED
@@ -19,16 +19,23 @@ PROFILE:VCARD
|
|
19
19
|
END:VCARD
|
20
20
|
EOF
|
21
21
|
|
22
|
+
GROUPVCF = <<EOF
|
23
|
+
BEGIN:VCARD
|
24
|
+
VERSION:3.0
|
25
|
+
PRODID:-//IDFuze//SimpleDav//EN
|
26
|
+
END:VCARD
|
27
|
+
EOF
|
28
|
+
|
22
29
|
class SimpleDav
|
23
30
|
attr_reader :headers, :uri, :client
|
24
31
|
|
32
|
+
# generate unique id to create resources
|
25
33
|
def gen_uid
|
26
34
|
"#{rand(100000)}-#{Time.now.to_i}-#{rand(100000)}"
|
27
35
|
end
|
28
36
|
|
29
37
|
def initialize(params = {})
|
30
38
|
begin
|
31
|
-
#https://serveur.ag-si.net/SOGo/dav/geraldine/Contacts/personal/
|
32
39
|
url = params[:ssl] ? "https://#{params[:server]}/" : "http://#{params[:server]}/"
|
33
40
|
url += case (@type = params[:type])
|
34
41
|
when "sogo" then "/SOGo/dav/#{params[:user]}/"
|
@@ -52,32 +59,104 @@ class SimpleDav
|
|
52
59
|
end
|
53
60
|
|
54
61
|
class AddressBook < SimpleDav
|
55
|
-
|
56
|
-
#PUT (Create) sends If-None-Match: *
|
57
|
-
|
58
|
-
#PUT (Replace) sends If-Match: <existing etag>
|
59
|
-
|
60
|
-
#DELETE sends If-Match: <existing etag>
|
61
62
|
|
62
63
|
def initialize(abu = "personal", params)
|
63
64
|
@vcard = nil
|
64
65
|
super(params)
|
65
|
-
abu = @type == "sogo" ? "Contacts/#{abu}/" : "#{abu}"
|
66
|
-
@uri.path += abu
|
66
|
+
@abu = @type == "sogo" ? "Contacts/#{abu}/" : "#{abu}"
|
67
|
+
@uri.path += @abu
|
68
|
+
@group = nil
|
69
|
+
end
|
70
|
+
|
71
|
+
# select address book
|
72
|
+
def select=(abu = "personnal")
|
73
|
+
#todo select uid or nil if personnal
|
74
|
+
@uri.path -= @abu
|
75
|
+
@uri.path += (@abu = abu)
|
67
76
|
end
|
68
77
|
|
78
|
+
# list available address books
|
79
|
+
#find all X-ADDRESSBOOKSERVER-KIND
|
80
|
+
def list
|
81
|
+
where("X-ADDRESSBOOKSERVER-KIND", "group")
|
82
|
+
end
|
83
|
+
|
84
|
+
# find addresse resource by uid
|
69
85
|
def self.find(uid)
|
70
86
|
where(:uid => uid)
|
71
87
|
end
|
72
88
|
|
73
|
-
|
74
|
-
|
89
|
+
# create collection : not working actually
|
90
|
+
def create_folder(name, displayname = "", description = "")
|
91
|
+
query = Nokogiri::XML::Builder.new(:encoding => "UTF-8") do |xml|
|
92
|
+
xml.send('D:mkcol', 'xmlns:D' => "DAV:", 'xmlns:C' => "urn:ietf:params:xml:ns:carddav") do
|
93
|
+
xml.send('D:set') do
|
94
|
+
xml.send('D:prop')
|
95
|
+
xml.send('D:resourcetype') do
|
96
|
+
xml.send('D:collection')
|
97
|
+
xml.send('C:addressbook')
|
98
|
+
end
|
99
|
+
end
|
100
|
+
xml.send('D:displayname') do
|
101
|
+
xml << displayname
|
102
|
+
end
|
103
|
+
xml.send('C:addressbook-description', 'xml:lang' => "en") do
|
104
|
+
xml << description
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
headers = {
|
110
|
+
"content-Type" => "text/xml; charset=\"utf-8\"",
|
111
|
+
"Content-Length" => query.to_xml.to_s.size
|
112
|
+
}
|
113
|
+
|
114
|
+
res = @client.request('MKCOL', @uri, nil, query.to_xml.to_s, headers)
|
115
|
+
|
116
|
+
if res.status < 200 or res.status >= 300
|
117
|
+
raise "create failed: #{res.inspect}"
|
118
|
+
else
|
119
|
+
true
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# create address book group
|
124
|
+
def create(name, description = "")
|
125
|
+
uid = "#{gen_uid}"
|
126
|
+
|
127
|
+
@vcard = Vcard.new(GROUPVCF)
|
128
|
+
@vcard.add_attribute("X-ADDRESSBOOKSERVER-KIND", "group")
|
129
|
+
@vcard.add_attribute("rev", Time.now.utc.round.iso8601(2))
|
130
|
+
@vcard.add_attribute("uid", uid)
|
131
|
+
@vcard.add_attribute(:f, name)
|
132
|
+
@vcard.add_attribute(:fn, description)
|
133
|
+
|
134
|
+
headers = {
|
135
|
+
"If-None-Match" => "*",
|
136
|
+
"Content-Type" => "text/vcard",
|
137
|
+
"Content-Length" => @vcard.to_s.size
|
138
|
+
}
|
139
|
+
|
140
|
+
unc = @uri.clone
|
141
|
+
unc.path += "#{uid}.vcf"
|
142
|
+
res = @client.request('PUT', unc, nil, @vcard.to_s, headers)
|
143
|
+
|
144
|
+
if res.status < 200 or res.status >= 300
|
145
|
+
@uid = nil
|
146
|
+
raise "create failed: #{res.inspect}"
|
147
|
+
else
|
148
|
+
@uid = @group = uid
|
149
|
+
end
|
150
|
+
@vcard
|
151
|
+
|
75
152
|
end
|
76
153
|
|
154
|
+
# access to current vcard object
|
77
155
|
def vcard
|
78
156
|
@vcard
|
79
157
|
end
|
80
|
-
|
158
|
+
|
159
|
+
# find where RoR style
|
81
160
|
def where(conditions)
|
82
161
|
query = Nokogiri::XML::Builder.new(:encoding => "UTF-8") do |xml|
|
83
162
|
xml.send('C:addressbook-query', 'xmlns:D' => "DAV:", 'xmlns:C' => "urn:ietf:params:xml:ns:carddav") do
|
@@ -116,12 +195,6 @@ class AddressBook < SimpleDav
|
|
116
195
|
return vcards
|
117
196
|
end
|
118
197
|
|
119
|
-
def update(params)
|
120
|
-
#get card
|
121
|
-
|
122
|
-
#push card with new params
|
123
|
-
end
|
124
|
-
|
125
198
|
def method_missing(meth, *args, &block)
|
126
199
|
if meth.to_s =~ /^find_by_(.+)$/
|
127
200
|
run_find_by_method($1, *args, &block)
|
@@ -143,6 +216,8 @@ class AddressBook < SimpleDav
|
|
143
216
|
|
144
217
|
end
|
145
218
|
|
219
|
+
# attributes : n|email|title|nickname|tel|bday|fn|org|note|uid
|
220
|
+
# todo change for another vcard managment class
|
146
221
|
class Vcard
|
147
222
|
attr_reader :ab
|
148
223
|
|
@@ -152,9 +227,12 @@ class Vcard
|
|
152
227
|
return self
|
153
228
|
end
|
154
229
|
|
155
|
-
def self.
|
156
|
-
|
157
|
-
|
230
|
+
def self.find(uid)
|
231
|
+
|
232
|
+
end
|
233
|
+
|
234
|
+
# create address resource
|
235
|
+
def self.create(params)
|
158
236
|
params.each do |k,v|
|
159
237
|
@vcard.update_attribute(k,v)
|
160
238
|
end
|
@@ -164,9 +242,12 @@ class Vcard
|
|
164
242
|
"Content-Type" => "text/vcard",
|
165
243
|
"Content-Length" => @vcard.to_s.size
|
166
244
|
}
|
167
|
-
uid = "#{ab.gen_uid}.vcf"
|
245
|
+
uid = "#{@ab.gen_uid}.vcf"
|
168
246
|
|
169
247
|
@vcard.update_attribute(:uid, uid)
|
248
|
+
if @vcard.ab && @vcard.ab.group
|
249
|
+
@vcard.add_attribute("X-ADDRESSBOOKSERVER-MEMBER", "urn:uuid:#{@vcard.ab.group}")
|
250
|
+
end
|
170
251
|
|
171
252
|
unc = ab.uri.clone
|
172
253
|
unc.path += uid
|
metadata
CHANGED
@@ -1,45 +1,62 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_dav
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
6
10
|
platform: ruby
|
7
|
-
authors:
|
11
|
+
authors:
|
8
12
|
- Olivier DIRRENBERGER
|
9
13
|
autorequire:
|
10
14
|
bindir: bin
|
11
15
|
cert_chain: []
|
12
|
-
|
16
|
+
|
17
|
+
date: 2012-10-03 00:00:00 +02:00
|
18
|
+
default_executable:
|
13
19
|
dependencies: []
|
14
|
-
|
20
|
+
|
21
|
+
description: Access your sogo dav server from ruby to sync contacts, events and tasks
|
15
22
|
email: od@idfuze.com
|
16
23
|
executables: []
|
24
|
+
|
17
25
|
extensions: []
|
26
|
+
|
18
27
|
extra_rdoc_files: []
|
19
|
-
|
28
|
+
|
29
|
+
files:
|
20
30
|
- lib/simple_dav.rb
|
31
|
+
has_rdoc: true
|
21
32
|
homepage: https://github.com/reivilo/simple_dav
|
22
33
|
licenses: []
|
34
|
+
|
23
35
|
post_install_message:
|
24
36
|
rdoc_options: []
|
25
|
-
|
37
|
+
|
38
|
+
require_paths:
|
26
39
|
- lib
|
27
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
requirements:
|
36
|
-
- -
|
37
|
-
- !ruby/object:Gem::Version
|
38
|
-
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
segments:
|
52
|
+
- 0
|
53
|
+
version: "0"
|
39
54
|
requirements: []
|
55
|
+
|
40
56
|
rubyforge_project:
|
41
|
-
rubygems_version: 1.
|
57
|
+
rubygems_version: 1.3.6
|
42
58
|
signing_key:
|
43
59
|
specification_version: 3
|
44
60
|
summary: Ruby dav client
|
45
61
|
test_files: []
|
62
|
+
|