simple_dav 0.0.3 → 0.0.4

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.
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