Source code for ics.icalendar

import copy
import warnings
from typing import Dict, Iterable, Optional, Set, Union

from six import text_type

from .component import Component
from .event import Event
from ics.grammar.parse import Container, calendar_string_to_containers
from .timeline import Timeline
from .todo import Todo
from ics.parsers.icalendar_parser import CalendarParser
from ics.serializers.icalendar_serializer import CalendarSerializer


[docs]class Calendar(Component): """ Represents an unique rfc5545 iCalendar. Attributes: events: a set of Event contained in the Calendar todos: a set of Todo contained in the Calendar timeline: a Timeline instance linked to this Calendar """ class Meta: name = 'VCALENDAR' parser = CalendarParser serializer = CalendarSerializer
[docs] def __init__( self, imports: Union[str, Container] = None, events: Iterable[Event] = None, todos: Iterable[Todo] = None, creator: str = None ): """Instantiates a new Calendar. Args: imports (**str**): data to be imported into the Calendar, events (**Set[Event]**): Events to be added to the calendar todos (Set[Todo]): Todos to be added to the calendar creator (string): uid of the creator program. If ``imports`` is specified, every other argument will be ignored. """ self._timezones: Dict = {} # FIXME mypy self.events: Set[Event] = set() self.todos: Set[Todo] = set() self.extra = Container(name='VCALENDAR') self.scale = None self.method = None self.timeline = Timeline(self) if imports is not None: if isinstance(imports, Container): self._populate(imports) else: containers = calendar_string_to_containers(imports) if len(containers) != 1: raise NotImplementedError( 'Multiple calendars in one file are not supported by this method. Use ics.Calendar.parse_multiple()') self._populate(containers[0]) # Use first calendar else: if events is not None: self.events.update(set(events)) if todos is not None: self.todos.update(set(todos)) self._creator = creator
[docs] @classmethod def parse_multiple(cls, string): """" Parses an input string that may contain mutiple calendars and retruns a list of :class:`ics.event.Calendar` """ containers = calendar_string_to_containers(string) return [cls(imports=c) for c in containers]
[docs] def __repr__(self) -> str: return "<Calendar with {} event{} and {} todo{}>" \ .format(len(self.events), "s" if len(self.events) > 1 else "", len(self.todos), "s" if len(self.todos) > 1 else "")
[docs] def __iter__(self) -> Iterable[str]: """Returns: iterable: an iterable version of seralize(), line per line (with line-endings). Example: Can be used to write calendar to a file: >>> c = Calendar(); c.events.add(Event(name="My cool event")) >>> open('my.ics', 'w').writelines(c) """ warnings.warn( "Using Calendar as Iterable is deprecated and will be removed in version 0.8. " "Use the explicit calendar.serialize_iter() instead.", DeprecationWarning) yield from self.serialize_iter()
[docs] def __eq__(self, other: object) -> bool: if not isinstance(other, Calendar): raise NotImplementedError for attr in ('extra', 'scale', 'method', 'creator'): if self.__getattribute__(attr) != other.__getattribute__(attr): return False return (self.events == other.events) and (self.todos == other.todos)
[docs] def __ne__(self, other: object) -> bool: return not self.__eq__(other)
@property def creator(self) -> Optional[str]: """Get or set the calendar's creator. | Will return a string. | May be set to a string. | Creator is the PRODID iCalendar property. | It uniquely identifies the program that created the calendar. """ return self._creator @creator.setter def creator(self, value: Optional[str]) -> None: if not isinstance(value, text_type): raise ValueError('Event.creator must be unicode data not {}'.format(type(value))) self._creator = value
[docs] def clone(self): """ Returns: Calendar: an exact deep copy of self """ clone = copy.copy(self) clone.extra = clone.extra.clone() clone.events = copy.copy(self.events) clone.todos = copy.copy(self.todos) clone._timezones = copy.copy(self._timezones) return clone