def outlook_calendar_event_exists(appointment, calendar_service, summary):
    ews_tz = EWSTimeZone.timezone('America/Chicago')

    d = appointment.start_time.datetime
    start_date_time = datetime(d.year, d.month, d.day, d.hour, d.minute, d.second, d.microsecond, ews_tz)
    start_ews_date_time = EWSDateTime.from_datetime(start_date_time)

    d = appointment.end_time.datetime
    end_date_time = datetime(d.year, d.month, d.day, d.hour, d.minute, d.second, d.microsecond, ews_tz)
    end_ews_date_time = EWSDateTime.from_datetime(end_date_time)

    matching_events = calendar_service.calendar.find_items(
        start=start_ews_date_time,
        end=end_ews_date_time,
        shape=AllProperties)

    if matching_events:
        for event in matching_events:
            if event.subject == summary:
                print(
                    "Found a matching Outlook calendar event for appointment {app}. Will not create a new one.".format(
                        app=appointment))
                return True

    return False
Esempio n. 2
0
    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))
        ]
Esempio n. 3
0
 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')
Esempio n. 4
0
    def addAgendaSubmit(self):

        fromDate = self.ui_addAgenda.agndFromDateInput.date()
        fromTime = self.ui_addAgenda.agndFromTimeInput.time()
        toDate = self.ui_addAgenda.agndToDateInput.date()
        toTime = self.ui_addAgenda.agndToTimeInput.time()

        fromDatetime = QDateTime(fromDate, fromTime, timeSpec=Qt.LocalTime)
        toDatetime = QDateTime(toDate, toTime, timeSpec=Qt.LocalTime)

        localTimeZone = EWSTimeZone.localzone()
        fromEWSDatetime = EWSDateTime.from_datetime(
            fromDatetime.toPyDateTime())
        toEWSDatetime = EWSDateTime.from_datetime(toDatetime.toPyDateTime())

        fromDT = fromEWSDatetime.astimezone(tz=localTimeZone)
        toDT = toEWSDatetime.astimezone(tz=localTimeZone)

        location = self.ui_addAgenda.agndPosInput.text()
        subject = self.ui_addAgenda.agndSubjectInput.text()
        detail = self.ui_addAgenda.agndDetailInput.toPlainText()
        reminderEnable = self.ui_addAgenda.agndAlarmEnableCheck.isChecked()
        reminder = self.ui_addAgenda.agndAlarmInput.value()
        self.timerRoutine.exchAccount.login()
        self.timerRoutine.exchAccount.addAgenda(fromDT, toDT, location,
                                                subject, detail,
                                                reminderEnable, reminder)

        self.addAgendaDialog.close()
        self.listDialog.show()
        self.timerRoutine.unrdAutoUpdateTimerStart()
        self.timerRoutine.timer2.start()
Esempio n. 5
0
def calendarIteration():
    global meetingList, busyTimes, busyTimesFlat, account, tz, year, month, day
    dst = time.localtime().tm_isdst
    calendarItems = []
    now = datetime.datetime.now()
    day, month, year = now.day, now.month, now.year
    tz = EWSTimeZone.timezone('Europe/Oslo')
    credentials = Credentials(username=config['username'], password=config['password'])
    account = Account(config['account'], credentials=credentials, autodiscover=True)
    items = account.calendar.view(
        start=tz.localize(EWSDateTime(year, month, day)),
        end=tz.localize(EWSDateTime(year, month, day)) + datetime.timedelta(days=1),
        )
    if dst == 0:
        for item in items:
            today_events = [item.start + datetime.timedelta(hours=1), item.end + datetime.timedelta(hours=1), item.organizer]
            calendarItems.append(today_events)
    else:
        for item in items:
            today_events = [item.start + datetime.timedelta(hours=2), item.end + datetime.timedelta(hours=2), item.organizer]
            calendarItems.append(today_events)
    meetingList = []
    busyTimes = []
    busyTimesFlat = []
    counter = 0
    for events in calendarItems:
        tempDict = {'start':str(calendarItems[counter][0]), 'end':str(calendarItems[counter][1]), 'title':calendarItems[counter][2].name}
        busyTimes = busyTimes+[list(range(int(tempDict['start'][11:16].replace(':','')),(int(tempDict['end'][11:16].replace(':','')))+1))]
        busyTimesFlat = [item for sublist in busyTimes for item in sublist]
        meetingList.append(tempDict)
        counter += 1
    with open('web/events.json', 'w') as f:
        f.write(json.dumps(meetingList))
        f.close()
