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
33from pydantic.v1 import Field
34
35from .calendar import Calendar
36from .component import ComponentModel
37from .parsing.component import encode_content, parse_content
38from .types.data_types import DATA_TYPE
39from .exceptions import CalendarParseError
40
41_LOGGER = logging.getLogger(__name__)
42
43
44class CalendarStream(ComponentModel):
45    """A container that is a collection of calendaring information.
46
47    This object supports parsing an rfc5545 calendar file, but does not
48    support encoding. See `IcsCalendarStream` instead for encoding ics files.
49    """
50
51    calendars: list[Calendar] = Field(alias="vcalendar", default_factory=list)
52
53    @classmethod
54    def from_ics(cls, content: str) -> "CalendarStream":
55        """Factory method to create a new instance from an rfc5545 iCalendar content."""
56        components = parse_content(content)
57        result: dict[str, list] = {"vcalendar": []}
58        for component in components:
59            result.setdefault(component.name, [])
60            result[component.name].append(component.as_dict())
61        _LOGGER.debug("Parsing object %s", result)
62        return cls(**result)
63
64    def ics(self) -> str:
65        """Encode the calendar stream as an rfc5545 iCalendar Stream content."""
66        return encode_content(self.__encode_component_root__().components)
67
68
69class IcsCalendarStream(CalendarStream):
70    """A calendar stream that supports parsing and encoding ICS."""
71
72    @classmethod
73    def calendar_from_ics(cls, content: str) -> Calendar:
74        """Load a single calendar from an ics string."""
75        stream = cls.from_ics(content)
76        if len(stream.calendars) == 1:
77            return stream.calendars[0]
78        if len(stream.calendars) == 0:
79            return Calendar()
80        raise CalendarParseError("Calendar Stream had more than one calendar")
81
82    @classmethod
83    def calendar_to_ics(cls, calendar: Calendar) -> str:
84        """Serialize a calendar as an ICS stream."""
85        stream = cls(vcalendar=[calendar])
86        return stream.ics()
87
88    class Config:
89        """Configuration for IcsCalendarStream pydantic model."""
90
91        json_encoders = DATA_TYPE.encode_property_json
92        validate_assignment = True
93        allow_population_by_field_name = True
class CalendarStream(ical.component.ComponentModel):
45class CalendarStream(ComponentModel):
46    """A container that is a collection of calendaring information.
47
48    This object supports parsing an rfc5545 calendar file, but does not
49    support encoding. See `IcsCalendarStream` instead for encoding ics files.
50    """
51
52    calendars: list[Calendar] = Field(alias="vcalendar", default_factory=list)
53
54    @classmethod
55    def from_ics(cls, content: str) -> "CalendarStream":
56        """Factory method to create a new instance from an rfc5545 iCalendar content."""
57        components = parse_content(content)
58        result: dict[str, list] = {"vcalendar": []}
59        for component in components:
60            result.setdefault(component.name, [])
61            result[component.name].append(component.as_dict())
62        _LOGGER.debug("Parsing object %s", result)
63        return cls(**result)
64
65    def ics(self) -> str:
66        """Encode the calendar stream as an rfc5545 iCalendar Stream content."""
67        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:
54    @classmethod
55    def from_ics(cls, content: str) -> "CalendarStream":
56        """Factory method to create a new instance from an rfc5545 iCalendar content."""
57        components = parse_content(content)
58        result: dict[str, list] = {"vcalendar": []}
59        for component in components:
60            result.setdefault(component.name, [])
61            result[component.name].append(component.as_dict())
62        _LOGGER.debug("Parsing object %s", result)
63        return cls(**result)

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

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

Encode the calendar stream as an rfc5545 iCalendar Stream content.

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

Serialize a calendar as an ICS stream.

Inherited Members
CalendarStream
calendars
from_ics
ics
class IcsCalendarStream.Config:
89    class Config:
90        """Configuration for IcsCalendarStream pydantic model."""
91
92        json_encoders = DATA_TYPE.encode_property_json
93        validate_assignment = True
94        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