13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
# File 'lib/async/caldav/handlers/report.rb', line 13
def call(path:, body:, storage:, resource_type: nil, **)
if body&.include?('sync-collection')
return handle_sync_collection(path: path, body: body, storage: storage)
end
col_path = path.ensure_trailing_slash
items = storage.list_items(col_path.to_s)
data_tag = resource_type == :addressbook ? 'cr:address-data' : 'c:calendar-data'
expand_range = parse_expand(body)
filter = begin
if resource_type == :addressbook
Protocol::Caldav::Filter::Parser.parse_addressbook(body)
else
Protocol::Caldav::Filter::Parser.parse_calendar(body)
end
rescue Protocol::Caldav::ParseError
nil
end
hrefs = (body)
if hrefs && !hrefs.empty?
multi = storage.get_multi(hrefs)
items = multi.select { |_, data| data }
end
responses = items.filter_map do |item_path, data|
next unless data
if filter
if resource_type == :addressbook
card = Protocol::Caldav::Vcard::Parser.parse(data[:body])
next unless card && Protocol::Caldav::Filter::Match.addressbook?(filter, card)
else
component = Protocol::Caldav::Ical::Parser.parse(data[:body])
next unless component && Protocol::Caldav::Filter::Match.calendar?(filter, component)
end
end
item_body = data[:body]
if expand_range && resource_type != :addressbook
component = Protocol::Caldav::Ical::Parser.parse(item_body)
if component
item_body = Protocol::Caldav::Ical::Expand.expand(
component,
range_start: expand_range[:start],
range_end: expand_range[:end]
)
end
end
item_p = Protocol::Caldav::Path.new(item_path, storage_class: storage)
item = Protocol::Caldav::Item.new(
path: item_p,
body: item_body,
content_type: data[:content_type],
etag: data[:etag]
)
item.to_report_xml(data_tag: data_tag)
end
xml = Protocol::Caldav::Multistatus.new(responses).to_xml
[207, Protocol::Caldav::Constants::DAV_HEADERS, [xml]]
end
|