def outlook_calendar_event_exists(appointment, calendar_service, summary):
    ews_tz = EWSTimeZone.timezone('America/Chicago')

    d = appointment.start_time.datetime
    start_date_time = datetime(d.year, d.month, d.day, d.hour, d.minute,
                               d.second, d.microsecond, ews_tz)
    start_ews_date_time = EWSDateTime.from_datetime(start_date_time)

    d = appointment.end_time.datetime
    end_date_time = datetime(d.year, d.month, d.day, d.hour, d.minute,
                             d.second, d.microsecond, ews_tz)
    end_ews_date_time = EWSDateTime.from_datetime(end_date_time)

    matching_events = calendar_service.calendar.find_items(
        start=start_ews_date_time, end=end_ews_date_time, shape=AllProperties)

    if matching_events:
        for event in matching_events:
            if event.subject == summary:
                print(
                    "Found a matching Outlook calendar event for appointment {app}. Will not create a new one."
                    .format(app=appointment))
                return True

    return False
Esempio n. 7
0
    def get_email_list(self, send_time_gte, subject_like=None, sender=None):
        """

        :param send_time_gte: must be specified
        :param subject_like: if None, it means no restrictions
        :param sender: if None, it means no restrictions
        :return: list type
        """
        tz = EWSTimeZone.timezone("Asia/Shanghai")
        email_list = []
        send_time_gte = datetime.datetime.strptime(send_time_gte, "%Y-%m-%d")
        inbox = self.account.inbox.filter(datetime_sent__gte=tz.localize(
            EWSDateTime(send_time_gte.year, send_time_gte.month,
                        send_time_gte.day)))

        for item in inbox.all().order_by("-datetime_sent"):
            subject = item.subject
            if not item.sender:
                continue
            sender_name = item.sender.name
            send_time = (
                item.datetime_sent +
                datetime.timedelta(hours=8)).strftime("%Y-%m-%d %H:%M:%S")
            b1 = (True if not subject_like
                  or subject_like.lower() in subject.lower() else False)
            b2 = True if not sender or sender.lower() in sender_name.lower(
            ) else False

            if b1 and b2:
                email_list.append([subject, sender_name, send_time])
        print("get {} email(s) in total".format(len(email_list)))
        return email_list
Esempio n. 8
0
    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)
Esempio n. 9
0
    def test_garbage_input(self):
        # Test that we can survive garbage input for common field types
        tz = EWSTimeZone.timezone('Europe/Copenhagen')
        account = namedtuple('Account', ['default_timezone'])(default_timezone=tz)
        payload = b'''\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
        <t:Foo>THIS_IS_GARBAGE</t:Foo>
    </t:Item>
</Envelope>'''
        elem = to_xml(payload).find('{%s}Item' % TNS)
        for field_cls in (Base64Field, BooleanField, IntegerField, DateField, DateTimeField, DecimalField):
            field = field_cls('foo', field_uri='item:Foo', is_required=True, default='DUMMY')
            self.assertEqual(field.from_xml(elem=elem, account=account), None)

        # Test MS timezones
        payload = b'''\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
        <t:Foo Id="THIS_IS_GARBAGE"></t:Foo>
    </t:Item>
</Envelope>'''
        elem = to_xml(payload).find('{%s}Item' % TNS)
        field = TimeZoneField('foo', field_uri='item:Foo', default='DUMMY')
        self.assertEqual(field.from_xml(elem=elem, account=account), None)
    def create_meeting(self, username, start_time, end_time, subject, body,
                       required_attendees, optional_attendees):
        """Create a meeting object"""
        account = self.connect_to_account(
            username, impersonation=(username != self.email))

        if required_attendees:
            required_attendees = [
                ra.strip() for ra in required_attendees.split(',')
            ]
        if optional_attendees:
            optional_attendees = [
                oa.strip() for oa in optional_attendees.split(',')
            ]

        tz = EWSTimeZone.timezone('Etc/GMT')

        meeting = CalendarItem(
            account=account,
            folder=account.calendar,
            start=EWSDateTime.from_datetime(
                datetime.datetime.fromtimestamp(start_time / 1000, tz=tz)),
            end=EWSDateTime.from_datetime(
                datetime.datetime.fromtimestamp(end_time / 1000, tz=tz)),
            subject=subject,
            body=body,
            required_attendees=required_attendees,
            optional_attendees=optional_attendees)
        return meeting
