File size: 14,560 Bytes
550665c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
from functools import total_ordering
from typing import List, Union
from beautiful_date import BeautifulDate
from tzlocal import get_localzone_name
from datetime import datetime, date, timedelta, time
from ._resource import Resource
from .attachment import Attachment
from .attendee import Attendee
from .conference import ConferenceSolution, ConferenceSolutionCreateRequest
from .person import Person
from .reminders import PopupReminder, EmailReminder, Reminder
from .util.date_time_util import ensure_localisation
class Visibility:
"""Possible values of the event visibility.
* `DEFAULT` - Uses the default visibility for events on the calendar. This is the default value.
* `PUBLIC` - The event is public and event details are visible to all readers of the calendar.
* `PRIVATE` - The event is private and only event attendees may view event details.
"""
DEFAULT = "default"
PUBLIC = "public"
PRIVATE = "private"
class Transparency:
"""Possible values of the event transparency.
* `OPAQUE` - Default value. The event does block time on the calendar.
This is equivalent to setting 'Show me as' to 'Busy' in the Calendar UI.
* `TRANSPARENT` - The event does not block time on the calendar.
This is equivalent to setting 'Show me as' to 'Available' in the Calendar UI.
"""
OPAQUE = 'opaque'
TRANSPARENT = 'transparent'
@total_ordering
class Event(Resource):
def __init__(
self,
summary: str,
start: Union[date, datetime, BeautifulDate],
end: Union[date, datetime, BeautifulDate] = None,
*,
timezone: str = get_localzone_name(),
event_id: str = None,
description: str = None,
location: str = None,
recurrence: Union[str, List[str]] = None,
color_id: str = None,
visibility: str = Visibility.DEFAULT,
attendees: Union[Attendee, str, List[Attendee], List[str]] = None,
attachments: Union[Attachment, List[Attachment]] = None,
conference_solution: Union[ConferenceSolution, ConferenceSolutionCreateRequest] = None,
reminders: Union[Reminder, List[Reminder]] = None,
default_reminders: bool = False,
minutes_before_popup_reminder: int = None,
minutes_before_email_reminder: int = None,
guests_can_invite_others: bool = True,
guests_can_modify: bool = False,
guests_can_see_other_guests: bool = True,
transparency: str = None,
_creator: Person = None,
_organizer: Person = None,
_created: datetime = None,
_updated: datetime = None,
_recurring_event_id: str = None,
**other
):
"""
:param summary:
Title of the event.
:param start:
Starting date/datetime.
:param end:
Ending date/datetime. If 'end' is not specified, event is considered as a 1-day or 1-hour event
if 'start' is date or datetime respectively.
:param timezone:
Timezone formatted as an IANA Time Zone Database name, e.g. "Europe/Zurich". By default,
the computers local timezone is used if it is configured. UTC is used otherwise.
:param event_id:
Opaque identifier of the event. By default, it is generated by the server. You can specify id as a
5-1024 long string of characters used in base32hex ([a-vA-V0-9]). The ID must be unique per
calendar.
:param description:
Description of the event. Can contain HTML.
:param location:
Geographic location of the event as free-form text.
:param recurrence:
RRULE/RDATE/EXRULE/EXDATE string or list of such strings. See :py:mod:`~gcsa.recurrence`
:param color_id:
Color id referring to an entry from colors endpoint.
See :py:meth:`~gcsa.google_calendar.GoogleCalendar.list_event_colors`
:param visibility:
Visibility of the event. Default is default visibility for events on the calendar.
See :py:class:`~gcsa.event.Visibility`
:param attendees:
Attendee or list of attendees. See :py:class:`~gcsa.attendee.Attendee`.
Each attendee may be given as email string or :py:class:`~gcsa.attendee.Attendee` object.
:param attachments:
Attachment or list of attachments. See :py:class:`~gcsa.attachment.Attachment`
:param conference_solution:
:py:class:`~gcsa.conference.ConferenceSolutionCreateRequest` object to create a new conference
or :py:class:`~gcsa.conference.ConferenceSolution` object for existing conference.
:param reminders:
Reminder or list of reminder objects. See :py:mod:`~gcsa.reminders`
:param default_reminders:
Whether the default reminders of the calendar apply to the event.
:param minutes_before_popup_reminder:
Minutes before popup reminder or None if reminder is not needed.
:param minutes_before_email_reminder:
Minutes before email reminder or None if reminder is not needed.
:param guests_can_invite_others:
Whether attendees other than the organizer can invite others to the event.
:param guests_can_modify:
Whether attendees other than the organizer can modify the event.
:param guests_can_see_other_guests:
Whether attendees other than the organizer can see who the event's attendees are.
:param transparency:
Whether the event blocks time on the calendar. See :py:class:`~gcsa.event.Transparency`
:param _creator:
The creator of the event. See :py:class:`~gcsa.person.Person`
:param _organizer:
The organizer of the event. See :py:class:`~gcsa.person.Person`.
If the organizer is also an attendee, this is indicated with a separate entry in attendees with
the organizer field set to True.
To change the organizer, use the move operation
see :py:meth:`~gcsa.google_calendar.GoogleCalendar.move_event`
:param _created:
Creation time of the event. Read-only.
:param _updated:
Last modification time of the event. Read-only.
:param _recurring_event_id:
For an instance of a recurring event, this is the id of the recurring event to which
this instance belongs. Read-only.
:param other:
Other fields that should be included in request json. Will be included as they are.
See more in https://developers.google.com/calendar/v3/reference/events
"""
def ensure_list(obj):
return [] if obj is None else obj if isinstance(obj, list) else [obj]
self.timezone = timezone
self.start = start
if end or start is None:
self.end = end
elif isinstance(start, datetime):
self.end = start + timedelta(hours=1)
elif isinstance(start, date):
self.end = start + timedelta(days=1)
if isinstance(self.start, datetime) and isinstance(self.end, datetime):
self.start = ensure_localisation(self.start, timezone)
self.end = ensure_localisation(self.end, timezone)
elif isinstance(self.start, datetime) or isinstance(self.end, datetime):
raise TypeError('Start and end must either both be date or both be datetime.')
def ensure_date(d):
"""Converts d to date if it is of type BeautifulDate."""
if isinstance(d, BeautifulDate):
return date(year=d.year, month=d.month, day=d.day)
else:
return d
self.start = ensure_date(self.start)
self.end = ensure_date(self.end)
self.created = _created
self.updated = _updated
attendees = [self._ensure_attendee_from_email(a) for a in ensure_list(attendees)]
reminders = ensure_list(reminders)
if len(reminders) > 5:
raise ValueError('The maximum number of override reminders is 5.')
if default_reminders and reminders:
raise ValueError('Cannot specify both default reminders and overrides at the same time.')
self.event_id = event_id
self.summary = summary
self.description = description
self.location = location
self.recurrence = ensure_list(recurrence)
self.color_id = color_id
self.visibility = visibility
self.attendees = attendees
self.attachments = ensure_list(attachments)
self.conference_solution = conference_solution
self.reminders = reminders
self.default_reminders = default_reminders
self.recurring_event_id = _recurring_event_id
self.guests_can_invite_others = guests_can_invite_others
self.guests_can_modify = guests_can_modify
self.guests_can_see_other_guests = guests_can_see_other_guests
self.transparency = transparency
self.creator = _creator
self.organizer = _organizer
self.other = other
if minutes_before_popup_reminder is not None:
self.add_popup_reminder(minutes_before_popup_reminder)
if minutes_before_email_reminder is not None:
self.add_email_reminder(minutes_before_email_reminder)
@property
def id(self):
return self.event_id
def add_attendee(
self,
attendee: Union[str, Attendee]
):
"""Adds attendee to an event. See :py:class:`~gcsa.attendee.Attendee`.
Attendee may be given as email string or :py:class:`~gcsa.attendee.Attendee` object."""
self.attendees.append(self._ensure_attendee_from_email(attendee))
def add_attendees(
self,
attendees: List[Union[str, Attendee]]
):
"""Adds multiple attendees to an event. See :py:class:`~gcsa.attendee.Attendee`.
Each attendee may be given as email string or :py:class:`~gcsa.attendee.Attendee` object."""
for a in attendees:
self.add_attendee(a)
def add_attachment(
self,
file_url: str,
title: str = None,
mime_type: str = None
):
"""Adds attachment to an event. See :py:class:`~gcsa.attachment.Attachment`"""
self.attachments.append(Attachment(file_url=file_url, title=title, mime_type=mime_type))
def add_email_reminder(
self,
minutes_before_start: int = None,
days_before: int = None,
at: time = None
):
"""Adds email reminder to an event. See :py:class:`~gcsa.reminders.EmailReminder`"""
self.add_reminder(EmailReminder(minutes_before_start, days_before, at))
def add_popup_reminder(
self,
minutes_before_start: int = None,
days_before: int = None,
at: time = None
):
"""Adds popup reminder to an event. See :py:class:`~gcsa.reminders.PopupReminder`"""
self.add_reminder(PopupReminder(minutes_before_start, days_before, at))
def add_reminder(
self,
reminder: Reminder
):
"""Adds reminder to an event. See :py:mod:`~gcsa.reminders`"""
if len(self.reminders) > 4:
raise ValueError('The maximum number of override reminders is 5.')
self.reminders.append(reminder)
@staticmethod
def _ensure_attendee_from_email(
attendee_or_email: Union[str, Attendee]
):
"""If attendee_or_email is email string, returns created :py:class:`~gcsa.attendee.Attendee`
object with the given email."""
if isinstance(attendee_or_email, str):
return Attendee(email=attendee_or_email)
else:
return attendee_or_email
@property
def is_recurring_instance(self):
return self.recurring_event_id is not None
def __str__(self):
return '{} - {}'.format(self.start, self.summary)
def __repr__(self):
return '<Event {}>'.format(self.__str__())
def __lt__(self, other):
def ensure_datetime(d, timezone):
if type(d) is date:
return ensure_localisation(datetime(year=d.year, month=d.month, day=d.day), timezone)
else:
return d
start = ensure_datetime(self.start, self.timezone)
end = ensure_datetime(self.end, self.timezone)
other_start = ensure_datetime(other.start, other.timezone)
other_end = ensure_datetime(other.end, other.timezone)
return (start, end) < (other_start, other_end)
def __eq__(self, other):
return (
isinstance(other, Event)
and self.start == other.start
and self.end == other.end
and self.event_id == other.event_id
and self.summary == other.summary
and self.description == other.description
and self.location == other.location
and self.recurrence == other.recurrence
and self.color_id == other.color_id
and self.visibility == other.visibility
and self.attendees == other.attendees
and self.attachments == other.attachments
and self.reminders == other.reminders
and self.default_reminders == other.default_reminders
and self.created == other.created
and self.updated == other.updated
and self.recurring_event_id == other.recurring_event_id
and self.guests_can_invite_others == other.guests_can_invite_others
and self.guests_can_modify == other.guests_can_modify
and self.guests_can_see_other_guests == other.guests_can_see_other_guests
and self.other == other.other
)
|