Class: Async::Caldav::Client::Calendar

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Calendar.



13
14
15
16
17
18
19
20
# File 'lib/async/caldav/client/calendar.rb', line 13

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

Instance Attribute Details

#colorObject (readonly)

Returns the value of attribute color.



11
12
13
# File 'lib/async/caldav/client/calendar.rb', line 11

def color
  @color
end

#ctagObject (readonly)

Returns the value of attribute ctag.



11
12
13
# File 'lib/async/caldav/client/calendar.rb', line 11

def ctag
  @ctag
end

#descriptionObject (readonly)

Returns the value of attribute description.



11
12
13
# File 'lib/async/caldav/client/calendar.rb', line 11

def description
  @description
end

#displaynameObject (readonly)

Returns the value of attribute displayname.



11
12
13
# File 'lib/async/caldav/client/calendar.rb', line 11

def displayname
  @displayname
end

#pathObject (readonly)

Returns the value of attribute path.



11
12
13
# File 'lib/async/caldav/client/calendar.rb', line 11

def path
  @path
end

Instance Method Details

#deleteObject



82
83
84
85
86
87
88
89
90
# File 'lib/async/caldav/client/calendar.rb', line 82

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_event(filename) ⇒ Object



71
72
73
74
75
76
77
78
79
80
# File 'lib/async/caldav/client/calendar.rb', line 71

def delete_event(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

#events(filter: nil) ⇒ Object

Raises:



22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/async/caldav/client/calendar.rb', line 22

def events(filter: nil)
  x = Builder::XmlMarkup.new
  x.instruct! :xml, version: "1.0", encoding: "UTF-8"
  x.tag!("c:calendar-query", "xmlns:d" => "DAV:", "xmlns:c" => "urn:ietf:params:xml:ns:caldav") do
    x.tag!("d:prop") { x.tag!("d:getetag"); x.tag!("c:calendar-data") }
    x << filter if filter
  end
  body = x.target!

  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: 'calendar-data')
end

#get_event(filename) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/async/caldav/client/calendar.rb', line 57

def get_event(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

#propfindObject

Raises:



92
93
94
95
96
# File 'lib/async/caldav/client/calendar.rb', line 92

def propfind
  status, _, body = @client.request('PROPFIND', @path, headers: { 'Depth' => '0' })
  raise Error, "PROPFIND failed: #{status}" unless status == 207
  @client.parse_collection_props(body)
end

#proppatch(displayname: nil, description: nil, color: nil) ⇒ Object

Raises:



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/async/caldav/client/calendar.rb', line 98

def proppatch(displayname: nil, description: nil, color: nil)
  x = Builder::XmlMarkup.new
  x.instruct! :xml, version: "1.0", encoding: "UTF-8"
  x.tag!("d:propertyupdate", "xmlns:d" => "DAV:", "xmlns:c" => "urn:ietf:params:xml:ns:caldav", "xmlns:x" => "http://apple.com/ns/ical/") do
    x.tag!("d:set") do
      x.tag!("d:prop") do
        x.tag!("d:displayname", displayname) if displayname
        x.tag!("c:calendar-description", description) if description
        x.tag!("x:calendar-color", color) if color
      end
    end
  end

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

  @displayname = displayname if displayname
  @description = description if description
  @color = color if color
  self
end

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



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/async/caldav/client/calendar.rb', line 37

def put_event(filename, body, if_match: nil, if_none_match: nil)
  headers = { 'Content-Type' => 'text/calendar' }
  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

#sync(token: nil) ⇒ Object

Raises:



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/async/caldav/client/calendar.rb', line 120

def sync(token: nil)
  x = Builder::XmlMarkup.new
  x.instruct! :xml, version: "1.0", encoding: "UTF-8"
  x.tag!("d:sync-collection", "xmlns:d" => "DAV:") do
    x.tag!("d:prop") { x.tag!("d:getetag") }
    if token
      x.tag!("d:sync-token", token)
    else
      x.tag!("d:sync-token")
    end
  end
  body = x.target!

  status, _, resp_body = @client.request('REPORT', @path, body: body, headers: { 'Content-Type' => 'text/xml' })

  if status == 403
    raise InvalidSyncToken, "Invalid sync token"
  end
  raise Error, "REPORT failed: #{status}" unless status == 207

  new_token = resp_body.match(/<[^>]*sync-token[^>]*>([^<]+)</)[1] rescue nil
  items = @client.parse_sync_items(resp_body)
  [items, new_token]
end