exchangelib.settings API documentation

# Module `exchangelib.settings`

Expand source code

    import datetime

    from .ewsdatetime import UTC
    from .fields import DateTimeField, MessageField, ChoiceField, Choice
    from .properties import EWSElement, OutOfOffice
    from .util import create_element, set_xml_value

    class OofSettings(EWSElement):
        """MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/oofsettings"""

        ELEMENT_NAME = 'OofSettings'
        REQUEST_ELEMENT_NAME = 'UserOofSettings'

        ENABLED = 'Enabled'
        SCHEDULED = 'Scheduled'
        DISABLED = 'Disabled'
        STATE_CHOICES = (ENABLED, SCHEDULED, DISABLED)

        state = ChoiceField(field_uri='OofState', is_required=True, choices={Choice(c) for c in STATE_CHOICES})
        external_audience = ChoiceField(field_uri='ExternalAudience',
                                        choices={Choice('None'), Choice('Known'), Choice('All')}, default='All')
        start = DateTimeField(field_uri='StartTime')
        end = DateTimeField(field_uri='EndTime')
        internal_reply = MessageField(field_uri='InternalReply')
        external_reply = MessageField(field_uri='ExternalReply')

        def clean(self, version=None):
            super().clean(version=version)
            if self.state == self.SCHEDULED:
                if not self.start or not self.end:
                    raise ValueError("'start' and 'end' must be set when state is '%s'" % self.SCHEDULED)
                if self.start >= self.end:
                    raise ValueError("'start' must be before 'end'")
                if self.end < datetime.datetime.now(tz=UTC):
                    raise ValueError("'end' must be in the future")
            if self.state != self.DISABLED and (not self.internal_reply or not self.external_reply):
                raise ValueError("'internal_reply' and 'external_reply' must be set when state is not '%s'" % self.DISABLED)

        @classmethod
        def from_xml(cls, elem, account):
            kwargs = {}
            for attr in ('state', 'external_audience', 'internal_reply', 'external_reply'):
                f = cls.get_field_by_fieldname(attr)
                kwargs[attr] = f.from_xml(elem=elem, account=account)
            kwargs.update(OutOfOffice.duration_to_start_end(elem=elem, account=account))
            cls._clear(elem)
            return cls(**kwargs)

        def to_xml(self, version):
            self.clean(version=version)
            elem = create_element('t:%s' % self.REQUEST_ELEMENT_NAME)
            for attr in ('state', 'external_audience'):
                value = getattr(self, attr)
                if value is None:
                    continue
                f = self.get_field_by_fieldname(attr)
                set_xml_value(elem, f.to_xml(value, version=version), version=version)
            if self.start or self.end:
                duration = create_element('t:Duration')
                if self.start:
                    f = self.get_field_by_fieldname('start')
                    set_xml_value(duration, f.to_xml(self.start, version=version), version)
                if self.end:
                    f = self.get_field_by_fieldname('end')
                    set_xml_value(duration, f.to_xml(self.end, version=version), version)
                elem.append(duration)
            for attr in ('internal_reply', 'external_reply'):
                value = getattr(self, attr)
                if value is None:
                    value = ''  # The value can be empty, but the XML element must always be present
                f = self.get_field_by_fieldname(attr)
                set_xml_value(elem, f.to_xml(value, version=version), version)
            return elem

        def __hash__(self):
            # Customize comparison
            if self.state == self.DISABLED:
                # All values except state are ignored by the server
                relevant_attrs = ('state',)
            elif self.state != self.SCHEDULED:
                # 'start' and 'end' values are ignored by the server, and the server always returns today's date
                relevant_attrs = tuple(f.name for f in self.FIELDS if f.name not in ('start', 'end'))
            else:
                relevant_attrs = tuple(f.name for f in self.FIELDS)
            return hash(tuple(getattr(self, attr) for attr in relevant_attrs))

## Classes

