simple_dav 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/simple_dav.rb +111 -88
  2. metadata +3 -3
data/lib/simple_dav.rb CHANGED
@@ -19,12 +19,7 @@ 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
22
+ GROUPVCF = BASEVCF
28
23
 
29
24
  class SimpleDav
30
25
  attr_reader :headers, :uri, :client
@@ -38,7 +33,7 @@ class SimpleDav
38
33
  begin
39
34
  url = params[:ssl] ? "https://#{params[:server]}/" : "http://#{params[:server]}/"
40
35
  url += case (@type = params[:type])
41
- when "sogo" then "/SOGo/dav/#{params[:user]}/"
36
+ when "sogo" then "SOGo/dav/#{params[:user]}/"
42
37
  else ""
43
38
  end
44
39
  @uri = URI.parse(url)
@@ -59,31 +54,37 @@ class SimpleDav
59
54
  end
60
55
 
61
56
  class AddressBook < SimpleDav
62
-
63
- def initialize(abu = "personal", params)
57
+ attr_reader :group
58
+ def initialize(params)
59
+ abu = "personal"
64
60
  @vcard = nil
65
61
  super(params)
66
62
  @abu = @type == "sogo" ? "Contacts/#{abu}/" : "#{abu}"
67
63
  @uri.path += @abu
68
- @group = nil
64
+ @group = nil #store group uid
65
+ Card.adb = self
69
66
  end
70
67
 
71
68
  # select address book
72
- def select=(abu = "personnal")
69
+ def change_group(abu)
73
70
  #todo select uid or nil if personnal
74
- @uri.path -= @abu
75
- @uri.path += (@abu = abu)
71
+ # old style folders
72
+ #@uri.path -= @abu
73
+ #@uri.path += (@abu = abu)
74
+ # new style v4 group
75
+ groups = Card.where({"X-ADDRESSBOOKSERVER-KIND" => "group", "f" => abu})
76
+ @group = groups && groups.first && groups.first.uid
76
77
  end
77
78
 
78
79
  # list available address books
79
80
  #find all X-ADDRESSBOOKSERVER-KIND
80
81
  def list
81
- where("X-ADDRESSBOOKSERVER-KIND", "group")
82
+ Card.where("X-ADDRESSBOOKSERVER-KIND" => "group")
82
83
  end
83
84
 
84
85
  # find addresse resource by uid
85
86
  def self.find(uid)
86
- where(:uid => uid)
87
+ Card.find(self, uid)
87
88
  end
88
89
 
89
90
  # create collection : not working actually
@@ -124,9 +125,9 @@ class AddressBook < SimpleDav
124
125
  def create(name, description = "")
125
126
  uid = "#{gen_uid}"
126
127
 
127
- @vcard = Vcard.new(GROUPVCF)
128
+ @vcard = Card.new(GROUPVCF)
128
129
  @vcard.add_attribute("X-ADDRESSBOOKSERVER-KIND", "group")
129
- @vcard.add_attribute("rev", Time.now.utc.round.iso8601(2))
130
+ @vcard.add_attribute("rev", Time.now.utc.iso8601(2))
130
131
  @vcard.add_attribute("uid", uid)
131
132
  @vcard.add_attribute(:f, name)
132
133
  @vcard.add_attribute(:fn, description)
@@ -155,60 +156,6 @@ class AddressBook < SimpleDav
155
156
  def vcard
156
157
  @vcard
157
158
  end