Esempio n. 11
0
def get_exchange_events(server: str, domain: Optional[str], username: str,
                        password: str, range_start: datetime,
                        range_end: datetime) -> List[CalendarEvent]:
    """Connect to exchange calendar server and get events within range."""
    # load exchange module if necessary
    from exchangelib import Credentials, Configuration, Account, DELEGATE
    from exchangelib import EWSDateTime, EWSTimeZone

    # setup access
    full_username = r'{}\{}'.format(domain, username) if domain else username
    account = Account(primary_smtp_address=username,
                      config=Configuration(server=server,
                                           credentials=Credentials(
                                               full_username, password)),
                      autodiscover=False,
                      access_type=DELEGATE)

    # collect event information within given time range
    events: List[CalendarEvent] = []
    localzone = EWSTimeZone.localzone()
    local_start = localzone.localize(EWSDateTime.from_datetime(range_start))
    local_end = localzone.localize(EWSDateTime.from_datetime(range_end))
    for item in account.calendar.filter(  ##pylint: disable=no-member
            start__range=(local_start, local_end)).order_by('start'):
        events.append(
            CalendarEvent(title=item.subject,
                          start=item.start,
                          end=item.end,
                          duration=(item.end - item.start).seconds / 3600,
                          categories=item.categories))
    return events
Esempio n. 12
0
    def test_q(self):
        tz = EWSTimeZone.timezone('Europe/Copenhagen')
        start = tz.localize(EWSDateTime(1950, 9, 26, 8, 0, 0))
        end = tz.localize(EWSDateTime(2050, 9, 26, 11, 0, 0))
        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="1950-09-26T08:00:00+01:00"/>
            </t:FieldURIOrConstant>
        </t:IsGreaterThan>
        <t:IsLessThan>
            <t:FieldURI FieldURI="calendar:Start"/>
            <t:FieldURIOrConstant>
                <t:Constant Value="2050-09-26T11:00:00+01: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()], applies_to=Restriction.ITEMS)
        self.assertEqual(str(r),
                         ''.join(l.lstrip() for l in result.split('\n')))
        # Test empty Q
        q = Q()
        self.assertEqual(
            q.to_xml(folders=[Calendar()],
                     version=None,
                     applies_to=Restriction.ITEMS), None)
        with self.assertRaises(ValueError):
            Restriction(q, folders=[Calendar()], 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()  # Must be serializable
        with self.assertRaises(ValueError):
            Q(datetime_created=EWSDateTime(2017, 1,
                                           1)).clean()  # Must be tz-aware date
        with self.assertRaises(ValueError):
            Q(categories__contains=[[1, 2], [3, 4]
                                    ]).clean()  # Must be single value
Esempio n. 13
0
    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'))
Esempio n. 14
0
 def __init__(self, domain, user, password, mail_server):
     self.domain = domain
     self.user = user
     self.password = password
     self.mail_server = mail_server
     self.tz = EWSTimeZone.timezone('UTC')
     self.account = None
     self.history = []
     self.modules = loadModules("mail_events")
Esempio n. 15
0
    def test_naive_datetime(self):
        # Test that we can survive naive datetimes on a datetime field
        tz = EWSTimeZone.timezone('Europe/Copenhagen')
        account = namedtuple('Account',
                             ['default_timezone'])(default_timezone=tz)
        default_value = tz.localize(EWSDateTime(2017, 1, 2, 3, 4))
        field = DateTimeField('foo',
                              field_uri='item:DateTimeSent',
                              default=default_value)

        # TZ-aware datetime string
        payload = b'''\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
        <t:DateTimeSent>2017-06-21T18:40:02Z</t:DateTimeSent>
    </t:Item>
</Envelope>'''
        elem = to_xml(payload).find('{%s}Item' % TNS)
        self.assertEqual(field.from_xml(elem=elem, account=account),
                         UTC.localize(EWSDateTime(2017, 6, 21, 18, 40, 2)))

        # Naive datetime string is localized to tz of the account
        payload = b'''\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
        <t:DateTimeSent>2017-06-21T18:40:02</t:DateTimeSent>
    </t:Item>
</Envelope>'''
        elem = to_xml(payload).find('{%s}Item' % TNS)
        self.assertEqual(field.from_xml(elem=elem, account=account),
                         tz.localize(EWSDateTime(2017, 6, 21, 18, 40, 2)))

        # Garbage string returns None
        payload = b'''\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
        <t:DateTimeSent>THIS_IS_GARBAGE</t:DateTimeSent>
    </t:Item>
</Envelope>'''
        elem = to_xml(payload).find('{%s}Item' % TNS)
        self.assertEqual(field.from_xml(elem=elem, account=account), None)

        # Element not found returns default value
        payload = b'''\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
    </t:Item>
</Envelope>'''
        elem = to_xml(payload).find('{%s}Item' % TNS)
        self.assertEqual(field.from_xml(elem=elem, account=account),
                         default_value)
Esempio n. 16
0
    def get_calendar_time(self, date_time):
        """Return a string date and time in Exchangelib format."""

        # Set timezone
        self._tz = EWSTimeZone.timezone('Europe/Stockholm')
        self._calendar_time = parser.parse(date_time)

        return self._tz.localize(
            EWSDateTime(self._calendar_time.year, self._calendar_time.month,
                        self._calendar_time.day, self._calendar_time.hour,
                        self._calendar_time.minute))
Esempio n. 17
0
 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)