`class OofSettings (**kwargs)`

  MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/oofsettings

  Expand source code

      class OofSettings(EWSElement):
          """MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/oofsettings"""

          ELEMENT_NAME = 'OofSettings'
          REQUEST_ELEMENT_NAME = 'UserOofSettings'

          ENABLED = 'Enabled'
          SCHEDULED = 'Scheduled'
          DISABLED = 'Disabled'
          STATE_CHOICES = (ENABLED, SCHEDULED, DISABLED)

          state = ChoiceField(field_uri='OofState', is_required=True, choices={Choice(c) for c in STATE_CHOICES})
          external_audience = ChoiceField(field_uri='ExternalAudience',
                                          choices={Choice('None'), Choice('Known'), Choice('All')}, default='All')
          start = DateTimeField(field_uri='StartTime')
          end = DateTimeField(field_uri='EndTime')
          internal_reply = MessageField(field_uri='InternalReply')
          external_reply = MessageField(field_uri='ExternalReply')

          def clean(self, version=None):
              super().clean(version=version)
              if self.state == self.SCHEDULED:
                  if not self.start or not self.end:
                      raise ValueError("'start' and 'end' must be set when state is '%s'" % self.SCHEDULED)
                  if self.start >= self.end:
                      raise ValueError("'start' must be before 'end'")
                  if self.end < datetime.datetime.now(tz=UTC):
                      raise ValueError("'end' must be in the future")
              if self.state != self.DISABLED and (not self.internal_reply or not self.external_reply):
                  raise ValueError("'internal_reply' and 'external_reply' must be set when state is not '%s'" % self.DISABLED)

          @classmethod
          def from_xml(cls, elem, account):
              kwargs = {}
              for attr in ('state', 'external_audience', 'internal_reply', 'external_reply'):
                  f = cls.get_field_by_fieldname(attr)
                  kwargs[attr] = f.from_xml(elem=elem, account=account)
              kwargs.update(OutOfOffice.duration_to_start_end(elem=elem, account=account))
              cls._clear(elem)
              return cls(**kwargs)

          def to_xml(self, version):
              self.clean(version=version)
              elem = create_element('t:%s' % self.REQUEST_ELEMENT_NAME)
              for attr in ('state', 'external_audience'):
                  value = getattr(self, attr)
                  if value is None:
                      continue
                  f = self.get_field_by_fieldname(attr)
                  set_xml_value(elem, f.to_xml(value, version=version), version=version)
              if self.start or self.end:
                  duration = create_element('t:Duration')
                  if self.start:
                      f = self.get_field_by_fieldname('start')
                      set_xml_value(duration, f.to_xml(self.start, version=version), version)
                  if self.end:
                      f = self.get_field_by_fieldname('end')
                      set_xml_value(duration, f.to_xml(self.end, version=version), version)
                  elem.append(duration)
              for attr in ('internal_reply', 'external_reply'):
                  value = getattr(self, attr)
                  if value is None:
                      value = ''  # The value can be empty, but the XML element must always be present
                  f = self.get_field_by_fieldname(attr)
                  set_xml_value(elem, f.to_xml(value, version=version), version)
              return elem

          def __hash__(self):
              # Customize comparison
              if self.state == self.DISABLED:
                  # All values except state are ignored by the server
                  relevant_attrs = ('state',)
              elif self.state != self.SCHEDULED:
                  # 'start' and 'end' values are ignored by the server, and the server always returns today's date
                  relevant_attrs = tuple(f.name for f in self.FIELDS if f.name not in ('start', 'end'))
              else:
                  relevant_attrs = tuple(f.name for f in self.FIELDS)
              return hash(tuple(getattr(self, attr) for attr in relevant_attrs))

  ### Ancestors

  - EWSElement

  ### Class variables

  `var DISABLED`
  `var ELEMENT_NAME`
  `var ENABLED`
  `var FIELDS`
  `var REQUEST_ELEMENT_NAME`
  `var SCHEDULED`
  `var STATE_CHOICES`

  ### Static methods

  `def from_xml(elem, account)`
    Expand source code

        @classmethod
        def from_xml(cls, elem, account):
            kwargs = {}
            for attr in ('state', 'external_audience', 'internal_reply', 'external_reply'):
                f = cls.get_field_by_fieldname(attr)
                kwargs[attr] = f.from_xml(elem=elem, account=account)
            kwargs.update(OutOfOffice.duration_to_start_end(elem=elem, account=account))
            cls._clear(elem)
            return cls(**kwargs)

  ### Instance variables

  `var end`
  `var external_audience`
  `var external_reply`
  `var internal_reply`
  `var start`
  `var state`

  ### Methods

  `def clean(self, version=None)`
    Expand source code

        def clean(self, version=None):
            super().clean(version=version)
            if self.state == self.SCHEDULED:
                if not self.start or not self.end:
                    raise ValueError("'start' and 'end' must be set when state is '%s'" % self.SCHEDULED)
                if self.start >= self.end:
                    raise ValueError("'start' must be before 'end'")
                if self.end < datetime.datetime.now(tz=UTC):
                    raise ValueError("'end' must be in the future")
            if self.state != self.DISABLED and (not self.internal_reply or not self.external_reply):
                raise ValueError("'internal_reply' and 'external_reply' must be set when state is not '%s'" % self.DISABLED)

  `def to_xml(self, version)`
    Expand source code

        def to_xml(self, version):
            self.clean(version=version)
            elem = create_element('t:%s' % self.REQUEST_ELEMENT_NAME)
            for attr in ('state', 'external_audience'):
                value = getattr(self, attr)
                if value is None:
                    continue
                f = self.get_field_by_fieldname(attr)
                set_xml_value(elem, f.to_xml(value, version=version), version=version)
            if self.start or self.end:
                duration = create_element('t:Duration')
                if self.start:
                    f = self.get_field_by_fieldname('start')
                    set_xml_value(duration, f.to_xml(self.start, version=version), version)
                if self.end:
                    f = self.get_field_by_fieldname('end')
                    set_xml_value(duration, f.to_xml(self.end, version=version), version)
                elem.append(duration)
            for attr in ('internal_reply', 'external_reply'):
                value = getattr(self, attr)
                if value is None:
                    value = ''  # The value can be empty, but the XML element must always be present
                f = self.get_field_by_fieldname(attr)
                set_xml_value(elem, f.to_xml(value, version=version), version)
            return elem

  ### Inherited members

  - `EWSElement`:
    - `add_field`
    - `remove_field`
    - `supported_fields`
    - `validate_field`