Class: Async::Caldav::Client::Addressbook

Inherits:
Object
  • Object
show all
Defined in:
lib/async/caldav/client/addressbook.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client, path, props = {}) ⇒ Addressbook

Returns a new instance of Addressbook.



12
13
14
15
16
# File 'lib/async/caldav/client/addressbook.rb', line 12

def initialize(client, path, props = {})
  @client = client
  @path = path
  @displayname = props[:displayname]
end

Instance Attribute Details

#displaynameObject (readonly)

Returns the value of attribute displayname.



10
11
12
# File 'lib/async/caldav/client/addressbook.rb', line 10

def displayname
  @displayname
end

#pathObject (readonly)

Returns the value of attribute path.



10
11
12
# File 'lib/async/caldav/client/addressbook.rb', line 10

def path
  @path
end

Instance Method Details

#contacts(filter: nil) ⇒ Object

Raises:



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/async/caldav/client/addressbook.rb', line 18

def contacts(filter: nil)
  body = if filter
    <<~XML
      <?xml version="1.0" encoding="UTF-8"?>
      <cr:addressbook-query xmlns:d="DAV:" xmlns:cr="urn:ietf:params:xml:ns:carddav">
        <d:prop><d:getetag/><cr:address-data/></d:prop>
        #{filter}
      </cr:addressbook-query>
    XML
  else
    <<~XML
      <?xml version="1.0" encoding="UTF-8"?>
      <cr:addressbook-query xmlns:d="DAV:" xmlns:cr="urn:ietf:params:xml:ns:carddav">
        <d:prop><d:getetag/><cr:address-data/></d:prop>
      </cr:addressbook-query>
    XML
  end

  status, _, resp_body = @client.request('REPORT', @path, body: body, headers: { 'Content-Type' => 'text/xml' })
  raise Error, "REPORT failed: #{status}" unless status == 207

  @client.parse_multistatus_items(resp_body, data_tag: 'address-data')
end

#deleteObject



87
88
89
90
91
92
93
94
95
# File 'lib/async/caldav/client/addressbook.rb', line 87

def delete
  status, = @client.request('DELETE', @path)

  case status
  when 204 then true
  when 404 then raise NotFound, "Not found: #{@path}"
  else raise Error, "DELETE failed: #{status}"
  end
end

#delete_contact(filename) ⇒ Object



76
77
78
79
80
81
82
83
84
85
# File 'lib/async/caldav/client/addressbook.rb', line 76

def delete_contact(filename)
  path = "#{@path}#{filename}"
  status, = @client.request('DELETE', path)

  case status
  when 204 then true
  when 404 then raise NotFound, "Not found: #{path}"
  else raise Error, "DELETE failed: #{status}"
  end
end

#get_contact(filename) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/async/caldav/client/addressbook.rb', line 62

def get_contact(filename)
  path = "#{@path}#{filename}"
  status, headers, body = @client.request('GET', path)

  case status
  when 200
    { path: path, body: body, etag: headers['etag'], content_type: headers['content-type'] }
  when 404
    raise NotFound, "Not found: #{path}"
  else
    raise Error, "GET failed: #{status}"
  end
end

#proppatch(displayname: nil) ⇒ Object

Raises:



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/async/caldav/client/addressbook.rb', line 97

def proppatch(displayname: nil)
  props = []
  props << "<d:displayname>#{Protocol::Caldav::Xml.escape(displayname)}</d:displayname>" if displayname

  body = <<~XML
    <?xml version="1.0" encoding="UTF-8"?>
    <d:propertyupdate xmlns:d="DAV:">
      <d:set><d:prop>#{props.join}</d:prop></d:set>
    </d:propertyupdate>
  XML

  status, = @client.request('PROPPATCH', @path, body: body, headers: { 'Content-Type' => 'text/xml' })
  raise Error, "PROPPATCH failed: #{status}" unless status == 207

  @displayname = displayname if displayname
  self
end

#put_contact(filename, body, if_match: nil, if_none_match: nil) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/async/caldav/client/addressbook.rb', line 42

def put_contact(filename, body, if_match: nil, if_none_match: nil)
  headers = { 'Content-Type' => 'text/vcard' }
  headers['If-Match'] = if_match if if_match
  headers['If-None-Match'] = if_none_match if if_none_match

  path = "#{@path}#{filename}"
  status, resp_headers, = @client.request('PUT', path, body: body, headers: headers)

  case status
  when 201, 204
    { path: path, etag: resp_headers['etag'], status: status }
  when 412
    raise PreconditionFailed, "Precondition failed for #{path}"
  when 409
    raise Conflict, "UID conflict for #{path}"
  else
    raise Error, "PUT failed: #{status}"
  end
end