From d6c0a05771b6d91bf8625235200a78a116ea15a4 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 14 Aug 2024 11:15:30 -0600 Subject: [PATCH] Style fixes for tox linting --- radicale/app/report.py | 18 ++++++++++++------ radicale/config.py | 1 + radicale/item/filter.py | 3 +++ radicale/tests/__init__.py | 2 +- radicale/tests/test_base.py | 16 +++++++++------- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/radicale/app/report.py b/radicale/app/report.py index ef0adc2f..9bca7f45 100644 --- a/radicale/app/report.py +++ b/radicale/app/report.py @@ -23,26 +23,31 @@ import datetime import posixpath import socket import xml.etree.ElementTree as ET -import vobject from http import client from typing import (Any, Callable, Iterable, Iterator, List, Optional, Sequence, Tuple, Union) from urllib.parse import unquote, urlparse +import vobject import vobject.base from vobject.base import ContentLine import radicale.item as radicale_item -from radicale import httputils, pathutils, storage, types, xmlutils, config +from radicale import httputils, pathutils, storage, types, xmlutils from radicale.app.base import Access, ApplicationBase from radicale.item import filter as radicale_filter from radicale.log import logger + def free_busy_report(base_prefix: str, path: str, xml_request: Optional[ET.Element], collection: storage.BaseCollection, encoding: str, unlock_storage_fn: Callable[[], None], max_occurrence: int - ) -> Tuple[int, str]: + ) -> Tuple[int, Union[ET.Element, str]]: + # NOTE: this function returns both an Element and a string because + # free-busy reports are an edge-case on the return type according + # to the spec. + multistatus = ET.Element(xmlutils.make_clark("D:multistatus")) if xml_request is None: return client.MULTI_STATUS, multistatus @@ -54,15 +59,16 @@ def free_busy_report(base_prefix: str, path: str, xml_request: Optional[ET.Eleme return client.FORBIDDEN, xmlutils.webdav_error("D:supported-report") time_range_element = root.find(xmlutils.make_clark("C:time-range")) + assert isinstance(time_range_element, ET.Element) # Build a single filter from the free busy query for retrieval # TODO: filter for VFREEBUSY in additional to VEVENT but # test_filter doesn't support that yet. vevent_cf_element = ET.Element(xmlutils.make_clark("C:comp-filter"), - attrib={'name':'VEVENT'}) + attrib={'name': 'VEVENT'}) vevent_cf_element.append(time_range_element) vcalendar_cf_element = ET.Element(xmlutils.make_clark("C:comp-filter"), - attrib={'name':'VCALENDAR'}) + attrib={'name': 'VCALENDAR'}) vcalendar_cf_element.append(vevent_cf_element) filter_element = ET.Element(xmlutils.make_clark("C:filter")) filter_element.append(vcalendar_cf_element) @@ -525,7 +531,7 @@ class ApplicationPartReport(ApplicationBase): "Bad REPORT request on %r: %s", path, e, exc_info=True) return httputils.BAD_REQUEST headers = {"Content-Type": "text/calendar; charset=%s" % self._encoding} - return status, headers, body + return status, headers, str(body) else: try: status, xml_answer = xml_report( diff --git a/radicale/config.py b/radicale/config.py index 10b36a6e..b6ab138d 100644 --- a/radicale/config.py +++ b/radicale/config.py @@ -301,6 +301,7 @@ DEFAULT_CONFIG_SCHEMA: types.CONFIG_SCHEMA = OrderedDict([ "type": positive_int})])) ]) + def parse_compound_paths(*compound_paths: Optional[str] ) -> List[Tuple[str, bool]]: """Parse a compound path and return the individual paths. diff --git a/radicale/item/filter.py b/radicale/item/filter.py index af3b0d19..ef6db2f5 100644 --- a/radicale/item/filter.py +++ b/radicale/item/filter.py @@ -70,10 +70,12 @@ def parse_time_range(time_filter: ET.Element) -> Tuple[datetime, datetime]: end = DATETIME_MAX return start, end + def time_range_timestamps(time_filter: ET.Element) -> Tuple[int, int]: start, end = parse_time_range(time_filter) return (math.floor(start.timestamp()), math.ceil(end.timestamp())) + def comp_match(item: "item.Item", filter_: ET.Element, level: int = 0) -> bool: """Check whether the ``item`` matches the comp ``filter_``. @@ -202,6 +204,7 @@ def time_range_fill(vobject_item: vobject.base.Component, start, end = parse_time_range(filter_) ranges: List[Tuple[datetime, datetime]] = [] + def range_fn(range_start: datetime, range_end: datetime, is_recurrence: bool) -> bool: nonlocal ranges diff --git a/radicale/tests/__init__.py b/radicale/tests/__init__.py index 616f62e1..f335fd3b 100644 --- a/radicale/tests/__init__.py +++ b/radicale/tests/__init__.py @@ -27,11 +27,11 @@ import sys import tempfile import wsgiref.util import xml.etree.ElementTree as ET -import vobject from io import BytesIO from typing import Any, Dict, List, Optional, Tuple, Union import defusedxml.ElementTree as DefusedET +import vobject import radicale from radicale import app, config, types, xmlutils diff --git a/radicale/tests/test_base.py b/radicale/tests/test_base.py index 479893f6..b7edb586 100644 --- a/radicale/tests/test_base.py +++ b/radicale/tests/test_base.py @@ -22,10 +22,10 @@ Radicale tests with simple requests. import os import posixpath -import vobject from typing import Any, Callable, ClassVar, Iterable, List, Optional, Tuple import defusedxml.ElementTree as DefusedET +import vobject from radicale import storage, xmlutils from radicale.tests import RESPONSES, BaseTest @@ -1369,7 +1369,7 @@ permissions: RrWw""") """Test free busy report on a few items""" calendar_path = "/calendar.ics/" self.mkcalendar(calendar_path) - for i in (1,2,10): + for i in (1, 2, 10): filename = "event{}.ics".format(i) event = get_file_content(filename) self.put(posixpath.join(calendar_path, filename), event) @@ -1377,18 +1377,20 @@ permissions: RrWw""") -""", 200, is_xml = False) +""", 200, is_xml=False) for response in responses.values(): assert isinstance(response, vobject.base.Component) assert len(responses) == 1 vcalendar = list(responses.values())[0] + assert isinstance(vcalendar, vobject.base.Component) assert len(vcalendar.vfreebusy_list) == 3 types = {} for vfb in vcalendar.vfreebusy_list: - if vfb.fbtype.value not in types: - types[vfb.fbtype.value] = 0 - types[vfb.fbtype.value] += 1 - assert types == {'BUSY':2, 'FREE':1} + fbtype_val = vfb.fbtype.value + if fbtype_val not in types: + types[fbtype_val] = 0 + types[fbtype_val] += 1 + assert types == {'BUSY': 2, 'FREE': 1} def _report_sync_token( self, calendar_path: str, sync_token: Optional[str] = None