Esempio n. 18
0
def ToEWSDateTime(_datetime):
    tz = EWSTimeZone.timezone('Europe/Helsinki')
    time = tz.localize(
        EWSDateTime(
            year=_datetime.year,
            month=_datetime.month,
            day=_datetime.day,
            hour=_datetime.hour,
            minute=_datetime.minute
        )
    )
    return time
def main():
    config_file_path = os.path.join(
        os.path.dirname(os.path.realpath(__file__)),
        'exchange-calendar-to-org.cfg')

    config = configparser.ConfigParser()
    config.read(config_file_path)

    email = config.get('Settings', 'email')
    try:
        server_url = config.get('Settings', 'server_url')
    except configparser.NoOptionError:
        server_url = None
    password = config.get('Settings', 'password')
    sync_days = int(config.get('Settings', 'sync_days'))
    org_file_path = config.get('Settings', 'org_file')
    tz_string = config.get('Settings', 'timezone_string')
    sslverify = config.getboolean('Settings', 'verify_ssl')

    tz = EWSTimeZone.timezone(tz_string)

    credentials = Credentials(username=email, password=password)

    if server_url is None:
        account = Account(
            primary_smtp_address=email,
            credentials=credentials,
            autodiscover=True,
            access_type=DELEGATE)
    else:
        server = Configuration(server=server_url, credentials=credentials, verify_ssl=sslverify)
        account = Account(
            primary_smtp_address=email,
            config=server,
            autodiscover=False,
            access_type=DELEGATE)

    now = datetime.datetime.now()
    end = now + datetime.timedelta(days=sync_days)

    items = account.calendar.filter(
        start__lt=tz.localize(EWSDateTime(end.year, end.month, end.day)),
        end__gt=tz.localize(EWSDateTime(now.year, now.month, now.day)), )

    text = []
    text.append('* Calendar')
    text.append('\n')
    for item in items:
        text.append(get_item_text(item, tz))
        text.append('\n')

    f = open(org_file_path, 'w')
    f.write(''.join(text))
Esempio n. 20
0
def main():

    exchAcc = ExchAccount('eas.outlook.com','******@outlook.com','********')
    exchAcc.login()
    localTimeZone = EWSTimeZone.localzone()
    nowDateTime = EWSDateTime.now(tz=localTimeZone)
    # print(EWSDateTime.now(tz=localTimeZone))
    items = exchAcc.account.calendar.view(start=nowDateTime - timedelta(days=1),end=nowDateTime + timedelta(days=6))

    for item in items:
        startTime = item.start.astimezone(tz=localTimeZone)
        endTime = item.end.astimezone(tz=localTimeZone)
        print(item.reminder_minutes_before_start)
Esempio n. 21
0
    def __init__(self, acc, pwd, ser, mail):
        global UTC_NOW

        credentials = Credentials(username=acc, password=pwd)
        config = Configuration(server=ser, credentials=credentials)
        self.my_account = Account(primary_smtp_address = mail, config=config,\
         autodiscover = False, access_type = DELEGATE)

        tz = EWSTimeZone.timezone('UTC')
        self.utc_time_point = UTC_NOW
        print("Successfully accessed to exchange server. time:%s" %
              str(UTC_NOW))
        print("Server:{0}, Mail:{1}, Username{2}".format(ser, mail, acc))
Esempio n. 22
0
def send_outlook_invitation(header="Invitation",
                            body="Please come to my meeting",
                            attendee=None,
                            start_time=None,
                            end_time=None):
    """Sends an outlook invitation."""

    logger.info("Sent outlook invitation")

    tz = EWSTimeZone.timezone('Europe/Stockholm')
    start_time = parser.parse(start_time)
    end_time = parser.parse(end_time)

    credentials = Credentials(settings.EMAIL_HOST_USER,
                              settings.EMAIL_HOST_PASSWORD)
    config = Configuration(server='outlook.office365.com',
                           credentials=credentials)
    account = Account(primary_smtp_address=settings.EMAIL_HOST_USER,
                      config=config,
                      autodiscover=False,
                      access_type=DELEGATE)

    if os.environ['ENVIRONMENT_MODE'] in ['UAT', 'DEV']:
        header_prefix = '*** TEST SYSTEM (env {}), NO REAL DATA *** | '.\
            format(os.environ['ENVIRONMENT_MODE'])
    else:
        header_prefix = ''

    # create a meeting request and send it out
    calendar_item = CalendarItem(
        account=account,
        folder=account.calendar,
        start=tz.localize(EWSDateTime(start_time.year,
                                      start_time.month,
                                      start_time.day,
                                      start_time.hour + 1,
                                      start_time.minute)),
        end=tz.localize(EWSDateTime(end_time.year,
                                    end_time.month,
                                    end_time.day,
                                    end_time.hour + 2,
                                    end_time.minute)),
        subject=header_prefix + header,
        body=body,
        required_attendees=[attendee]
    )

    calendar_item.save(
        send_meeting_invitations=SEND_TO_ALL_AND_SAVE_COPY)

    logger.info("Sent calendar invitation")
Esempio n. 23
0
    def download_email(self, subject, sender, send_time):
        """
        all three parameters must be specified
        only download one email each time
        :param subject:
        :param sender:
        :param send_time:
        :return: dict type
        """
        tz = EWSTimeZone.timezone("UTC")
        _dict = {}
        send_time = datetime.datetime.strptime(
            send_time, "%Y-%m-%d %H:%M:%S") - datetime.timedelta(hours=8)
        send_time = tz.localize(
            EWSDateTime(
                send_time.year,
                send_time.month,
                send_time.day,
                send_time.hour,
                send_time.minute,
                send_time.second,
            ))
        inbox = (self.account.inbox.filter(
            datetime_sent__gte=send_time, ).filter(
                datetime_sent__lte=send_time).filter(
                    subject__icontains=subject))

        for item in inbox.all().order_by("-datetime_sent"):
            for attachment in item.attachments:
                if isinstance(attachment, FileAttachment):
                    local_path = os.path.join('/Users/tongjia/Desktop/',
                                              attachment.name)
                    with open(local_path, 'wb') as f:
                        f.write(attachment.content)
                    print('Saved attachment to', local_path)

            if sender.lower() in item.sender.name.lower():
                _dict["content"] = item.text_body
                _dict["attachments"] = [
                    {
                        "name": attachment.name,
                        "content": attachment.content
                    } for attachment in item.attachments
                    if isinstance(attachment, FileAttachment)
                ]
                if _dict:
                    print('one mail meets conditions')
                return _dict
            return
 def __init__(self, sensor_service, config):
     super(ItemSensor, self).__init__(sensor_service=sensor_service, config=config)
     self._logger = self.sensor_service.get_logger(name=self.__class__.__name__)
     self._stop = False
     self._store_key = 'exchange.item_sensor_date_str'
     self._timezone = EWSTimeZone.timezone(config['timezone'])
     self._credentials = ServiceAccount(
         username=config['username'],
         password=config['password'])
     self.primary_smtp_address = config['primary_smtp_address']
     self.sensor_folder = config['sensor_folder']
     try:
         self.server = config['server']
         self.autodiscover = False
     except KeyError:
         self.autodiscover = True
Esempio n. 25
0
    def __init__(self,
                 username,
                 password,
                 server,
                 stmp_address,
                 tz_str='Asia/Hong_Kong'):
        self.username = username
        self.password = password
        self.server = server
        self.stmp_address = stmp_address
        self.url = 'https://' + server + '/EWS/Exchange.asmx'
        self.tz = EWSTimeZone.timezone(tz_str)

        self._exchangelib_connection = None
        self._imaplib_connection = None
        self._ews_connection = None
Esempio n. 26
0
    def Update(self):
        localTimeZone = EWSTimeZone.localzone()
        nowDateTime = EWSDateTime.now(tz=localTimeZone)
        # print(EWSDateTime.now(tz=localTimeZone))
        items = self.account.calendar.view(
            start=nowDateTime - timedelta(days=1),
            end=nowDateTime + timedelta(days=6),
        )

        retStr = []

        unseenStr = []
        unseenMails = self.account.inbox.filter(is_read=False)
        unseenStr.append(('{}'.format(unseenMails.count())))
        retStr.append(unseenStr)

        for item in items:
            itemStr = []
            startTime = item.start.astimezone(tz=localTimeZone)
            endTime = item.end.astimezone(tz=localTimeZone)
            dataOffset = startTime - nowDateTime
            dateOffNum = dataOffset.days+ dataOffset.seconds/(24.0*60.0*60.0)
            dateOffStr = ('%3.2f' % (dateOffNum))+'天后' if(dateOffNum>0) else ('%3.2f' % (abs(dateOffNum)))+'天前'
            if startTime.date()== nowDateTime.date():
                dateOffStr=('今天')

            when = '{},{}-{}'.format(dateOffStr,startTime.strftime('%m/%d %H:%M'),endTime.strftime('%H:%M'))

            subject = (re.sub('(?s)([^<]*)(<.*>)(.*)', '\\1\\3', '{}'.format(item.subject))).replace('None','')
            detail = (re.sub('(?s)([^<]*)(<.*>)(.*)', '\\1\\3', ':{}'.format(item.body))).replace(':None','')

            reminderTime = startTime - timedelta(minutes=item.reminder_minutes_before_start)
            if(nowDateTime.strftime("%m/%d %H:%M") == reminderTime.strftime("%m/%d %H:%M")):
                remindNow = True
            else:
                remindNow = False

            reminder = ('{} min'.format(item.reminder_minutes_before_start if item.reminder_is_set else 'No remind'))
            location = ('@{}#{}'.format(item.location,reminder)).replace('None','')

            itemStr.append(when)
            itemStr.append('{}{}'.format(subject,detail))
            itemStr.append(location)
            itemStr.append(remindNow)
            retStr.append(itemStr)
        
        return retStr
Esempio n. 27
0
 def test_localize(self):
     # Test some cornercases around DST
     tz = EWSTimeZone.timezone('Europe/Copenhagen')
     self.assertEqual(str(tz.localize(EWSDateTime(2023, 10, 29, 2, 36, 0))),
                      '2023-10-29 02:36:00+01:00')
     with self.assertRaises(AmbiguousTimeError):
         tz.localize(EWSDateTime(2023, 10, 29, 2, 36, 0), is_dst=None)
     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))),
                      '2023-03-26 02:36:00+01:00')
     with self.assertRaises(NonExistentTimeError):
         tz.localize(EWSDateTime(2023, 3, 26, 2, 36, 0), is_dst=None)
     self.assertEqual(
         str(tz.localize(EWSDateTime(2023, 3, 26, 2, 36, 0), is_dst=True)),
         '2023-03-26 02:36:00+02:00')
Esempio n. 28
0
def delete_malicious_email(recipient_email, attachment_name):
    # once the recipients are found we parse their mailboxes and delete the malicious email

    # Args:
    #     recipient_email (str)	: malware recipient email address
    #     attachment_name (str)	: the attachment file name to identify the malicious email

    # Returns:
    #     True is it parses the mailboxes, False if an error occurs

    # TODO:
    # 	ban the infected recipient machine with either IP or FortiClient using item.is_read

    account = Account(primary_smtp_address=recipient_email,
                      config=config,
                      autodiscover=False,
                      access_type=IMPERSONATION)
    tz = EWSTimeZone.localzone()
    right_now = tz.localize(EWSDateTime.now())
    xmin_ago = right_now - timedelta(minutes=300)

    try:
        for item in account.inbox.filter(datetime_received__gt=xmin_ago):
            for attachment in item.attachments:
                if isinstance(attachment, FileAttachment):
                    if attachment.name == attachment_name:
                        # Either delete the infected email, or move it to trash
                        #item.delete()
                        item.move_to_trash()

                        #send an alert to the recipient
                        m = Message(
                            account=account,
                            subject='FortiSIEM: You have received a Virus ' +
                            attachment_name,
                            body=
                            'The maliicous email has been deleted from your inbox, please contact your administrator for further incident response',
                            to_recipients=[
                                Mailbox(email_address=recipient_email)
                            ],
                        )
                        m.send()
        return True
    except:
        return False
Esempio n. 29
0
    def __init__(self):
        # Set Timezone to local Timezone
        self._tz = EWSTimeZone.localzone()

        # set start and end time of Calendarentry
        self.init_time()

        # Logger
        logging.basicConfig(level=logging.WARNING,
                            handlers=[PrettyXmlHandler()])

        # Config Parser
        config = configparser.ConfigParser()
        config.read('config.txt')
        try:
            LoginData = config["Credentials"]
        except KeyError as error:
            print('The key ' + str(error) +
                  ' were not found in the config file')
            exit()

        _Login = {
            "user": LoginData['user'],
            "password": LoginData['password'],
            "Primary_SMTP_Adress": LoginData['Primary SMTP Adress']
        }

        # Credentials and account
        self._credentials = Credentials(username=_Login["user"],
                                        password=_Login["password"])

        # Autodiscover fails w/o mail_config. See issue #337 on github exchangelib
        self._mailConfig = Configuration(server='outlook.office365.com',
                                         credentials=self._credentials)

        self._account = Account(
            default_timezone=self._tz,
            primary_smtp_address=_Login["Primary_SMTP_Adress"],
            config=self._mailConfig,
            credentials=self._credentials,
            autodiscover=False,
            access_type=DELEGATE)

        # Init Database
        self._db = exchange_database.exchange_database()
Esempio n. 30
0
def find_malicious_email(sender_email, file_name):
    # identify the attributes of the email with was sent with the malicious attachment

    # Args:
    #     sender_email (str)	: the sender email address
    #     file_name (str)		: the attachment file name to identify the malicious email

    # Returns:
    #     two lists, sibjects of the infected emails, recipients of the infected email

    # TODO:
    # 	Could be imroved by getting the email sent_time and use it as a filter in xmin_ago instead of the current 300 seconds

    recipient_emails = []
    emails_subjects = []
    account = Account(primary_smtp_address=sender_email,
                      config=config,
                      autodiscover=False,
                      access_type=IMPERSONATION)
    tz = EWSTimeZone.localzone()
    right_now = tz.localize(EWSDateTime.now())
    xmin_ago = right_now - timedelta(minutes=300)
    for item in account.sent.filter(datetime_sent__gt=xmin_ago):
        #for item in account.sent.all().order_by('-datetime_received')[:10]:
        for attachment in item.attachments:
            if isinstance(attachment, FileAttachment):
                if attachment.name == file_name:
                    emails_subjects.append(item.subject)
                    #					logging.debug('Subject: '+item.subject+' '+attachment.name)
                    if item.to_recipients is not None:
                        for index, val in enumerate(item.to_recipients):
                            if val.email_address not in recipient_emails:
                                recipient_emails.append(val.email_address)
                    if item.cc_recipients is not None:
                        for index, val in enumerate(item.cc_recipients):
                            if val.email_address not in recipient_emails:
                                recipient_emails.append(val.email_address)
                    if item.bcc_recipients is not None:
                        for index, val in enumerate(item.bcc_recipients):
                            if val.email_address not in recipient_emails:
                                recipient_emails.append(val.email_address)
    logging.debug(emails_subjects)
    logging.debug(recipient_emails)
    return emails_subjects, recipient_emails
def handleExceptions(outlook_event, google_event):

    global gEvtList

    gEvtList = []

    bIsFutureEventModified = False
    bIsFutureEventDeleted = False
    if outlook_event.modified_occurrences == None and outlook_event.deleted_occurrences == None:
        return
    if outlook_event.modified_occurrences != None:
        for occ in outlook_event.modified_occurrences:
            if isFutureDate(occ.start):
                bIsFutureEventModified = True
    if outlook_event.deleted_occurrences != None:
        for occ in outlook_event.deleted_occurrences:
            if isFutureDate(occ.start):
                bIsFutureEventDeleted = True
    # create event list in google up to
    if bIsFutureEventModified or bIsFutureEventDeleted:
        page_token = None
        now = datetime.now()
        tz = EWSTimeZone.timezone('GMT')
        maxDt = str(
            datetime(year=now.year, month=now.month, day=now.day, tzinfo=tz) +
            timedelta(days=max_fut_days_to_check)).replace(" ", "T")

        while True:
            gevents = google_service.events().instances(
                calendarId=new_cal_id,
                eventId=google_event['id'],
                pageToken=page_token,
                timeMax=maxDt).execute()
            for event in gevents['items']:
                if isFutureDate(event['start']['dateTime']):
                    gEvtList.append(event)
            page_token = gevents.get('nextPageToken')
            if not page_token:
                break

    if bIsFutureEventModified:
        handleModifiedOccurences(outlook_event)
    if bIsFutureEventDeleted:
        handleDeletedOccurences(outlook_event)
Esempio n. 32
0
def create_outlook_calendar_event(appointment, calendar_service, summary):
    ews_tz = EWSTimeZone.timezone('America/Chicago')

    d = appointment.start_time.datetime
    start_date_time = datetime(d.year, d.month, d.day, d.hour, d.minute, d.second, d.microsecond, ews_tz)
    start_ews_date_time = EWSDateTime.from_datetime(start_date_time)

    d = appointment.end_time.datetime
    end_date_time = datetime(d.year, d.month, d.day, d.hour, d.minute, d.second, d.microsecond, ews_tz)
    end_ews_date_time = EWSDateTime.from_datetime(end_date_time)

    event = CalendarItem(
        subject=summary,
        body='This event was created by Frontline Calendar. Contact Abby Lance with issues.',
        start=start_ews_date_time,
        end=end_ews_date_time
    )

    calendar_service.calendar.add_items([event])
    print('Outlook calendar event created. Details: {0}'.format(event))
Esempio n. 33
0
from yaml import safe_load

from exchangelib import DELEGATE, ServiceAccount, Configuration, Account, EWSDateTime, EWSTimeZone, CalendarItem

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.timezone('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=ServiceAccount(settings['username'], settings['password'])
)
print('Exchange server: %s' % config.protocol.server)

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

# Remove leftovers from earlier tests
Esempio n. 34
0
from yaml import load

from exchangelib import DELEGATE, services, Credentials, Configuration, Account, EWSDateTime, EWSTimeZone, 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('US/Pacific')

config = Configuration(server=settings['server'],
                       credentials=Credentials(settings['username'], settings['password'], is_service_account=True),
                       verify_ssl=settings['verify_ssl'])
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))
Esempio n. 35
0
#!/usr/bin/env python

# https://github.com/ecederstrand/exchangelib

import sys
import exchangelib
from exchangelib import (
    Account,
    Configuration,
    Credentials,
    EWSDateTime,
    EWSTimeZone,
)
from datetime import datetime, timedelta

TZ = EWSTimeZone.timezone("America/New_York")

class EWSAccount(object):
    def __init__(self, user, password):
        config = Configuration(
            server="outlook.office365.com",
            credentials=Credentials(username=user, password=password),
        )
        account = Account(
            primary_smtp_address=user,
            config=config,
            access_type=exchangelib.DELEGATE,
        )
        # could use this with Account(..., autodiscover=False)
        self.cache = {
            'ews-url': account.protocol.service_endpoint,
Esempio n. 36
0
from exchangelib import DELEGATE, Credentials, Account, EWSTimeZone, UTC_NOW
import sh

if '--insecure' in sys.argv:
    # Disable TLS when Office365 can't get their certificate act together
    from exchangelib.protocol import BaseProtocol, NoVerifyHTTPAdapter
    BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter
    # Disable insecure TLS 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
tz = EWSTimeZone.localzone()

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)
a = Account(primary_smtp_address=c.username, credentials=c, access_type=DELEGATE, autodiscover=True)

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)
Esempio n. 37
0
File: ews.py Progetto: toke/dotfiles
def connect():
    credentials = ServiceAccount(username=userconfig['ews']['username'], password=userconfig['ews']['password'])
    ews_config = Configuration(server=userconfig['ews']['server'], credentials=credentials)
    account = Account(
            config=ews_config,
            primary_smtp_address=userconfig['ews']['primary_smtp_address'],
            autodiscover=False,
            access_type=DELEGATE
    )
    return account


if __name__ == '__main__':

    account = connect()
    tz = EWSTimeZone.timezone('Europe/Berlin')

    d = datetime.today()
    year, month, day = (d.year, d.month, d.day)

    items = account.calendar.view(
        start   = tz.localize(EWSDateTime(year, month, day)),
        end     = tz.localize(EWSDateTime(year, month, day + 5))
        #,
        #categories__contains=['foo', 'bar'],
    )

    #qs = account.calendar.all()
    #qs.filter(start__range=(dt1, dt2))  # Returns items starting within range. Only for date and numerical types

    kal = LocalCalendar()