File size: 3,977 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
import json
from collections import namedtuple
from datetime import datetime
from typing import Dict, List

TimeRange = namedtuple('TimeRange', ('start', 'end'))


class FreeBusy:
    def __init__(

            self,

            *,

            time_min: datetime,

            time_max: datetime,

            groups: Dict[str, List[str]],

            calendars: Dict[str, List[TimeRange]],

            groups_errors: Dict = None,

            calendars_errors: Dict = None,

    ):
        """Represents free/busy information for a given calendar(s) and/or group(s)



        :param time_min:

                The start of the interval.

        :param time_max:

                The end of the interval.

        :param groups:

                Expansion of groups.

                Dictionary that maps the name of the group to the list of calendars that are members of this group.

        :param calendars:

                Free/busy information for calendars.

                Dictionary that maps calendar id to the list of time ranges during which this calendar should be

                regarded as busy.

        :param groups_errors:

                Optional error(s) (if computation for the group failed).

                Dictionary that maps the name of the group to the list of errors.

        :param calendars_errors:

                Optional error(s) (if computation for the calendar failed).

                Dictionary that maps calendar id to the list of errors.





        .. note:: Errors have the following format:



            .. code-block::



                {

                  "domain": "<domain>",

                  "reason": "<reason>"

                }



            Some possible values for "reason" are:



             * "groupTooBig" - The group of users requested is too large for a single query.

             * "tooManyCalendarsRequested" - The number of calendars requested is too large for a single query.

             * "notFound" - The requested resource was not found.

             * "internalError" - The API service has encountered an internal error.



            Additional error types may be added in the future.

        """
        self.time_min = time_min
        self.time_max = time_max
        self.groups = groups
        self.calendars = calendars
        self.groups_errors = groups_errors or {}
        self.calendars_errors = calendars_errors or {}

    def __iter__(self):
        """

        :returns:

                list of 'TimeRange's during which this calendar should be regarded as busy.

        :raises:

                ValueError if requested all requested calendars have errors

                or more than one calendar has been requested.

        """
        if len(self.calendars) == 0:
            raise ValueError("No free/busy information has been received. "
                             "Check the 'calendars_errors' and 'groups_errors' fields.")
        if len(self.calendars) > 1 or len(self.calendars_errors) > 0:
            raise ValueError("Can't iterate over FreeBusy objects directly when more than one calendars were requested."
                             "Use 'calendars' field instead to get free/busy information of the specific calendar.")
        return iter(next(iter(self.calendars.values())))

    def __str__(self):
        return '<FreeBusy {} - {}>'.format(self.time_min, self.time_max)

    def __repr__(self):
        return self.__str__()


class FreeBusyQueryError(Exception):
    def __init__(self, groups_errors, calendars_errors):
        message = '\n'
        if groups_errors:
            message += f'Groups errors: {json.dumps(groups_errors, indent=4)}'
        if calendars_errors:
            message += f'Calendars errors: {json.dumps(calendars_errors, indent=4)}'
        super().__init__(message)
        self.groups_errors = groups_errors
        self.calendars_errors = calendars_errors