Module exchangelib.services.get_server_time_zones
Expand source code
import datetime
from .common import EWSService
from ..errors import NaiveDateTimeNotAllowed
from ..ewsdatetime import EWSDateTime
from ..fields import WEEKDAY_NAMES
from ..util import create_element, set_xml_value, xml_text_to_value, peek, TNS, MNS
from ..version import EXCHANGE_2010
class GetServerTimeZones(EWSService):
"""MSDN:
https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getservertimezones-operation
"""
SERVICE_NAME = 'GetServerTimeZones'
element_container_name = '{%s}TimeZoneDefinitions' % MNS
supported_from = EXCHANGE_2010
def call(self, timezones=None, return_full_timezone_data=False):
return self._elems_to_objs(self._get_elements(payload=self.get_payload(
timezones=timezones,
return_full_timezone_data=return_full_timezone_data
)))
def get_payload(self, timezones, return_full_timezone_data):
payload = create_element(
'm:%s' % self.SERVICE_NAME,
attrs=dict(ReturnFullTimeZoneData='true' if return_full_timezone_data else 'false'),
)
if timezones is not None:
is_empty, timezones = peek(timezones)
if not is_empty:
tz_ids = create_element('m:Ids')
for timezone in timezones:
tz_id = set_xml_value(create_element('t:Id'), timezone.ms_id, version=self.protocol.version)
tz_ids.append(tz_id)
payload.append(tz_ids)
return payload
def _elems_to_objs(self, elems):
for elem in elems:
if isinstance(elem, Exception):
yield elem
continue
tz_id = elem.get('Id')
tz_name = elem.get('Name')
tz_periods = self._get_periods(elem)
tz_transitions_groups = self._get_transitions_groups(elem)
tz_transitions = self._get_transitions(elem)
yield tz_id, tz_name, tz_periods, tz_transitions, tz_transitions_groups
@staticmethod
def _get_periods(timezonedef):
tz_periods = {}
periods = timezonedef.find('{%s}Periods' % TNS)
for period in periods.findall('{%s}Period' % TNS):
# Convert e.g. "trule:Microsoft/Registry/W. Europe Standard Time/2006-Daylight" to (2006, 'Daylight')
p_year, p_type = period.get('Id').rsplit('/', 1)[1].split('-')
tz_periods[(int(p_year), p_type)] = dict(
name=period.get('Name'),
bias=xml_text_to_value(period.get('Bias'), datetime.timedelta)
)
return tz_periods
@staticmethod
def _get_transitions_groups(timezonedef):
tz_transitions_groups = {}
transitiongroups = timezonedef.find('{%s}TransitionsGroups' % TNS)
if transitiongroups is not None:
for transitiongroup in transitiongroups.findall('{%s}TransitionsGroup' % TNS):
tg_id = int(transitiongroup.get('Id'))
tz_transitions_groups[tg_id] = []
for transition in transitiongroup.findall('{%s}Transition' % TNS):
# Apply same conversion to To as for period IDs
to_year, to_type = transition.find('{%s}To' % TNS).text.rsplit('/', 1)[1].split('-')
tz_transitions_groups[tg_id].append(dict(
to=(int(to_year), to_type),
))
for transition in transitiongroup.findall('{%s}RecurringDayTransition' % TNS):
# Apply same conversion to To as for period IDs
to_year, to_type = transition.find('{%s}To' % TNS).text.rsplit('/', 1)[1].split('-')
occurrence = xml_text_to_value(transition.find('{%s}Occurrence' % TNS).text, int)
if occurrence == -1:
# See TimeZoneTransition.from_xml()
occurrence = 5
tz_transitions_groups[tg_id].append(dict(
to=(int(to_year), to_type),
offset=xml_text_to_value(transition.find('{%s}TimeOffset' % TNS).text, datetime.timedelta),
iso_month=xml_text_to_value(transition.find('{%s}Month' % TNS).text, int),
iso_weekday=WEEKDAY_NAMES.index(transition.find('{%s}DayOfWeek' % TNS).text) + 1,
occurrence=occurrence,
))
return tz_transitions_groups
@staticmethod
def _get_transitions(timezonedef):
tz_transitions = {}
transitions = timezonedef.find('{%s}Transitions' % TNS)
if transitions is not None:
for transition in transitions.findall('{%s}Transition' % TNS):
to = transition.find('{%s}To' % TNS)
if to.get('Kind') != 'Group':
raise ValueError('Unexpected "Kind" XML attr: %s' % to.get('Kind'))
tg_id = xml_text_to_value(to.text, int)
tz_transitions[tg_id] = None
for transition in transitions.findall('{%s}AbsoluteDateTransition' % TNS):
to = transition.find('{%s}To' % TNS)
if to.get('Kind') != 'Group':
raise ValueError('Unexpected "Kind" XML attr: %s' % to.get('Kind'))
tg_id = xml_text_to_value(to.text, int)
try:
t_date = xml_text_to_value(transition.find('{%s}DateTime' % TNS).text, EWSDateTime).date()
except NaiveDateTimeNotAllowed as e:
# We encountered a naive datetime. Don't worry. we just need the date
t_date = e.local_dt.date()
tz_transitions[tg_id] = t_date
return tz_transitions
Classes
class GetServerTimeZones (protocol, chunk_size=None, timeout=None)
-
Expand source code
class GetServerTimeZones(EWSService): """MSDN: https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getservertimezones-operation """ SERVICE_NAME = 'GetServerTimeZones' element_container_name = '{%s}TimeZoneDefinitions' % MNS supported_from = EXCHANGE_2010 def call(self, timezones=None, return_full_timezone_data=False): return self._elems_to_objs(self._get_elements(payload=self.get_payload( timezones=timezones, return_full_timezone_data=return_full_timezone_data ))) def get_payload(self, timezones, return_full_timezone_data): payload = create_element( 'm:%s' % self.SERVICE_NAME, attrs=dict(ReturnFullTimeZoneData='true' if return_full_timezone_data else 'false'), ) if timezones is not None: is_empty, timezones = peek(timezones) if not is_empty: tz_ids = create_element('m:Ids') for timezone in timezones: tz_id = set_xml_value(create_element('t:Id'), timezone.ms_id, version=self.protocol.version) tz_ids.append(tz_id) payload.append(tz_ids) return payload def _elems_to_objs(self, elems): for elem in elems: if isinstance(elem, Exception): yield elem continue tz_id = elem.get('Id') tz_name = elem.get('Name') tz_periods = self._get_periods(elem) tz_transitions_groups = self._get_transitions_groups(elem) tz_transitions = self._get_transitions(elem) yield tz_id, tz_name, tz_periods, tz_transitions, tz_transitions_groups @staticmethod def _get_periods(timezonedef): tz_periods = {} periods = timezonedef.find('{%s}Periods' % TNS) for period in periods.findall('{%s}Period' % TNS): # Convert e.g. "trule:Microsoft/Registry/W. Europe Standard Time/2006-Daylight" to (2006, 'Daylight') p_year, p_type = period.get('Id').rsplit('/', 1)[1].split('-') tz_periods[(int(p_year), p_type)] = dict( name=period.get('Name'), bias=xml_text_to_value(period.get('Bias'), datetime.timedelta) ) return tz_periods @staticmethod def _get_transitions_groups(timezonedef): tz_transitions_groups = {} transitiongroups = timezonedef.find('{%s}TransitionsGroups' % TNS) if transitiongroups is not None: for transitiongroup in transitiongroups.findall('{%s}TransitionsGroup' % TNS): tg_id = int(transitiongroup.get('Id')) tz_transitions_groups[tg_id] = [] for transition in transitiongroup.findall('{%s}Transition' % TNS): # Apply same conversion to To as for period IDs to_year, to_type = transition.find('{%s}To' % TNS).text.rsplit('/', 1)[1].split('-') tz_transitions_groups[tg_id].append(dict( to=(int(to_year), to_type), )) for transition in transitiongroup.findall('{%s}RecurringDayTransition' % TNS): # Apply same conversion to To as for period IDs to_year, to_type = transition.find('{%s}To' % TNS).text.rsplit('/', 1)[1].split('-') occurrence = xml_text_to_value(transition.find('{%s}Occurrence' % TNS).text, int) if occurrence == -1: # See TimeZoneTransition.from_xml() occurrence = 5 tz_transitions_groups[tg_id].append(dict( to=(int(to_year), to_type), offset=xml_text_to_value(transition.find('{%s}TimeOffset' % TNS).text, datetime.timedelta), iso_month=xml_text_to_value(transition.find('{%s}Month' % TNS).text, int), iso_weekday=WEEKDAY_NAMES.index(transition.find('{%s}DayOfWeek' % TNS).text) + 1, occurrence=occurrence, )) return tz_transitions_groups @staticmethod def _get_transitions(timezonedef): tz_transitions = {} transitions = timezonedef.find('{%s}Transitions' % TNS) if transitions is not None: for transition in transitions.findall('{%s}Transition' % TNS): to = transition.find('{%s}To' % TNS) if to.get('Kind') != 'Group': raise ValueError('Unexpected "Kind" XML attr: %s' % to.get('Kind')) tg_id = xml_text_to_value(to.text, int) tz_transitions[tg_id] = None for transition in transitions.findall('{%s}AbsoluteDateTransition' % TNS): to = transition.find('{%s}To' % TNS) if to.get('Kind') != 'Group': raise ValueError('Unexpected "Kind" XML attr: %s' % to.get('Kind')) tg_id = xml_text_to_value(to.text, int) try: t_date = xml_text_to_value(transition.find('{%s}DateTime' % TNS).text, EWSDateTime).date() except NaiveDateTimeNotAllowed as e: # We encountered a naive datetime. Don't worry. we just need the date t_date = e.local_dt.date() tz_transitions[tg_id] = t_date return tz_transitions
Ancestors
Class variables
var SERVICE_NAME
var element_container_name
var supported_from
Methods
def call(self, timezones=None, return_full_timezone_data=False)
-
Expand source code
def call(self, timezones=None, return_full_timezone_data=False): return self._elems_to_objs(self._get_elements(payload=self.get_payload( timezones=timezones, return_full_timezone_data=return_full_timezone_data )))
def get_payload(self, timezones, return_full_timezone_data)
-
Expand source code
def get_payload(self, timezones, return_full_timezone_data): payload = create_element( 'm:%s' % self.SERVICE_NAME, attrs=dict(ReturnFullTimeZoneData='true' if return_full_timezone_data else 'false'), ) if timezones is not None: is_empty, timezones = peek(timezones) if not is_empty: tz_ids = create_element('m:Ids') for timezone in timezones: tz_id = set_xml_value(create_element('t:Id'), timezone.ms_id, version=self.protocol.version) tz_ids.append(tz_id) payload.append(tz_ids) return payload
Inherited members