mirror of
https://github.com/Kozea/Radicale.git
synced 2025-06-26 16:45:52 +00:00
processing expand property for REPORT
This commit is contained in:
parent
6ae831a324
commit
ae731290c1
1 changed files with 64 additions and 10 deletions
|
@ -18,11 +18,16 @@
|
||||||
# along with Radicale. If not, see <http://www.gnu.org/licenses/>.
|
# along with Radicale. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
|
import datetime
|
||||||
import posixpath
|
import posixpath
|
||||||
import socket
|
import socket
|
||||||
|
import copy
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
from http import client
|
from http import client
|
||||||
from typing import Callable, Iterable, Iterator, Optional, Sequence, Tuple
|
from typing import (
|
||||||
|
Callable, Iterable, Iterator,
|
||||||
|
Optional, Sequence, Tuple, List,
|
||||||
|
)
|
||||||
from urllib.parse import unquote, urlparse
|
from urllib.parse import unquote, urlparse
|
||||||
|
|
||||||
import radicale.item as radicale_item
|
import radicale.item as radicale_item
|
||||||
|
@ -64,9 +69,8 @@ def xml_report(base_prefix: str, path: str, xml_request: Optional[ET.Element],
|
||||||
logger.warning("Invalid REPORT method %r on %r requested",
|
logger.warning("Invalid REPORT method %r on %r requested",
|
||||||
xmlutils.make_human_tag(root.tag), path)
|
xmlutils.make_human_tag(root.tag), path)
|
||||||
return client.FORBIDDEN, xmlutils.webdav_error("D:supported-report")
|
return client.FORBIDDEN, xmlutils.webdav_error("D:supported-report")
|
||||||
prop_element = root.find(xmlutils.make_clark("D:prop"))
|
|
||||||
props = ([prop.tag for prop in prop_element]
|
props = root.find(xmlutils.make_clark("D:prop")) or []
|
||||||
if prop_element is not None else [])
|
|
||||||
|
|
||||||
hreferences: Iterable[str]
|
hreferences: Iterable[str]
|
||||||
if root.tag in (
|
if root.tag in (
|
||||||
|
@ -138,19 +142,40 @@ def xml_report(base_prefix: str, path: str, xml_request: Optional[ET.Element],
|
||||||
found_props = []
|
found_props = []
|
||||||
not_found_props = []
|
not_found_props = []
|
||||||
|
|
||||||
for tag in props:
|
for prop in props:
|
||||||
element = ET.Element(tag)
|
element = ET.Element(prop.tag)
|
||||||
if tag == xmlutils.make_clark("D:getetag"):
|
if prop.tag == xmlutils.make_clark("D:getetag"):
|
||||||
element.text = item.etag
|
element.text = item.etag
|
||||||
found_props.append(element)
|
found_props.append(element)
|
||||||
elif tag == xmlutils.make_clark("D:getcontenttype"):
|
elif prop.tag == xmlutils.make_clark("D:getcontenttype"):
|
||||||
element.text = xmlutils.get_content_type(item, encoding)
|
element.text = xmlutils.get_content_type(item, encoding)
|
||||||
found_props.append(element)
|
found_props.append(element)
|
||||||
elif tag in (
|
elif prop.tag in (
|
||||||
xmlutils.make_clark("C:calendar-data"),
|
xmlutils.make_clark("C:calendar-data"),
|
||||||
xmlutils.make_clark("CR:address-data")):
|
xmlutils.make_clark("CR:address-data")):
|
||||||
element.text = item.serialize()
|
element.text = item.serialize()
|
||||||
found_props.append(element)
|
|
||||||
|
expand = prop.find(xmlutils.make_clark("C:expand"))
|
||||||
|
if expand is not None:
|
||||||
|
start = expand.get('start')
|
||||||
|
end = expand.get('end')
|
||||||
|
|
||||||
|
if (start is None) or (end is None):
|
||||||
|
return client.FORBIDDEN, \
|
||||||
|
xmlutils.webdav_error("C:expand")
|
||||||
|
|
||||||
|
start = datetime.datetime.strptime(
|
||||||
|
start, '%Y%m%dT%H%M%SZ'
|
||||||
|
).replace(tzinfo=datetime.timezone.utc)
|
||||||
|
end = datetime.datetime.strptime(
|
||||||
|
end, '%Y%m%dT%H%M%SZ'
|
||||||
|
).replace(tzinfo=datetime.timezone.utc)
|
||||||
|
|
||||||
|
expanded_elements = _expand(
|
||||||
|
element, copy.copy(item), start, end)
|
||||||
|
found_props.extend(expanded_elements)
|
||||||
|
else:
|
||||||
|
found_props.append(element)
|
||||||
else:
|
else:
|
||||||
not_found_props.append(element)
|
not_found_props.append(element)
|
||||||
|
|
||||||
|
@ -164,6 +189,35 @@ def xml_report(base_prefix: str, path: str, xml_request: Optional[ET.Element],
|
||||||
return client.MULTI_STATUS, multistatus
|
return client.MULTI_STATUS, multistatus
|
||||||
|
|
||||||
|
|
||||||
|
def _expand(
|
||||||
|
element: ET.Element,
|
||||||
|
item: radicale_item.Item,
|
||||||
|
start: datetime.datetime,
|
||||||
|
end: datetime.datetime,
|
||||||
|
) -> List[ET.Element]:
|
||||||
|
expanded = [element]
|
||||||
|
|
||||||
|
for component in item.vobject_item.components():
|
||||||
|
if component.name != 'VEVENT':
|
||||||
|
continue
|
||||||
|
|
||||||
|
if hasattr(component, "rrule"):
|
||||||
|
rulleset = component.getrruleset()
|
||||||
|
instances = rulleset.between(start, end)
|
||||||
|
|
||||||
|
for instance in instances:
|
||||||
|
try:
|
||||||
|
delattr(item.vobject_item.vevent, 'recurrence-id')
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
item.vobject_item.vevent.add('RECURRENCE-ID').value = instance
|
||||||
|
element.text = item.vobject_item.serialize()
|
||||||
|
expanded.append(element)
|
||||||
|
|
||||||
|
return expanded
|
||||||
|
|
||||||
|
|
||||||
def xml_item_response(base_prefix: str, href: str,
|
def xml_item_response(base_prefix: str, href: str,
|
||||||
found_props: Sequence[ET.Element] = (),
|
found_props: Sequence[ET.Element] = (),
|
||||||
not_found_props: Sequence[ET.Element] = (),
|
not_found_props: Sequence[ET.Element] = (),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue