Пример #1
0
    def test_ewsdatetime(self):
        tz = EWSTimeZone.timezone('Europe/Copenhagen')
        self.assertIsInstance(tz, EWSTimeZone)
        self.assertEqual(tz.ms_id, 'Romance Standard Time')
        self.assertEqual(tz.ms_name, '(UTC+01:00) Brussels, Copenhagen, Madrid, Paris')

        dt = tz.localize(EWSDateTime(2000, 1, 2, 3, 4, 5))
        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=<DstTzInfo 'Europe/Copenhagen' CET+1:00:00 STD>)"
        )
        self.assertIsInstance(dt + timedelta(days=1), EWSDateTime)
        self.assertIsInstance(dt - timedelta(days=1), EWSDateTime)
        self.assertIsInstance(dt - EWSDateTime.now(tz=tz), timedelta)
        self.assertIsInstance(EWSDateTime.now(tz=tz), EWSDateTime)
        self.assertEqual(dt, EWSDateTime.from_datetime(tz.localize(datetime(2000, 1, 2, 3, 4, 5))))
        self.assertEqual(dt.ewsformat(), '2000-01-02T03:04:05')
        utc_tz = EWSTimeZone.timezone('UTC')
        self.assertEqual(dt.astimezone(utc_tz).ewsformat(), '2000-01-02T02:04:05Z')
        # Test summertime
        dt = tz.localize(EWSDateTime(2000, 8, 2, 3, 4, 5))
        self.assertEqual(dt.astimezone(utc_tz).ewsformat(), '2000-08-02T01:04:05Z')
def initEventStorage():
    # Open sqlite database, up to now it is used to store calendarNames / Outlook categories and Mattermost groups in which calendar events should be posted.
    # The calendar events are stored in an Outlook calendar and also in the sqlite database up to now.
    try: 
        conn = sqlite3.connect(calendarSettings['DatabaseName'])
        cursor=conn.cursor()
    except Exception as e:
        print ("Could not open sqlite database due to following exception:\n {0} \n {1}".format(e.__doc__, e.message))

    # Open outlook calendar
    try:
        config = Configuration(username=outlookSettings['Username'], password=outlookSettings['Password'])
        account = Account(primary_smtp_address=outlookSettings['Email'], config=config, autodiscover=True, access_type=DELEGATE)
    except Exception as e:
        print ("Could not open Outlook calendar due to following exception:\n {0} \n {1}".format(e.__doc__, e.message))

    # Set timezone needed later, note: only Copenhagen is mapped but it is the same timezone as Berlin
    tz = EWSTimeZone.timezone('Europe/Copenhagen')

    # Create table which contains subcalendars
    # calendarName: Name which is refered to add an event, calendarMattermostGroup: group in which events should be published
    # calendarName is rewritten in an Outlook calendar category to be stored in Outlook calendar
    try:
        createCalendarTable = "CREATE TABLE IF NOT EXISTS 'calendarTable' (id INTEGER PRIMARY KEY AUTOINCREMENT, calendarName TEXT, calendarMattermostGroup TEXT)"
        conn.execute(createCalendarTable)
    except Exception as e:
        print ("Could not access / create sqlite calendar due to following exception:\n {0} \n {1}".format(e.__doc__, e.message))

    return conn, cursor, tz, account
Пример #3
0
    def setUpClass(cls):
        # There's no official Exchange server we can test against, and we can't really provide credentials for our
        # own test server to everyone on the Internet. Travis-CI uses the encrypted settings.yml.enc for testing.
        #
        # If you want to test against your own server and account, create your own settings.yml with credentials for
        # that server. 'settings.yml.sample' is provided as a template.
        try:
            with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'settings.yml')) as f:
                settings = safe_load(f)
        except FileNotFoundError:
            print('Skipping %s - no settings.yml file found' % cls.__name__)
            print('Copy settings.yml.sample to settings.yml and enter values for your test server')
            raise unittest.SkipTest('Skipping %s - no settings.yml file found' % cls.__name__)

        cls.verify_ssl = settings.get('verify_ssl', True)
        if not cls.verify_ssl:
            # Allow unverified TLS if requested in settings file
            BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter

        # Speed up tests a bit. We don't need to wait 10 seconds for every nonexisting server in the discover dance
        AutodiscoverProtocol.TIMEOUT = 2

        # Create an account shared by all tests
        tz = EWSTimeZone.timezone('Europe/Copenhagen')
        cls.retry_policy = FaultTolerance(max_wait=600)
        config = Configuration(
            server=settings['server'],
            credentials=Credentials(settings['username'], settings['password']),
            retry_policy=cls.retry_policy,
        )
        cls.account = Account(primary_smtp_address=settings['account'], access_type=DELEGATE, config=config,
                              locale='da_DK', default_timezone=tz)
Пример #4
0
    def test_from_params(self):
        tz = EWSTimeZone.timezone('Europe/Copenhagen')
        start = tz.localize(EWSDateTime(1900, 9, 26, 8, 0, 0))
        end = tz.localize(EWSDateTime(2200, 9, 26, 11, 0, 0))
        xml = Restriction.from_params(start=start, end=end, categories=['FOO', 'BAR'])
        result = '''\
<m:Restriction>
    <t:And>
        <t:IsGreaterThan>
            <t:FieldURI FieldURI="calendar:End" />
            <t:FieldURIOrConstant>
                <t:Constant Value="1900-09-26T07:10:00Z" />
            </t:FieldURIOrConstant>
        </t:IsGreaterThan>
        <t:IsLessThan>
            <t:FieldURI FieldURI="calendar:Start" />
            <t:FieldURIOrConstant>
                <t:Constant Value="2200-09-26T10:00:00Z" />
            </t:FieldURIOrConstant>
        </t:IsLessThan>
        <t:Or>
            <t:Contains ContainmentComparison="Exact" ContainmentMode="Substring">
                <t:FieldURI FieldURI="item:Categories" />
                <t:Constant Value="FOO" />
            </t:Contains>
            <t:Contains ContainmentComparison="Exact" ContainmentMode="Substring">
                <t:FieldURI FieldURI="item:Categories" />
                <t:Constant Value="BAR" />
            </t:Contains>
        </t:Or>
    </t:And>
</m:Restriction>'''
        self.assertEqual(str(xml), ''.join(l.lstrip() for l in result.split('\n')))
Пример #5
0
    def test_task_validation(self):
        tz = EWSTimeZone.timezone('Europe/Copenhagen')
        task = Task(due_date=tz.localize(EWSDateTime(2017, 1, 1)),
                    start_date=tz.localize(EWSDateTime(2017, 2, 1)))
        task.clean()
        # We reset due date if it's before start date
        self.assertEqual(task.due_date, tz.localize(EWSDateTime(2017, 2, 1)))
        self.assertEqual(task.due_date, task.start_date)

        task = Task(complete_date=tz.localize(EWSDateTime(2099, 1, 1)),
                    status=Task.NOT_STARTED)
        task.clean()
        # We reset status if complete_date is set
        self.assertEqual(task.status, Task.COMPLETED)
        # We also reset complete date to now() if it's in the future
        self.assertEqual(task.complete_date.date(), UTC_NOW().date())

        task = Task(complete_date=tz.localize(EWSDateTime(2017, 1, 1)),
                    start_date=tz.localize(EWSDateTime(2017, 2, 1)))
        task.clean()
        # We also reset complete date to start_date if it's before start_date
        self.assertEqual(task.complete_date, task.start_date)

        task = Task(percent_complete=Decimal('50.0'), status=Task.COMPLETED)
        task.clean()
        # We reset percent_complete to 100.0 if state is completed
        self.assertEqual(task.percent_complete, Decimal(100))

        task = Task(percent_complete=Decimal('50.0'), status=Task.NOT_STARTED)
        task.clean()
        # We reset percent_complete to 0.0 if state is not_started
        self.assertEqual(task.percent_complete, Decimal(0))
Пример #6
0
 def setUp(self):
     self.tz = EWSTimeZone.timezone('Europe/Copenhagen')
     try:
         with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'settings.yml')) as f:
             settings = load(f)
     except FileNotFoundError:
         print('Copy settings.yml.sample to settings.yml and enter values for your test server')
         raise
     self.categories = ['Test']
     self.config = Configuration(server=settings['server'], username=settings['username'],
                                 password=settings['password'])
     self.account = Account(primary_smtp_address=settings['account'], access_type=DELEGATE, config=self.config)
Пример #7
0
 def setUp(self):
     # There's no official Exchange server we can test against, and we can't really provide credentials for our
     # own test server to anyone on the Internet. You need to create your own settings.yml with credentials for
     # your own test server. 'settings.yml.sample' is provided as a template.
     try:
         with open(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'settings.yml')) as f:
             settings = load(f)
     except FileNotFoundError:
         print('Copy settings.yml.sample to settings.yml and enter values for your test server')
         raise
     self.tz = EWSTimeZone.timezone('Europe/Copenhagen')
     self.categories = ['Test']
     self.config = Configuration(server=settings['server'], username=settings['username'],
                                 password=settings['password'], verify_ssl=settings['verify_ssl'])
     self.account = Account(primary_smtp_address=settings['account'], access_type=DELEGATE, config=self.config)
     self.maxDiff = None
Пример #8
0
def initEventStorage():
    # Open sqlite database, up to now it is used to store calendarNames / Outlook categories and Mattermost groups in which calendar events should be posted.
    # The calendar events are stored in an Outlook calendar and also in the sqlite database up to now.
    try:
        conn = sqlite3.connect(calendarSettings['DatabaseName'])
        cursor = conn.cursor()
    except Exception as e:
        print(
            "Could not open sqlite database due to following exception:\n {0} \n {1}"
            .format(e.__doc__, e.message))

    # Open outlook calendar
    try:
        config = Configuration(username=outlookSettings['Username'],
                               password=outlookSettings['Password'])
        account = Account(primary_smtp_address=outlookSettings['Email'],
                          config=config,
                          autodiscover=True,
                          access_type=DELEGATE)
    except Exception as e:
        print(
            "Could not open Outlook calendar due to following exception:\n {0} \n {1}"
            .format(e.__doc__, e.message))

    # Set timezone needed later, note: only Copenhagen is mapped but it is the same timezone as Berlin
    tz = EWSTimeZone.timezone('Europe/Copenhagen')

    # Create table which contains subcalendars
    # calendarName: Name which is refered to add an event, calendarMattermostGroup: group in which events should be published
    # calendarName is rewritten in an Outlook calendar category to be stored in Outlook calendar
    try:
        createCalendarTable = "CREATE TABLE IF NOT EXISTS 'calendarTable' (id INTEGER PRIMARY KEY AUTOINCREMENT, calendarName TEXT, calendarMattermostGroup TEXT)"
        conn.execute(createCalendarTable)
    except Exception as e:
        print(
            "Could not access / create sqlite calendar due to following exception:\n {0} \n {1}"
            .format(e.__doc__, e.message))

    return conn, cursor, tz, account
Пример #9
0
 def random_val(self, field):
     if isinstance(field, ExtendedPropertyField):
         if field.value_cls.property_type == 'StringArray':
             return [
                 get_random_string(255) for _ in range(random.randint(1, 4))
             ]
         if field.value_cls.property_type == 'IntegerArray':
             return [
                 get_random_int(0, 256) for _ in range(random.randint(1, 4))
             ]
         if field.value_cls.property_type == 'BinaryArray':
             return [
                 get_random_string(255).encode()
                 for _ in range(random.randint(1, 4))
             ]
         if field.value_cls.property_type == 'String':
             return get_random_string(255)
         if field.value_cls.property_type == 'Integer':
             return get_random_int(0, 256)
         if field.value_cls.property_type == 'Binary':
             # In the test_extended_distinguished_property test, EWS rull return 4 NULL bytes after char 16 if we
             # send a longer bytes sequence.
             return get_random_string(16).encode()
         raise ValueError('Unsupported field %s' % field)
     if isinstance(field, URIField):
         return get_random_url()
     if isinstance(field, EmailAddressField):
         return get_random_email()
     if isinstance(field, ChoiceField):
         return get_random_choice(
             field.supported_choices(version=self.account.version))
     if isinstance(field, CultureField):
         return get_random_choice([
             'da-DK', 'de-DE', 'en-US', 'es-ES', 'fr-CA', 'nl-NL', 'ru-RU',
             'sv-SE'
         ])
     if isinstance(field, BodyField):
         return get_random_string(400)
     if isinstance(field, CharListField):
         return [get_random_string(16) for _ in range(random.randint(1, 4))]
     if isinstance(field, TextListField):
         return [
             get_random_string(400) for _ in range(random.randint(1, 4))
         ]
     if isinstance(field, CharField):
         return get_random_string(field.max_length)
     if isinstance(field, TextField):
         return get_random_string(400)
     if isinstance(field, MimeContentField):
         return get_random_string(400)
     if isinstance(field, Base64Field):
         return get_random_bytes(400)
     if isinstance(field, BooleanField):
         return get_random_bool()
     if isinstance(field, DecimalField):
         return get_random_decimal(field.min or 1, field.max or 99)
     if isinstance(field, IntegerField):
         return get_random_int(field.min or 0, field.max or 256)
     if isinstance(field, DateTimeField):
         return get_random_datetime(tz=self.account.default_timezone)
     if isinstance(field, AttachmentField):
         return [
             FileAttachment(name='my_file.txt',
                            content=get_random_bytes(400))
         ]
     if isinstance(field, MailboxListField):
         # email_address must be a real account on the server(?)
         # TODO: Mailbox has multiple optional args but vals must match server account, so we can't easily test
         if get_random_bool():
             return [
                 Mailbox(email_address=self.account.primary_smtp_address)
             ]
         else:
             return [self.account.primary_smtp_address]
     if isinstance(field, MailboxField):
         # email_address must be a real account on the server(?)
         # TODO: Mailbox has multiple optional args but vals must match server account, so we can't easily test
         if get_random_bool():
             return Mailbox(email_address=self.account.primary_smtp_address)
         else:
             return self.account.primary_smtp_address
     if isinstance(field, AttendeesField):
         # Attendee must refer to a real mailbox on the server(?). We're only sure to have one
         if get_random_bool():
             mbx = Mailbox(email_address=self.account.primary_smtp_address)
         else:
             mbx = self.account.primary_smtp_address
         with_last_response_time = get_random_bool()
         if with_last_response_time:
             return [
                 Attendee(mailbox=mbx,
                          response_type='Accept',
                          last_response_time=get_random_datetime(
                              tz=self.account.default_timezone))
             ]
         else:
             if get_random_bool():
                 return [Attendee(mailbox=mbx, response_type='Accept')]
             else:
                 return [self.account.primary_smtp_address]
     if isinstance(field, EmailAddressesField):
         addrs = []
         for label in EmailAddress.get_field_by_fieldname(
                 'label').supported_choices(version=self.account.version):
             addr = EmailAddress(email=get_random_email())
             addr.label = label
             addrs.append(addr)
         return addrs
     if isinstance(field, PhysicalAddressField):
         addrs = []
         for label in PhysicalAddress.get_field_by_fieldname('label')\
                 .supported_choices(version=self.account.version):
             addr = PhysicalAddress(street=get_random_string(32),
                                    city=get_random_string(32),
                                    state=get_random_string(32),
                                    country=get_random_string(32),
                                    zipcode=get_random_string(8))
             addr.label = label
             addrs.append(addr)
         return addrs
     if isinstance(field, PhoneNumberField):
         pns = []
         for label in PhoneNumber.get_field_by_fieldname(
                 'label').supported_choices(version=self.account.version):
             pn = PhoneNumber(phone_number=get_random_string(16))
             pn.label = label
             pns.append(pn)
         return pns
     if isinstance(field, EWSElementField):
         if field.value_cls == Recurrence:
             return Recurrence(pattern=DailyPattern(interval=5),
                               start=get_random_date(),
                               number=7)
     if isinstance(field, TimeZoneField):
         while True:
             try:
                 return EWSTimeZone.timezone(
                     random.choice(pytz.all_timezones))
             except UnknownTimeZone:
                 pass
     if isinstance(field, PermissionSetField):
         return PermissionSet(permissions=[
             Permission(user_id=UserId(
                 primary_smtp_address=self.account.primary_smtp_address), )
         ])
     raise ValueError('Unknown field %s' % field)
Пример #10
0
from exchangelib.configuration import Configuration
from exchangelib.account import Account
from exchangelib.ewsdatetime import EWSDateTime, EWSTimeZone
from exchangelib.folders import CalendarItem

logging.basicConfig(level=logging.WARNING)

try:
    with open(os.path.join(os.path.dirname(__file__), 'settings.yml')) as f:
        settings = load(f)
except FileNotFoundError:
    print('Copy settings.yml.sample to settings.yml and enter values for your test server')
    raise

categories = ['perftest']
tz = EWSTimeZone.timezone('Europe/Copenhagen')

config = Configuration(server=settings['server'], username=settings['username'], password=settings['password'])
print(('Exchange server: %s' % config.protocol.server))

account = Account(config=config, primary_smtp_address=settings['account'], access_type=DELEGATE)
cal = account.calendar


# Calendar item generator
def calitems():
    i = 0
    start = tz.localize(EWSDateTime(2000, 3, 1, 8, 30, 0))
    end = tz.localize(EWSDateTime(2000, 3, 1, 9, 15, 0))
    item = CalendarItem(
        item_id='',
Пример #11
0
# Disable insecure SSL warnings
warnings.filterwarnings("ignore")

# Use notify-send for email notifications and zenity for calendar notifications
notify = sh.Command('/usr/bin/notify-send')
zenity = sh.Command('/usr/bin/zenity')

# Get the local timezone
timedatectl = sh.Command('/usr/bin/timedatectl')
for l in timedatectl():
    if 'Timezone' in l:
        tz_name = l.split()[1]
        break
else:
    raise ValueError('Timezone not found')
tz = EWSTimeZone.timezone(tz_name)

sleep = int(sys.argv[1])  # 1st arg to this script is the number of seconds to look back in the inbox
now = UTC_NOW()
emails_since = now - timedelta(seconds=sleep)
cal_items_before = now + timedelta(seconds=sleep * 4)  # Longer notice of upcoming appointments than new emails
username, _, password = netrc().authenticators('office365')
c = Credentials(username, password, is_service_account=False)
a = Account(primary_smtp_address=c.username, credentials=c, access_type=DELEGATE, autodiscover=True, verify_ssl=False)

for msg in a.calendar.view(start=now, end=cal_items_before)\
        .only('start', 'end', 'subject', 'location')\
        .order_by('start', 'end'):
    if msg.start < now:
        continue
    minutes_to_appointment = int((msg.start - now).total_seconds() / 60)
Пример #12
0
from exchangelib.configuration import Configuration
from exchangelib.account import Account
from exchangelib.ewsdatetime import EWSDateTime, EWSTimeZone
from exchangelib.folders import CalendarItem

logging.basicConfig(level=logging.WARNING)

try:
    with open(os.path.join(os.path.dirname(__file__), 'settings.yml')) as f:
        settings = load(f)
except FileNotFoundError:
    print('Copy settings.yml.sample to settings.yml and enter values for your test server')
    raise

categories = ['foobar', 'perftest']
tz = EWSTimeZone.timezone('US/Pacific')

t0 = datetime.now()

config = Configuration(server=settings['server'], username=settings['username'], password=settings['password'],
                       verify_ssl=False)
print(('Exchange server: %s' % config.protocol.server))

account = Account(config=config, primary_smtp_address=settings['account'], access_type=DELEGATE)
cal = account.calendar

t1 = datetime.now()
print(('Time to build ExchangeServer object: %s' % (t1 - t0)))

year = 2012
month = 3