ical.calendar_stream

The core, a collection of Calendar and Scheduling objects.

This is an example of parsing an ics file as a stream of calendar objects:

from pathlib import Path
from ical.calendar_stream import IcsCalendarStream

filename = Path("example/calendar.ics")
with filename.open() as ics_file:
    stream = IcsCalendarStream.from_ics(ics_file.read())
    print("File contains %s calendar(s)", len(stream.calendars))

You can encode a calendar stream as ics content calling the ics() method on the IcsCalendarStream:

from pathlib import Path

filename = Path("/tmp/output.ics")
with filename.open(mode="w") as ics_file:
    ics_file.write(stream.ics())
 1"""The core, a collection of Calendar and Scheduling objects.
 2
 3This is an example of parsing an ics file as a stream of calendar objects:
 4```python
 5from pathlib import Path
 6from ical.calendar_stream import IcsCalendarStream
 7
 8filename = Path("example/calendar.ics")
 9with filename.open() as ics_file:
10    stream = IcsCalendarStream.from_ics(ics_file.read())
11    print("File contains %s calendar(s)", len(stream.calendars))
12```
13
14You can encode a calendar stream as ics content calling the `ics()` method on
15the `IcsCalendarStream`:
16
17```python
18from pathlib import Path
19
20filename = Path("/tmp/output.ics")
21with filename.open(mode="w") as ics_file:
22    ics_file.write(stream.ics())
23```
24
25"""
26
27# mypy: allow-any-generics
28
29from __future__ import annotations
30
31import logging
32import pyparsing
33
34try:
35    from pydantic.v1 import Field
36except ImportError:
37    from pydantic import Field  # type: ignore[assignment]
38
39from .calendar import Calendar
40from .component import ComponentModel
41from .parsing.component import encode_content, parse_content
42from .types.data_types import DATA_TYPE
43from .exceptions import CalendarParseError
44
45_LOGGER = logging.getLogger(__name__)
46
47
48class CalendarStream(ComponentModel):
49    """A container that is a collection of calendaring information.
50
51    This object supports parsing an rfc5545 calendar file, but does not
52    support encoding. See `IcsCalendarStream` instead for encoding ics files.
53    """
54
55    calendars: list[Calendar] = Field(alias="vcalendar", default_factory=list)
56
57    @classmethod
58    def from_ics(cls, content: str) -> "CalendarStream":
59        """Factory method to create a new instance from an rfc5545 iCalendar content."""
60        components = parse_content(content)
61        result: dict[str, list] = {"vcalendar": []}
62        for component in components:
63            result.setdefault(component.name, [])
64            result[component.name].append(component.as_dict())
65        _LOGGER.debug("Parsing object %s", result)
66        return cls(**result)
67
68    def ics(self) -> str:
69        """Encode the calendar stream as an rfc5545 iCalendar Stream content."""
70        return encode_content(self.__encode_component_root__().components)
71
72
73class IcsCalendarStream(CalendarStream):
74    """A calendar stream that supports parsing and encoding ICS."""
75
76    @classmethod
77    def calendar_from_ics(cls, content: str) -> Calendar:
78        """Load a single calendar from an ics string."""
79        stream = cls.from_ics(content)
80        if len(stream.calendars) == 1:
81            return stream.calendars[0]
82        if len(stream.calendars) == 0:
83            return Calendar()
84        raise CalendarParseError("Calendar Stream had more than one calendar")
85
86    @classmethod
87    def calendar_to_ics(cls, calendar: Calendar) -> str:
88        """Serialize a calendar as an ICS stream."""
89        stream = cls(vcalendar=[calendar])
90        return stream.ics()
91
92    class Config:
93        """Configuration for IcsCalendarStream pydantic model."""
94
95        json_encoders = DATA_TYPE.encode_property_json
96        validate_assignment = True
97        allow_population_by_field_name = True
class CalendarStream(ical.component.ComponentModel):
49class CalendarStream(ComponentModel):
50    """A container that is a collection of calendaring information.
51
52    This object supports parsing an rfc5545 calendar file, but does not
53    support encoding. See `IcsCalendarStream` instead for encoding ics files.
54    """
55
56    calendars: list[Calendar] = Field(alias="vcalendar", default_factory=list)
57
58    @classmethod
59    def from_ics(cls, content: str) -> "CalendarStream":
60        """Factory method to create a new instance from an rfc5545 iCalendar content."""
61        components = parse_content(content)
62        result: dict[str, list] = {"vcalendar": []}
63        for component in components:
64            result.setdefault(component.name, [])
65            result[component.name].append(component.as_dict())
66        _LOGGER.debug("Parsing object %s", result)
67        return cls(**result)
68
69    def ics(self) -> str:
70        """Encode the calendar stream as an rfc5545 iCalendar Stream content."""
71        return encode_content(self.__encode_component_root__().components)

