diff --git a/radicale/__init__.py b/radicale/__init__.py index 42f32f5..641fba5 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -94,15 +94,16 @@ def _log_request_content(request, function): content_length = int(request.headers.get("Content-Length", 0)) if content_length: request._content = request.rfile.read(content_length) + log.LOGGER.debug( + "Request headers:\n%s" % "\n".join( + ": ".join((key, value)) + for key, value in request.headers.items())) log.LOGGER.debug("Request content:\n%s" % request._content) else: request._content = None function(request) - log.LOGGER.debug( - "Response headers:\n%s" % "\n".join( - ": ".join((key, value)) for key, value in request.headers.items())) if getattr(request, "_answer"): log.LOGGER.debug( "Response content:\n%s" % request._answer) diff --git a/radicale/ical.py b/radicale/ical.py index 25a1b44..fcfbdaf 100644 --- a/radicale/ical.py +++ b/radicale/ical.py @@ -64,8 +64,8 @@ class Item(object): # An item must have a name, determined in order by: # # - the ``name`` parameter - # - the ``X-RADICALE-NAME`` iCal property (for Events and Todos) - # - the ``UID`` iCal property (for Events and Todos) + # - the ``X-RADICALE-NAME`` iCal property (for Events, Todos, Journals) + # - the ``UID`` iCal property (for Events, Todos, Journals) # - the ``TZID`` iCal property (for Timezones) if not self._name: for line in self.text.splitlines(): @@ -124,6 +124,11 @@ class Todo(Item): # pylint: enable=W0511 +class Journal(Item): + """Internal journal class.""" + tag = "VJOURNAL" + + class Timezone(Item): """Internal timezone class.""" tag = "VTIMEZONE" @@ -190,7 +195,8 @@ class Calendar(object): """ items = self.items - for new_item in self._parse(text, (Timezone, Event, Todo), name): + for new_item in self._parse( + text, (Timezone, Event, Todo, Journal), name): if new_item.name not in (item.name for item in items): items.append(new_item) @@ -198,10 +204,11 @@ class Calendar(object): def remove(self, name): """Remove object named ``name`` from calendar.""" - todos = [todo for todo in self.todos if todo.name != name] - events = [event for event in self.events if event.name != name] + components = [ + component for component in self.components + if component.name != name] - items = self.timezones + todos + events + items = self.timezones + components self.write(items=items) def replace(self, name, text): @@ -259,7 +266,12 @@ class Calendar(object): @property def items(self): """Get list of all items in calendar.""" - return self._parse(self.text, (Event, Todo, Timezone)) + return self._parse(self.text, (Event, Todo, Journal, Timezone)) + + @property + def components(self): + """Get list of all components in calendar.""" + return self._parse(self.text, (Event, Todo, Journal)) @property def events(self): @@ -271,6 +283,11 @@ class Calendar(object): """Get list of ``Todo`` items in calendar.""" return self._parse(self.text, (Todo,)) + @property + def journals(self): + """Get list of ``Journal`` items in calendar.""" + return self._parse(self.text, (Journal,)) + @property def timezones(self): """Get list of ``Timezome`` items in calendar.""" diff --git a/radicale/xmlutils.py b/radicale/xmlutils.py index ed73c17..08fe199 100644 --- a/radicale/xmlutils.py +++ b/radicale/xmlutils.py @@ -101,7 +101,7 @@ def propfind(path, xml_request, calendar, depth): else: # depth is 1, infinity or not specified # we limit ourselves to depth == 1 - items = [calendar] + calendar.events + calendar.todos + items = [calendar] + calendar.components else: items = [] @@ -152,12 +152,10 @@ def propfind(path, xml_request, calendar, depth): tag.text = path element.append(tag) elif tag == _tag("C", "supported-calendar-component-set"): - comp = ET.Element(_tag("C", "comp")) - comp.set("name", "VTODO") # pylint: disable=W0511 - element.append(comp) - comp = ET.Element(_tag("C", "comp")) - comp.set("name", "VEVENT") - element.append(comp) + for component in ("VTODO", "VEVENT", "VJOURNAL"): + comp = ET.Element(_tag("C", "comp")) + comp.set("name", component) + element.append(comp) elif tag == _tag("D", "current-user-privilege-set"): privilege = ET.Element(_tag("D", "privilege")) privilege.append(ET.Element(_tag("D", "all"))) @@ -227,7 +225,8 @@ def report(path, xml_request, calendar): else: # Reference is a calendar path = hreference - items = calendar.events + calendar.todos + items = calendar.components + print(calendar.components) for item in items: response = ET.Element(_tag("D", "response")) @@ -248,7 +247,7 @@ def report(path, xml_request, calendar): if tag == _tag("D", "getetag"): element.text = item.etag elif tag == _tag("C", "calendar-data"): - if isinstance(item, (ical.Event, ical.Todo)): + if isinstance(item, (ical.Event, ical.Todo, ical.Journal)): element.text = ical.serialize( calendar.headers, calendar.timezones + [item]) prop.append(element)