158
-
159
- # find where RoR style
160
- def where(conditions)
161
- query = Nokogiri::XML::Builder.new(:encoding => "UTF-8") do |xml|
162
- xml.send('C:addressbook-query', 'xmlns:D' => "DAV:", 'xmlns:C' => "urn:ietf:params:xml:ns:carddav") do
163
- xml.send('D:prop') do
164
- xml.send('D:getetag')
165
- xml.send('C:address-data') do
166
- xml.send('C:prop', 'name' => "UID")
167
- conditions.each do |k,v|
168
- xml.send('C:prop', 'name' => k.to_s.upcase)
169
- end
170
- end
171
- end
172
- xml.send('C:filter') do
173
- conditions.each do |k,v|
174
- xml.send('C:prop-filter', 'name' => k.to_s.upcase) do
175
- xml.send('C:text-match', 'collation' => "i;unicode-casemap", 'match-type' => "equals") do
176
- xml << v
177
- end
178
- end
179
- end
180
- end
181
- end
182
- end
183
- headers = {
184
- "content-Type" => "text/xml; charset=\"utf-8\"",
185
- "depth" => 1
186
- }
187
-
188
- content = @client.request('REPORT', @uri, nil, query.to_xml.to_s, headers)
189
- #puts "#{content.body}"
190
- xml = Nokogiri::XML(content.body)
191
- vcards = []
192
- xml.xpath('//C:address-data').each do |card|
193
- vcards << Vcard.new(self, card.text)
194
- end
195
- return vcards
196
- end
197
-
198
- def method_missing(meth, *args, &block)
199
- if meth.to_s =~ /^find_by_(.+)$/
200
- run_find_by_method($1, *args, &block)
201
- else
202
- super
203
- end
204
- end
205
-
206
- def run_find_by_method(attrs, *args, &block)
207
- attrs = attrs.split('_and_')
208
- attrs_with_args = [attrs, args].transpose
209
- conditions = Hash[attrs_with_args]
210
- where(conditions)
211
- end
212
159
 
213
160
  def debug_dev=(dev)
214
161
  @client.debug_dev = dev
@@ -218,21 +165,22 @@ end
218
165
 
219
166
  # attributes : n|email|title|nickname|tel|bday|fn|org|note|uid
220
167
  # todo change for another vcard managment class
221
- class Vcard
222
- attr_reader :ab
168
+ class Card
169
+ class << self; attr_accessor :adb end
170
+ @adb = nil
223
171
 
224
- def initialize(ab, text = BASEVCF)
172
+ def initialize(text = BASEVCF)
225
173
  @plain = text
226
- @ab = ab
227
174
  return self
228
175
  end
229
176
 
230
177
  def self.find(uid)
231
-
178
+ where(:uid => uid)
232
179
  end
233
180
 
234
181
  # create address resource
235
182
  def self.create(params)
183
+ @vcard = Card.new
236
184
  params.each do |k,v|
237
185
  @vcard.update_attribute(k,v)
238
186
  end
@@ -242,16 +190,16 @@ class Vcard
242
190
  "Content-Type" => "text/vcard",
243
191
  "Content-Length" => @vcard.to_s.size
244
192
  }
245
- uid = "#{@ab.gen_uid}.vcf"
193
+ uid = "#{adb.gen_uid}.vcf"
246
194
 
247
195
  @vcard.update_attribute(:uid, uid)
248
- if @vcard.ab && @vcard.ab.group
249
- @vcard.add_attribute("X-ADDRESSBOOKSERVER-MEMBER", "urn:uuid:#{@vcard.ab.group}")
196
+ if adb && adb.group
197
+ @vcard.add_attribute("X-ADDRESSBOOKSERVER-MEMBER", "urn:uuid:#{adb.group}")
250
198
  end
251
199
 
252
- unc = ab.uri.clone
200
+ unc = adb.uri.clone
253
201
  unc.path += uid
254
- res = @vcard.ab.client.request('PUT', unc, nil, @vcard.to_s, headers)
202
+ res = adb.client.request('PUT', unc, nil, @vcard.to_s, headers)
255
203
 
256
204
  if res.status < 200 or res.status >= 300
257
205
  @uid = nil
@@ -273,9 +221,9 @@ class Vcard
273
221
  }
274
222
  uid = self.uid
275
223
 
276
- unc = ab.uri.clone
224
+ unc = Card.adb.uri.clone
277
225
  unc.path += uid
278
- res = @ab.client.request('PUT', unc, nil, @plain, headers)
226
+ res = Card.adb.client.request('PUT', unc, nil, @plain, headers)
279
227
 
280
228
  if res.status < 200 or res.status >= 300
281
229
  @uid = nil
@@ -287,15 +235,15 @@ class Vcard
287
235
  end
288
236
 
289
237
  def delete
290
- if @uid && @ab
238
+ if @uid && Card.adb
291
239
 
292
240
  headers = {
293
241
  #"If-None-Match" => "*",
294
242
  "Content-Type" => "text/xml; charset=\"utf-8\""
295
243
  }
296
- unc = @ab.uri.clone
244
+ unc = adb.uri.clone
297
245
  unc.path += @uid
298
- res = @ab.client.request('DELETE', unc, nil, nil, headers)
246
+ res = adb.client.request('DELETE', unc, nil, nil, headers)
299
247
 
300
248
  if res.status < 200 or res.status >= 300