A container that is a collection of calendaring information.

This object supports parsing an rfc5545 calendar file, but does not support encoding. See IcsCalendarStream instead for encoding ics files.

calendars: list[ical.calendar.Calendar]
@classmethod
def from_ics(cls, content: str) -> CalendarStream:
58    @classmethod
59    def from_ics(cls, content: str) -> "CalendarStream":
60        """Factory method to create a new instance from an rfc5545 iCalendar content."""
61        components = parse_content(content)
62        result: dict[str, list] = {"vcalendar": []}
63        for component in components:
64            result.setdefault(component.name, [])
65            result[component.name].append(component.as_dict())
66        _LOGGER.debug("Parsing object %s", result)
67        return cls(**result)

Factory method to create a new instance from an rfc5545 iCalendar content.

def ics(self) -> str:
69    def ics(self) -> str:
70        """Encode the calendar stream as an rfc5545 iCalendar Stream content."""
71        return encode_content(self.__encode_component_root__().components)

Encode the calendar stream as an rfc5545 iCalendar Stream content.

class IcsCalendarStream(CalendarStream):
74class IcsCalendarStream(CalendarStream):
75    """A calendar stream that supports parsing and encoding ICS."""
76
77    @classmethod
78    def calendar_from_ics(cls, content: str) -> Calendar:
79        """Load a single calendar from an ics string."""
80        stream = cls.from_ics(content)
81        if len(stream.calendars) == 1:
82            return stream.calendars[0]
83        if len(stream.calendars) == 0:
84            return Calendar()
85        raise CalendarParseError("Calendar Stream had more than one calendar")
86
87    @classmethod
88    def calendar_to_ics(cls, calendar: Calendar) -> str:
89        """Serialize a calendar as an ICS stream."""
90        stream = cls(vcalendar=[calendar])
91        return stream.ics()
92
93    class Config:
94        """Configuration for IcsCalendarStream pydantic model."""
95
96        json_encoders = DATA_TYPE.encode_property_json
97        validate_assignment = True
98        allow_population_by_field_name = True

A calendar stream that supports parsing and encoding ICS.

@classmethod
def calendar_from_ics(cls, content: str) -> ical.calendar.Calendar:
77    @classmethod
78    def calendar_from_ics(cls, content: str) -> Calendar:
79        """Load a single calendar from an ics string."""
80        stream = cls.from_ics(content)
81        if len(stream.calendars) == 1:
82            return stream.calendars[0]
83        if len(stream.calendars) == 0:
84            return Calendar()
85        raise CalendarParseError("Calendar Stream had more than one calendar")

Load a single calendar from an ics string.

@classmethod
def calendar_to_ics(cls, calendar: ical.calendar.Calendar) -> str:
87    @classmethod
88    def calendar_to_ics(cls, calendar: Calendar) -> str:
89        """Serialize a calendar as an ICS stream."""
90        stream = cls(vcalendar=[calendar])
91        return stream.ics()

Serialize a calendar as an ICS stream.

Inherited Members
CalendarStream
calendars
from_ics
ics
class IcsCalendarStream.Config:
93    class Config:
94        """Configuration for IcsCalendarStream pydantic model."""
95
96        json_encoders = DATA_TYPE.encode_property_json
97        validate_assignment = True
98        allow_population_by_field_name = True

Configuration for IcsCalendarStream pydantic model.

json_encoders = {<class 'datetime.date'>: <bound method DateEncoder.__encode_property_json__ of <class 'ical.types.date.DateEncoder'>>, <class 'datetime.datetime'>: <bound method DateTimeEncoder.__encode_property_json__ of <class 'ical.types.date_time.DateTimeEncoder'>>, <class 'datetime.timedelta'>: <bound method DurationEncoder.__encode_property_json__ of <class 'ical.types.duration.DurationEncoder'>>, <class 'ical.types.Geo'>: <bound method Geo.__encode_property_json__ of <class 'ical.types.Geo'>>, <class 'ical.types.RequestStatus'>: <bound method RequestStatus.__encode_property_json__ of <class 'ical.types.RequestStatus'>>, <class 'ical.types.UtcOffset'>: <bound method UtcOffset.__encode_property_json__ of <class 'ical.types.UtcOffset'>>}
validate_assignment = True
allow_population_by_field_name = True