def test_get_free_busy_info(self): tz = EWSTimeZone('Europe/Copenhagen') server_timezones = list(self.account.protocol.get_timezones(return_full_timezone_data=True)) start = EWSDateTime.now(tz=tz) end = EWSDateTime.now(tz=tz) + datetime.timedelta(hours=6) accounts = [(self.account, 'Organizer', False)] with self.assertRaises(ValueError): self.account.protocol.get_free_busy_info(accounts=[(123, 'XXX', 'XXX')], start=0, end=0) with self.assertRaises(ValueError): self.account.protocol.get_free_busy_info(accounts=[(self.account, 'XXX', 'XXX')], start=0, end=0) with self.assertRaises(ValueError): self.account.protocol.get_free_busy_info(accounts=[(self.account, 'Organizer', 'XXX')], start=0, end=0) with self.assertRaises(ValueError): self.account.protocol.get_free_busy_info(accounts=accounts, start=end, end=start) with self.assertRaises(ValueError): self.account.protocol.get_free_busy_info(accounts=accounts, start=start, end=end, merged_free_busy_interval='XXX') with self.assertRaises(ValueError): self.account.protocol.get_free_busy_info(accounts=accounts, start=start, end=end, requested_view='XXX') for view_info in self.account.protocol.get_free_busy_info(accounts=accounts, start=start, end=end): self.assertIsInstance(view_info, FreeBusyView) self.assertIsInstance(view_info.working_hours_timezone, TimeZone) ms_id = view_info.working_hours_timezone.to_server_timezone(server_timezones, start.year) self.assertIn(ms_id, {t[0] for t in CLDR_TO_MS_TIMEZONE_MAP.values()}) # Test account as simple email for view_info in self.account.protocol.get_free_busy_info( accounts=[(self.account.primary_smtp_address, 'Organizer', False)], start=start, end=end ): self.assertIsInstance(view_info, FreeBusyView)
def test_localize(self): # Test some corner cases around DST tz = EWSTimeZone('Europe/Copenhagen') with warnings.catch_warnings(): # localize() is deprecated but we still want to test it. Silence the DeprecationWarning warnings.simplefilter("ignore") self.assertEqual( str( tz.localize(EWSDateTime(2023, 10, 29, 2, 36, 0), is_dst=False)), '2023-10-29 02:36:00+01:00') self.assertEqual( str( tz.localize(EWSDateTime(2023, 10, 29, 2, 36, 0), is_dst=None)), '2023-10-29 02:36:00+02:00') self.assertEqual( str( tz.localize(EWSDateTime(2023, 10, 29, 2, 36, 0), is_dst=True)), '2023-10-29 02:36:00+02:00') self.assertEqual( str( tz.localize(EWSDateTime(2023, 3, 26, 2, 36, 0), is_dst=False)), '2023-03-26 02:36:00+01:00') self.assertEqual( str( tz.localize(EWSDateTime(2023, 3, 26, 2, 36, 0), is_dst=None)), '2023-03-26 02:36:00+01:00') self.assertEqual( str( tz.localize(EWSDateTime(2023, 3, 26, 2, 36, 0), is_dst=True)), '2023-03-26 02:36:00+02:00')
def mail_ids_by_date( self, *, before: Optional[float] = None, after: Optional[float] = None, ) -> Iterable[float]: # exchangelib needs a timezone to be applied in order to select mails by # date. Providing none (and thus keep the default) results in errors # on some machines, so we hardcode one here. # In order to make EWS filter correctly in different timezones we need # a way to configure the enforced setting and keep the defaults if # none are given. tz = EWSTimeZone("Europe/Berlin") dt_start = EWSDateTime.from_datetime( datetime.fromtimestamp(after) if after else datetime(1990, 1, 1) ).astimezone(tz) dt_end = EWSDateTime.from_datetime( datetime.fromtimestamp(before) if before else datetime.now() ).astimezone(tz) logging.debug("fetch mails from %s (from %s)", dt_start, after) logging.debug("fetch mails to %s (from %s)", dt_end, before) return [ item.datetime_sent.timestamp() for item in self._selected_folder.filter( datetime_received__range=(dt_start, dt_end)) ]
def test_super_methods(self): tz = EWSTimeZone('Europe/Copenhagen') self.assertIsInstance(EWSDateTime.now(), EWSDateTime) self.assertIsInstance(EWSDateTime.now(tz=tz), EWSDateTime) self.assertIsInstance(EWSDateTime.utcnow(), EWSDateTime) self.assertIsInstance(EWSDateTime.fromtimestamp(123456789), EWSDateTime) self.assertIsInstance(EWSDateTime.fromtimestamp(123456789, tz=tz), EWSDateTime) self.assertIsInstance(EWSDateTime.utcfromtimestamp(123456789), EWSDateTime)
def test_ewstimezone(self): # Test autogenerated translations tz = EWSTimeZone('Europe/Copenhagen') self.assertIsInstance(tz, EWSTimeZone) self.assertEqual(tz.key, 'Europe/Copenhagen') self.assertEqual(tz.ms_id, 'Romance Standard Time') # self.assertEqual(EWSTimeZone('Europe/Copenhagen').ms_name, '') # EWS works fine without the ms_name # Test localzone() tz = EWSTimeZone.localzone() self.assertIsInstance(tz, EWSTimeZone) # Test common helpers tz = EWSTimeZone('UTC') self.assertIsInstance(tz, EWSTimeZone) self.assertEqual(tz.key, 'UTC') self.assertEqual(tz.ms_id, 'UTC') tz = EWSTimeZone('GMT') self.assertIsInstance(tz, EWSTimeZone) self.assertEqual(tz.key, 'GMT') self.assertEqual(tz.ms_id, 'UTC') # Test mapper contents. Latest map from unicode.org has 394 entries self.assertGreater(len(EWSTimeZone.IANA_TO_MS_MAP), 300) for k, v in EWSTimeZone.IANA_TO_MS_MAP.items(): self.assertIsInstance(k, str) self.assertIsInstance(v, tuple) self.assertEqual(len(v), 2) self.assertIsInstance(v[0], str) # Test timezone unknown by ZoneInfo with self.assertRaises(UnknownTimeZone) as e: EWSTimeZone('UNKNOWN') self.assertEqual(e.exception.args[0], 'No time zone found with key UNKNOWN') # Test timezone known by IANA but with no Winzone mapping with self.assertRaises(UnknownTimeZone) as e: del EWSTimeZone.IANA_TO_MS_MAP['Africa/Tripoli'] EWSTimeZone('Africa/Tripoli') self.assertEqual( e.exception.args[0], 'No Windows timezone name found for timezone "Africa/Tripoli"') # Test __eq__ with non-EWSTimeZone compare self.assertFalse(EWSTimeZone('GMT') == zoneinfo.ZoneInfo('UTC')) # Test from_ms_id() with non-standard MS ID self.assertEqual(EWSTimeZone('Europe/Copenhagen'), EWSTimeZone.from_ms_id('Europe/Copenhagen'))
def test_localize(self): # Test some cornercases around DST tz = EWSTimeZone('Europe/Copenhagen') self.assertEqual( str(tz.localize(EWSDateTime(2023, 10, 29, 2, 36, 0), is_dst=False)), '2023-10-29 02:36:00+01:00') self.assertEqual( str(tz.localize(EWSDateTime(2023, 10, 29, 2, 36, 0), is_dst=None)), '2023-10-29 02:36:00+02:00') self.assertEqual( str(tz.localize(EWSDateTime(2023, 10, 29, 2, 36, 0), is_dst=True)), '2023-10-29 02:36:00+02:00') self.assertEqual( str(tz.localize(EWSDateTime(2023, 3, 26, 2, 36, 0), is_dst=False)), '2023-03-26 02:36:00+01:00') self.assertEqual( str(tz.localize(EWSDateTime(2023, 3, 26, 2, 36, 0), is_dst=None)), '2023-03-26 02:36:00+01:00') self.assertEqual( str(tz.localize(EWSDateTime(2023, 3, 26, 2, 36, 0), is_dst=True)), '2023-03-26 02:36:00+02:00')
def test_ewsdatetime(self): # Test a static timezone tz = EWSTimeZone('Etc/GMT-5') dt = EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=tz) self.assertIsInstance(dt, EWSDateTime) self.assertIsInstance(dt.tzinfo, EWSTimeZone) self.assertEqual(dt.tzinfo.ms_id, tz.ms_id) self.assertEqual(dt.tzinfo.ms_name, tz.ms_name) self.assertEqual(str(dt), '2000-01-02 03:04:05+05:00') self.assertEqual( repr(dt), "EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=EWSTimeZone(key='Etc/GMT-5'))" ) # Test a DST timezone tz = EWSTimeZone('Europe/Copenhagen') dt = EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=tz) self.assertIsInstance(dt, EWSDateTime) self.assertIsInstance(dt.tzinfo, EWSTimeZone) self.assertEqual(dt.tzinfo.ms_id, tz.ms_id) self.assertEqual(dt.tzinfo.ms_name, tz.ms_name) self.assertEqual(str(dt), '2000-01-02 03:04:05+01:00') self.assertEqual( repr(dt), "EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=EWSTimeZone(key='Europe/Copenhagen'))" ) # Test from_string with self.assertRaises(NaiveDateTimeNotAllowed): EWSDateTime.from_string('2000-01-02T03:04:05') self.assertEqual(EWSDateTime.from_string('2000-01-02T03:04:05+01:00'), EWSDateTime(2000, 1, 2, 2, 4, 5, tzinfo=UTC)) self.assertEqual(EWSDateTime.from_string('2000-01-02T03:04:05Z'), EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=UTC)) self.assertIsInstance( EWSDateTime.from_string('2000-01-02T03:04:05+01:00'), EWSDateTime) self.assertIsInstance(EWSDateTime.from_string('2000-01-02T03:04:05Z'), EWSDateTime) # Test addition, subtraction, summertime etc self.assertIsInstance(dt + datetime.timedelta(days=1), EWSDateTime) self.assertIsInstance(dt - datetime.timedelta(days=1), EWSDateTime) self.assertIsInstance(dt - EWSDateTime.now(tz=tz), datetime.timedelta) self.assertIsInstance(EWSDateTime.now(tz=tz), EWSDateTime) # Test various input for from_datetime() self.assertEqual( dt, EWSDateTime.from_datetime( datetime.datetime(2000, 1, 2, 3, 4, 5, tzinfo=EWSTimeZone('Europe/Copenhagen')))) self.assertEqual( dt, EWSDateTime.from_datetime( datetime.datetime( 2000, 1, 2, 3, 4, 5, tzinfo=zoneinfo.ZoneInfo('Europe/Copenhagen')))) self.assertEqual( dt, EWSDateTime.from_datetime( datetime.datetime( 2000, 1, 2, 3, 4, 5, tzinfo=dateutil.tz.gettz('Europe/Copenhagen')))) self.assertEqual( dt, EWSDateTime.from_datetime( datetime.datetime(2000, 1, 2, 3, 4, 5, tzinfo=pytz.timezone('Europe/Copenhagen')))) self.assertEqual(dt.ewsformat(), '2000-01-02T03:04:05+01:00') utc_tz = EWSTimeZone('UTC') self.assertEqual( dt.astimezone(utc_tz).ewsformat(), '2000-01-02T02:04:05Z') # Test summertime dt = EWSDateTime(2000, 8, 2, 3, 4, 5, tzinfo=tz) self.assertEqual( dt.astimezone(utc_tz).ewsformat(), '2000-08-02T01:04:05Z') # Test in-place add and subtract dt = EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=tz) dt += datetime.timedelta(days=1) self.assertIsInstance(dt, EWSDateTime) self.assertEqual(dt, EWSDateTime(2000, 1, 3, 3, 4, 5, tzinfo=tz)) dt = EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=tz) dt -= datetime.timedelta(days=1) self.assertIsInstance(dt, EWSDateTime) self.assertEqual(dt, EWSDateTime(2000, 1, 1, 3, 4, 5, tzinfo=tz)) # Test ewsformat() failure dt = EWSDateTime(2000, 1, 2, 3, 4, 5) with self.assertRaises(ValueError): dt.ewsformat() # Test wrong tzinfo type with self.assertRaises(ValueError): EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=zoneinfo.ZoneInfo('UTC')) with self.assertRaises(ValueError): EWSDateTime.from_datetime(EWSDateTime(2000, 1, 2, 3, 4, 5))
def test_q(self): version = Version(build=EXCHANGE_2007) account = mock_account(version=version, protocol=mock_protocol( version=version, service_endpoint='example.com')) root = Root(account=account) tz = EWSTimeZone('Europe/Copenhagen') start = EWSDateTime(2020, 9, 26, 8, 0, 0, tzinfo=tz) end = EWSDateTime(2020, 9, 26, 11, 0, 0, tzinfo=tz) result = '''\ <m:Restriction xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"> <t:And xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"> <t:Or> <t:Contains ContainmentMode="Substring" ContainmentComparison="Exact"> <t:FieldURI FieldURI="item:Categories"/> <t:Constant Value="FOO"/> </t:Contains> <t:Contains ContainmentMode="Substring" ContainmentComparison="Exact"> <t:FieldURI FieldURI="item:Categories"/> <t:Constant Value="BAR"/> </t:Contains> </t:Or> <t:IsGreaterThan> <t:FieldURI FieldURI="calendar:End"/> <t:FieldURIOrConstant> <t:Constant Value="2020-09-26T08:00:00+02:00"/> </t:FieldURIOrConstant> </t:IsGreaterThan> <t:IsLessThan> <t:FieldURI FieldURI="calendar:Start"/> <t:FieldURIOrConstant> <t:Constant Value="2020-09-26T11:00:00+02:00"/> </t:FieldURIOrConstant> </t:IsLessThan> </t:And> </m:Restriction>''' q = Q(Q(categories__contains='FOO') | Q(categories__contains='BAR'), start__lt=end, end__gt=start) r = Restriction(q, folders=[Calendar(root=root)], applies_to=Restriction.ITEMS) self.assertEqual(str(r), ''.join(s.lstrip() for s in result.split('\n'))) # Test empty Q q = Q() self.assertEqual( q.to_xml(folders=[Calendar()], version=version, applies_to=Restriction.ITEMS), None) with self.assertRaises(ValueError): Restriction(q, folders=[Calendar(root=root)], applies_to=Restriction.ITEMS) # Test validation with self.assertRaises(ValueError): Q(datetime_created__range=(1, )) # Must have exactly 2 args with self.assertRaises(ValueError): Q(datetime_created__range=(1, 2, 3)) # Must have exactly 2 args with self.assertRaises(TypeError): Q(datetime_created=Build(15, 1)).clean( version=Version(build=EXCHANGE_2007)) # Must be serializable with self.assertRaises(ValueError): Q(datetime_created=EWSDateTime(2017, 1, 1)).clean( version=Version(build=EXCHANGE_2007)) # Must be tz-aware with self.assertRaises(ValueError): Q(categories__contains=[[1, 2], [3, 4]]).clean( version=Version(build=EXCHANGE_2007)) # Must be single value
from exchangelib import DELEGATE, Configuration, Account, EWSDateTime, EWSTimeZone, CalendarItem, Credentials, \ FaultTolerance logging.basicConfig(level=logging.WARNING) try: with open(os.path.join(os.path.dirname(__file__), '../settings.yml')) as f: settings = safe_load(f) except FileNotFoundError: print( 'Copy settings.yml.sample to settings.yml and enter values for your test server' ) raise categories = ['perftest'] tz = EWSTimeZone('America/New_York') verify_ssl = settings.get('verify_ssl', True) if not verify_ssl: from exchangelib.protocol import BaseProtocol, NoVerifyHTTPAdapter BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter config = Configuration( server=settings['server'], credentials=Credentials(settings['username'], settings['password']), retry_policy=FaultTolerance(), ) print('Exchange server: %s' % config.service_endpoint) account = Account(config=config, primary_smtp_address=settings['account'],
mocker.patch.object(ExpandGroup, "__init__", return_value=None) mocker.patch.object(ExpandGroup, "call", return_value=raw_response) client = self.MockClient() res = get_expanded_group( client, email_address="*****@*****.**" ) actual_ec = res[1] assert expected == actual_ec MESSAGES = [ Message(subject='message1', message_id='message1', text_body='Hello World', body='message1', datetime_received=EWSDateTime(2021, 7, 14, 13, 00, 00, tzinfo=EWSTimeZone(key='UTC')), datetime_sent=EWSDateTime(2021, 7, 14, 13, 00, 00, tzinfo=EWSTimeZone(key='UTC')), datetime_created=EWSDateTime(2021, 7, 14, 13, 00, 00, tzinfo=EWSTimeZone(key='UTC')) ), Message(subject='message2', message_id='message2', text_body='Hello World', body='message2', datetime_received=EWSDateTime(2021, 7, 14, 13, 9, 00, tzinfo=EWSTimeZone(key='UTC')), datetime_sent=EWSDateTime(2021, 7, 14, 13, 9, 00, tzinfo=EWSTimeZone(key='UTC')), datetime_created=EWSDateTime(2021, 7, 14, 13, 9, 00, tzinfo=EWSTimeZone(key='UTC')) ), Message(subject='message3', message_id='message3', text_body='Hello World', body='message3',
break else: if "max_timeout" in command.keys(): __max_timeout__ = command["max_timeout"] print("Starting extraction of data from {}".format( command["email"])) conn = connect(**command) root = osjoin(command["path_output"], "data") try: makedirs(root, mode=0o777) except FileExistsError: pass if 'timezone' in command.keys(): local_time = EWSTimeZone.localzone() if command['timezone'].lower() == 'local' \ else EWSTimeZone.timezone(command['timezone'].lower()) else: local_time = EWSTimeZone() for f in conn.root.walk(): handle_folder(f, root) print("Time taken:" + str(datetime.now() - start_time)) exit(0) print("Time taken:" + str(datetime.now() - start_time)) exit(-1) else: print(usage) print("Time taken:" + str(datetime.now() - start_time)) exit(-1)