Module: Async::Caldav::Handlers::Propfind

Defined in:
lib/async/caldav/handlers/propfind.rb

Class Method Summary collapse

Class Method Details

.call(path:, storage:, user:, headers: {}, body: nil) ⇒ Object



9
10
11
12
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
87
88
89
90
91
92
# File 'lib/async/caldav/handlers/propfind.rb', line 9

def call(path:, storage:, user:, headers: {}, body: nil, **)
  depth = headers['depth'] || '1'
  propname = body&.include?('propname')
  if propname
    build = :build_propname
  else
    build = :build_propfind
  end

  col_path = path.ensure_trailing_slash
  collection = storage.get_collection(col_path.to_s)
  item_data = storage.get_item(path.to_s)

  # Non-existent deep path
  if !collection && !item_data && path.depth > 2
    [404, { 'content-type' => 'text/plain' }, ['Not Found']]
  else
    xml = Protocol::Caldav::Multistatus.new.to_xml do |x|
      if collection
        col = Protocol::Caldav::Collection.new(
          path:        col_path,
          type:        collection[:type],
          displayname: collection[:displayname],
          description: collection[:description],
          color:       collection[:color],
          props:       collection[:props],
        )
        col.send(build, x)

        if depth != '0'
          storage.list_collections(col_path.to_s).each do |child_path, child_data|
            child_p = Protocol::Caldav::Path.new(child_path, storage_class: storage)
            child_col = Protocol::Caldav::Collection.new(
              path:        child_p,
              type:        child_data[:type],
              displayname: child_data[:displayname],
              description: child_data[:description],
              color:       child_data[:color],
              props:       child_data[:props],
            )
            child_col.send(build, x)
          end

          storage.list_items(col_path.to_s).each do |item_path, data|
            item_p = Protocol::Caldav::Path.new(item_path, storage_class: storage)
            item = Protocol::Caldav::Item.new(
              path:         item_p,
              body:         data[:body],
              content_type: data[:content_type],
              etag:         data[:etag],
            )
            item.send(build, x)
          end
        end
      elsif item_data
        item = Protocol::Caldav::Item.new(
          path:         path,
          body:         item_data[:body],
          content_type: item_data[:content_type],
          etag:         item_data[:etag],
        )
        item.send(build, x)
      else
        build_discovery(x, path, user)

        if depth != '0'
          storage.list_collections(col_path.to_s).each do |child_path, child_data|
            child_p = Protocol::Caldav::Path.new(child_path, storage_class: storage)
            child_col = Protocol::Caldav::Collection.new(
              path:        child_p,
              type:        child_data[:type],
              displayname: child_data[:displayname],
              description: child_data[:description],
              color:       child_data[:color],
              props:       child_data[:props],
            )
            child_col.send(build, x)
          end
        end
      end
    end
    [207, Protocol::Caldav::Constants::DAV_HEADERS, [xml]]
  end
end