301
249
  @uid = nil
@@ -309,6 +257,23 @@ class Vcard
309
257
  end
310
258
  end
311
259
 
260
+ def retreive
261
+ path = "#{self.uid}.vcf"
262
+ unc = adb.uri.clone
263
+ unc.path += path
264
+ res = adb.client.request('GET', unc)
265
+
266
+ if res.status < 200 or res.status >= 300
267
+ @uid = nil
268
+ raise "delete failed: #{res.inspect}"
269
+ else
270
+ puts res.body
271
+ @plain = res.body
272
+ @uid = uid
273
+ true
274
+ end
275
+ end
276
+
312
277
  def update_attribute(a, v)
313
278
  @plain.match(/^#{a.to_s.upcase}:(.+)$/) ? @plain.gsub!(/^#{a.to_s.upcase}:(.+)$/, "#{a.to_s.upcase}:#{v}") : add_attribute(a, v)
314
279
  end
@@ -318,8 +283,11 @@ class Vcard
318
283
  end
319
284
 
320
285
  def method_missing(meth, *args, &block)
321
- if meth.to_s =~ /^((n|email|title|nickname|tel|bday|fn|org|note|uid)=?)$/
322
- run_on_field($1, *args, &block)
286
+ case meth.to_s
287
+ when /^((n|email|title|nickname|tel|bday|fn|org|note|uid|X-ADDRESSBOOKSERVER-KIND)=?)$/
288
+ run_on_field($1, *args, &block)
289
+ when /^find_by_(.+)$/
290
+ run_find_by_method($1, *args, &block)
323
291
  else
324
292
  super
325
293
  end
@@ -341,6 +309,61 @@ class Vcard
341
309
  end
342
310
  end
343
311
 
312
+ # find where RoR style
313
+ def self.where(conditions)
314
+ limit = 1
315
+ query = Nokogiri::XML::Builder.new(:encoding => "UTF-8") do |xml|
316
+ xml.send('B:addressbook-query', 'xmlns:B' => "urn:ietf:params:xml:ns:carddav") do
317
+ xml.send('A:prop', 'xmlns:A' => "DAV:",) do
318
+ xml.send('A:getetag')
319
+ xml.send('B:address-data')
320
+
321
+ end
322
+ #xml.send('C:filter', 'test' => "anyof") do
323
+ xml.send('B:filter', 'test' => 'anyof') do
324
+ conditions.each do |k,v|
325
+ xml.send('B:prop-filter', 'test' => 'allof','name' => k.to_s) do
326
+ #xml.send('C:text-match', 'collation' => "i;unicode-casemap", 'match-type' => "contains") do
327
+ xml.send('B:text-match', 'collation' => "i;unicode-casemap", 'match-type' => "contains") do
328
+ xml << v
329
+ end
330
+ end
331
+ end
332
+ end
333
+ if limit
334
+ xml.send('C:limit') do
335
+ xml.send('C:nresults') do
336
+ xml << "#{limit}"
337
+ end
338
+ end
339
+ end
340
+
341
+ end
342
+
343
+ end
344
+ headers = {
345
+ "content-Type" => "text/xml; charset=\"utf-8\"",
346
+ "depth" => 1,
347
+ "Content-Length" => "#{query.to_xml.to_s.size}"
348
+ }
349
+ puts ">>>> #{adb.uri}\n"
350
+ content = adb.client.request('REPORT', adb.uri, nil, query.to_xml.to_s, headers)
351
+ puts "#{content.body}\n\n#{query.to_xml}\n\n"
352
+ xml = Nokogiri::XML(content.body)
353
+ vcards = []
354
+ xml.xpath('//C:address-data').each do |card|
355
+ vcards << Card.new(card.text)
356
+ end
357
+ return vcards
358
+ end
359
+
360
+ def run_find_by_method(attrs, *args, &block)
361
+ attrs = attrs.split('_and_')
362
+ attrs_with_args = [attrs, args].transpose
363
+ conditions = Hash[attrs_with_args]
364
+ where(conditions)
365
+ end
366
+
344
367
  def to_s
345
368
  @plain.to_s
346
369
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 3
9
- version: 0.0.3
8
+ - 4
9
+ version: 0.0.4
10
10
  platform: ruby
11
11
  authors:
12
12
  - Olivier DIRRENBERGER
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2012-10-03 00:00:00 +02:00
17
+ date: 2012-10-05 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency