def createAppointment(self, sendAppointment: SendAppointment): required_recipients = [] optional_recipients = [] for attendee in sendAppointment.requiredAttendees.split(';'): if attendee == "": continue required_recipients.append(attendee) for attendee in sendAppointment.optionalAttendees.split(';'): if attendee == "": continue optional_recipients.append(attendee) calendar_item = CalendarItem( account=self.account, folder=self.account.calendar, start=self.account.default_timezone.localize( EWSDateTime.from_datetime(sendAppointment.startTime)), end=self.account.default_timezone.localize( EWSDateTime.from_datetime(sendAppointment.endTime)), subject=sendAppointment.subject, body=sendAppointment.body, required_attendees=required_recipients, optional_attendees=optional_recipients) # 'SendToNone', 'SendOnlyToAll', 'SendToAllAndSaveCopy calendar_item.save(send_meeting_invitations='SendToAllAndSaveCopy')
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
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
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()
def miniprogram_pushMessage_get(isGetAll: bool = False): db_session = None if "DEVMODE" in os.environ: if os.environ["DEVMODE"] == "True": db_session = orm.init_db(os.environ["DEV_DATABASEURI"]) else: db_session = orm.init_db(os.environ["DATABASEURI"]) else: db_session = orm.init_db(os.environ["DATABASEURI"]) learner = weapp.getLearner() if not learner: db_session.remove() return {'code': -1001, 'message': '没有找到对应的Learner'}, 200 response = [] if isGetAll: pushMessageList = db_session.query(orm.PushMessage_db).all() else: pushMessageList = db_session.query(orm.PushMessage_db).filter(orm.PushMessage_db.expireDateTime > datetime.datetime.utcnow()).all() for pushMessage in pushMessageList: if util.isRecipient(learner, json.loads(pushMessage.recipients)): response.append({ "id": pushMessage.id, "messageType": pushMessage.messageType, "entityId": pushMessage.entityId, "senderId": pushMessage.senderId, "recipients": json.loads(pushMessage.recipients), "rsvp": json.loads(pushMessage.rsvp), "sentDateTime": EWSDateTime.from_datetime(tzinfo.localize(pushMessage.sentDateTime)).ewsformat(), "modifiedDateTime": EWSDateTime.from_datetime(tzinfo.localize(pushMessage.modifiedDateTime)).ewsformat(), "expireDateTime": EWSDateTime.from_datetime(tzinfo.localize(pushMessage.expireDateTime)).ewsformat(), "content": json.loads(pushMessage.content) }) db_session.remove() return {'code': 0, 'data': response, 'message': '成功'}, 200
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
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
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 upcomingEvents(self, window=timedelta(minutes=5)): start = datetime.now() #start = datetime(2017, 3, 17, 12, 56) endtm = start + window start = TZ.localize(EWSDateTime.from_datetime(start)) endtm = TZ.localize(EWSDateTime.from_datetime(endtm)) return self.account.calendar.view(start=start, end=endtm)
def miniprogram_announcement_announcementId_get(announcementId): # 获取通知的详情 db_session = None if "DEVMODE" in os.environ: if os.environ["DEVMODE"] == "True": db_session = orm.init_db(os.environ["DEV_DATABASEURI"]) else: db_session = orm.init_db(os.environ["DATABASEURI"]) else: db_session = orm.init_db(os.environ["DATABASEURI"]) learner = weapp.getLearner() if not learner: db_session.remove() return {'code': -1001, 'message': '没有找到对应的Learner'}, 200 announcement = db_session.query(orm.Announcement_db).filter(orm.Announcement_db.id == announcementId).one_or_none() try: response = { "id": announcement.id, "initiatorId": announcement.initiatorId, "initiatorDisplayName": announcement.initiatorDisplayName, "recipients": json.loads(announcement.recipients), "sentDateTime": EWSDateTime.from_datetime(tzinfo.localize(announcement.sentDateTime)).ewsformat(), "modifiedDateTime": EWSDateTime.from_datetime(tzinfo.localize(announcement.modifiedDateTime)).ewsformat(), "thumbnail": json.loads(announcement.thumbnail), "title": announcement.title, "description": announcement.description, "body": json.loads(announcement.body), "attachment": json.loads(announcement.attachment), } db_session.remove() return {'code': 0, 'data': response, 'message': '成功'}, 200 except Exception as e: db_session.remove() return {'code': -5003, 'message': '获取通知详情失败', 'log': str(e)}, 200
def miniprogram_notification_get(isGetAll: bool = False): def constructContent(notification: Notification_db): if notification.notificationType == "活动日程": event: Event_db = db_session.query(orm.Event_db).filter( orm.Event_db.id == notification.entityId).one_or_none() return { "startDateTime": json.loads(event.eventInfo)["startDateTime"], "endDateTime": json.loads(event.eventInfo)["endDateTime"], "initiatorId": event.initiatorId, "initiatorDisplayName": event.initiatorDisplayName } db_session = None if "DEVMODE" in os.environ: if os.environ["DEVMODE"] == "True": db_session = orm.init_db(os.environ["DEV_DATABASEURI"]) else: db_session = orm.init_db(os.environ["DATABASEURI"]) else: db_session = orm.init_db(os.environ["DATABASEURI"]) learner = weapp.getLearner() if not learner: db_session.remove() return {'code': -1001, 'message': '没有找到对应的Learner'}, 200 response = [] if isGetAll: notificationList: List[Notification_db] = db_session.query( orm.Notification_db).filter( orm.Notification_db.learnerId == learner.id).all() else: notificationList = db_session.query(orm.Notification_db).filter( orm.Notification_db.learnerId == learner.id).filter( orm.Notification_db.expireDateTime > datetime.datetime.utcnow()).all() for notification in notificationList: response.append({ "notificationType": notification.notificationType, "entityId": notification.entityId, "createdDateTime": EWSDateTime.from_datetime( tzinfo.localize(notification.createdDateTime)).ewsformat(), "expireDateTime": EWSDateTime.from_datetime( tzinfo.localize(notification.expireDateTime)).ewsformat(), "status": notification.status, "title": notification.title, "description": notification.description, "content": constructContent(notification) }) db_session.remove() return {'code': 0, 'data': response, 'message': '成功'}, 200
def init_time(self): ''' Initialize the time with start and endTime saves a localized EWSDateTime formatted start and endtime ''' tz = self._tz today = datetime.date.today() st = datetime.time(hour=21, minute=00) et = datetime.time(hour=22, minute=00) # forgive me father because I have sinned self._startTime = EWSDateTime.from_datetime( tz.localize(datetime.datetime.combine(today, st))) self._endTime = EWSDateTime.from_datetime( tz.localize(datetime.datetime.combine(today, et)))
def poll(self): stored_date = self._get_last_date() if not stored_date: stored_date = datetime.now() - timedelta(minutes=1) self._logger.info("Stored date is {0} and now is {1}".format( stored_date, datetime.now())) start_date = self._timezone.localize( EWSDateTime.from_datetime(stored_date)) target = self.account.root.get_folder_by_name(self.sensor_folder) items = target.filter(is_read=False).filter( datetime_received__gt=start_date) self._logger.info("Found {0} items in {1}".format( items.count(), target)) if items.count() > 0: self._logger.info("Here it is:\nItems of type {0}:\n{1}".format( type(items), items.all())) for payload in items.values( 'subject'): # , 'item_id', 'body', 'datetime_received' self._logger.info("Sending trigger for item '{0}'.".format( payload['subject'])) self._sensor_service.dispatch( trigger='msexchange.exchange_new_item', payload=payload)
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))
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))
def set_ooo( internal_reply, external_reply, dt_start, next_tuesday ): a = ews_account() # for some reason, creating a timezone from scracth is b0rked. # use the existing timezone settings = a.oof_settings tz_ews = settings.start.tzinfo oof_start = EWSDateTime.from_datetime( dt_start ) oof_end = EWSDateTime.from_datetime( next_tuesday ) oof_settings = OofSettings( state = OofSettings.SCHEDULED, external_audience = 'All', internal_reply = internal_reply, external_reply = external_reply, start = tz_ews.localize( oof_start ), end = tz_ews.localize( oof_end ) ) a.oof_settings = oof_settings
def poll(self): stored_date = self._get_last_date() if not stored_date: stored_date = datetime.now() start_date = self._timezone.localize(EWSDateTime.from_datetime(stored_date)) target = self.account.root.get_folder_by_name(self.sensor_folder) items = target.filter(is_read=False).filter(datetime_received__gt=start_date) self._logger.info("Found {0} items".format(items.count())) for payload in items.values('item_id', 'subject', 'body', 'datetime_received'): self._logger.info("Sending trigger for item '{0}'.".format(payload['subject'])) self._sensor_service.dispatch(trigger='exchange_new_item', payload=payload) self._set_last_date(payload['datetime_received'])
def miniprogram_announcement_get(): # 获取通知列表,目前暂时默认为返回全部条目 db_session = None if "DEVMODE" in os.environ: if os.environ["DEVMODE"] == "True": db_session = orm.init_db(os.environ["DEV_DATABASEURI"]) else: db_session = orm.init_db(os.environ["DATABASEURI"]) else: db_session = orm.init_db(os.environ["DATABASEURI"]) learner = weapp.getLearner() if not learner: db_session.remove() return {'code': -1001, 'message': '没有找到对应的Learner'}, 200 try: announcementList = db_session.query(orm.Announcement_db).all() response = [] for announcement in announcementList: response.append({ "id": announcement.id, "pushMessageId": announcement.pushMessageId, "initiatorId": announcement.initiatorId, "initiatorDisplayName": announcement.initiatorDisplayName, "recipients": json.loads(announcement.recipients), "sentDateTime": EWSDateTime.from_datetime(tzinfo.localize(announcement.sentDateTime)).ewsformat(), "modifiedDateTime": EWSDateTime.from_datetime(tzinfo.localize(announcement.modifiedDateTime)).ewsformat(), "expireDateTime": EWSDateTime.from_datetime(tzinfo.localize(announcement.expireDateTime)).ewsformat(), "thumbnail": json.loads(announcement.thumbnail), "title": announcement.title, "description": announcement.description, "body": json.loads(announcement.body), "attachment": json.loads(announcement.attachment) }) db_session.remove() except Exception as e: db_session.remove() return {'code': -3006, 'message': '获取通知列表失败', 'log': str(e)}, 200 return {'code': 0, 'data': response, 'message': '成功'}, 200
def _get_unread_mail_infos(self, last_time): """未読メール情報を取得 Args: last_time(DateTime): 前回実行日時 (UTC) 未指定の場合は、全ての未読メールを取得 Returns: list(dict): 受信トレイおよびサブフォルダの未読メール情報 """ inbox_mails = self.account.inbox.filter(is_read=False) subfolder_mails = self.account.inbox.walk().filter(is_read=False) if last_time: ews_last_time = EWSDateTime.from_datetime(last_time) inbox_mails = inbox_mails.filter(datetime_received__gt=ews_last_time) subfolder_mails = subfolder_mails.filter(datetime_received__gt=ews_last_time) return self._get_mail_infos(inbox_mails) + self._get_mail_infos(subfolder_mails)
def _get_unread_mail_ids(self, last_time): """未読メールIDを取得 Args: last_time(DateTime): 前回実行日時 (UTC) 未指定の場合は、全ての未読メールを取得 Returns: list(str): 受信トレイおよびサブフォルダの未読メール識別ID (Message.id) """ unread_inbox = self.account.inbox.filter(is_read=False) unread_subfolder = self.account.inbox.walk().filter(is_read=False) if last_time: ews_last_time = EWSDateTime.from_datetime(last_time) unread_inbox = unread_inbox.filter(datetime_received__gt=ews_last_time) unread_subfolder = unread_subfolder.filter(datetime_received__gt=ews_last_time) return [mail.id for mail in unread_inbox] + [mail.id for mail in unread_subfolder]
def miniprogram_event_eventId_get(eventId): # 获取活动的详情以及相关的rsvp详情 db_session = None if "DEVMODE" in os.environ: if os.environ["DEVMODE"] == "True": db_session = orm.init_db(os.environ["DEV_DATABASEURI"]) else: db_session = orm.init_db(os.environ["DATABASEURI"]) else: db_session = orm.init_db(os.environ["DATABASEURI"]) learner = weapp.getLearner() if not learner: db_session.remove() return {'code': -1001, 'message': '没有找到对应的Learner'}, 200 event = db_session.query( orm.Event_db).filter(orm.Event_db.id == eventId).one_or_none() pushMessage = db_session.query(orm.PushMessage_db).filter( orm.PushMessage_db.id == event.pushMessageId).one_or_none() try: response = { "id": event.id, "initiatorId": event.initiatorId, "initiatorDisplayName": event.initiatorDisplayName, "eventInfo": json.loads(event.eventInfo), "invitee": json.loads(event.invitee), "thumbnail": json.loads(event.thumbnail), "rsvp": json.loads(pushMessage.rsvp), "expireDatetime": EWSDateTime.from_datetime(tzinfo.localize( event.expireDateTime)).ewsformat() } db_session.remove() return {'code': 0, 'data': response, 'message': '成功'}, 200 except Exception as e: db_session.remove() return {'code': -3004, 'message': '获取活动详情失败', 'log': str(e)}, 200
def read_email(self): while True: try: print("Reading emails....") tz = self.account.default_timezone lc_now = tz.localize( EWSDateTime.from_datetime(datetime.datetime.now())) since = lc_now - timedelta( hours=self.config.get("filter time")) print(since) filtered_emails = self.account.inbox.all().filter( datetime_received__gt=since).order_by('-datetime_received') data = self.validate_emails(filtered_emails) print(data) self.post_to_server(data) except Exception: logger.exception("read_email") finally: print("Sleeping for 5 Sec") time.sleep(5)
def poll(self): stored_date = self._get_last_date() self._logger.info("Stored Date: {}".format(stored_date)) if not stored_date: stored_date = datetime.now() start_date = self._timezone.localize( EWSDateTime.from_datetime(stored_date)) target = self.account.root.get_folder_by_name(self.sensor_folder) items = target.filter(is_read=False).filter( datetime_received__gt=start_date) self._logger.info("Found {0} items".format(items.count())) for newitem in items: self._logger.info("Sending trigger for item '{0}'.".format( newitem.subject)) self._dispatch_trigger_for_new_item(newitem=newitem) self._set_last_date(newitem.datetime_received) self._logger.info("Updating read status on item '{0}'.".format( newitem.subject)) newitem.is_read = True newitem.save()
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 get_emails(self, username, folder_path=None, email_ids=None, sender=None, subject=None, body=None, start_date=None, end_date=None, has_attachments=None, order_by_recency=None, num_emails=None, search_subfolders=False): """Get queried emails""" # Default folder path if no folder path is specified folder_path = self.default_folder_path if folder_path is None else folder_path # Get list of all specified folders, preserving commas wrapped in quotes split_folder_paths = re.findall('(?:[^,"]|"(?:\\.|[^"])*")+', folder_path) folders = [ self.go_to_folder(username, folder.strip()) for folder in split_folder_paths ] # Subfolder query check if search_subfolders: subfolders = [] # For each specified folder for folder in folders: if folder.child_folder_count > 0: subfolders += list(folder.walk().get_folders()) folders += subfolders folder_collection = FolderCollection( account=self.connect_to_account(username), folders=folders) filtered_emails = folder_collection.all() # filter by ids if email_ids: id_query = Q() for email_id in email_ids.split(','): id_query = id_query | Q(message_id=email_id.strip()) filtered_emails = filtered_emails.filter(id_query) # filter by sender if sender: filtered_emails = filtered_emails.filter(sender=sender) if subject: filtered_emails = filtered_emails.filter(subject__contains=subject) if body: filtered_emails = filtered_emails.filter(body__contains=body) # filter by date if start_date: # get YYYY/MM/DD from epoch time in milliseconds tz = EWSTimeZone.timezone('Etc/GMT') start_date = EWSDateTime.from_datetime( datetime.datetime.fromtimestamp(start_date / 1000, tz=tz)) filtered_emails = filtered_emails.filter( datetime_received__gte=start_date) if end_date: # get YYYY/MM/DD from epoch time in milliseconds tz = EWSTimeZone.timezone('Etc/GMT') end_date = EWSDateTime.from_datetime( datetime.datetime.fromtimestamp(end_date / 1000, tz=tz)) filtered_emails = filtered_emails.filter( datetime_received__lte=end_date) # Check attachments if has_attachments is not None: filtered_emails = filtered_emails.filter( has_attachments=has_attachments) # Order by date if order_by_recency is not None: if order_by_recency: filtered_emails = filtered_emails.order_by( '-datetime_received') else: filtered_emails = filtered_emails.order_by('datetime_received') # Only get num_emails if num_emails: filtered_emails = filtered_emails[:num_emails] return filtered_emails
def test_ewsdatetime(self): # Test a static timezone tz = EWSTimeZone.timezone('Etc/GMT-5') 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+05:00') self.assertEqual( repr(dt), "EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=<StaticTzInfo 'Etc/GMT-5'>)" ) # Test a DST timezone tz = EWSTimeZone.timezone('Europe/Copenhagen') 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>)" ) # 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'), UTC.localize(EWSDateTime(2000, 1, 2, 2, 4, 5))) self.assertEqual(EWSDateTime.from_string('2000-01-02T03:04:05Z'), UTC.localize(EWSDateTime(2000, 1, 2, 3, 4, 5))) 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) self.assertEqual( dt, EWSDateTime.from_datetime( tz.localize(datetime.datetime(2000, 1, 2, 3, 4, 5)))) self.assertEqual(dt.ewsformat(), '2000-01-02T03:04:05+01:00') 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') # Test normalize, for completeness self.assertEqual( tz.normalize(dt).ewsformat(), '2000-08-02T03:04:05+02:00') self.assertEqual( utc_tz.normalize(dt, is_dst=True).ewsformat(), '2000-08-02T01:04:05Z') # Test in-place add and subtract dt = tz.localize(EWSDateTime(2000, 1, 2, 3, 4, 5)) dt += datetime.timedelta(days=1) self.assertIsInstance(dt, EWSDateTime) self.assertEqual(dt, tz.localize(EWSDateTime(2000, 1, 3, 3, 4, 5))) dt = tz.localize(EWSDateTime(2000, 1, 2, 3, 4, 5)) dt -= datetime.timedelta(days=1) self.assertIsInstance(dt, EWSDateTime) self.assertEqual(dt, tz.localize(EWSDateTime(2000, 1, 1, 3, 4, 5))) # 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=pytz.utc) with self.assertRaises(ValueError): EWSDateTime.from_datetime(EWSDateTime(2000, 1, 2, 3, 4, 5))
today = EWSDate.today() also_today = right_now.date() also_today += timedelta(days=10) # UTC helpers. 'UTC' is the UTC timezone as an EWSTimeZone instance. # 'UTC_NOW' returns a timezone-aware UTC timestamp of current time. from exchangelib import UTC, UTC_NOW right_now_in_utc = UTC.localize(EWSDateTime.now()) right_now_in_utc = UTC_NOW() # Already have a Python datetime object you want to use? Make sure it's localized. Then pass # it to from_datetime(). pytz_tz = pytz.timezone('Europe/Copenhagen') py_dt = pytz_tz.localize(datetime(2017, 12, 11, 10, 9, 8)) ews_now = EWSDateTime.from_datetime(py_dt) ###Creating, updating, deleting, sending, moving, archiving # Here's an example of creating a calendar item in the user's standard calendar. If you want to # access a non-standard calendar, choose a different one from account.folders[Calendar]. # # You can create, update and delete single items: from exchangelib import Account, CalendarItem, Message, Mailbox, FileAttachment, HTMLBody from exchangelib.items import SEND_ONLY_TO_ALL, SEND_ONLY_TO_CHANGED from exchangelib.properties import DistinguishedFolderId a = Account(...) item = CalendarItem(folder=a.calendar, subject='foo') item.save() # This gives the item an 'id' and a 'changekey' value item.save(send_meeting_invitations=SEND_ONLY_TO_ALL
def __collect_metrics(self) -> list: meeting_room_occupancy = GaugeMetricFamily( 'exchange_meeting_room_occupied', 'This metric exposes info about meeting room occupancy', labels=[ "meeting_room_list_name", "meeting_room_name", "meeting_room_email" ]) meeting_room_will_be_occupied = GaugeMetricFamily( 'exchange_meeting_room_will_be_occupied_timestamp', 'This metric exposes timestamp of closest start of the room occupancy.', labels=[ "meeting_room_list_name", "meeting_room_name", "meeting_room_email" ]) meeting_room_will_be_free = GaugeMetricFamily( 'exchange_meeting_room_will_be_free_timestamp', 'This metric exposes timestamp of the most recent time the room will be free.', labels=[ "meeting_room_list_name", "meeting_room_name", "meeting_room_email" ]) today_meetings_left = GaugeMetricFamily( 'exchange_meeting_room_meetings_left_today', 'This metric exposes number of the meetings till the end of this day.', labels=[ "meeting_room_list_name", "meeting_room_name", "meeting_room_email" ]) now = self.__account.default_timezone.localize(EWSDateTime.now()) end = self.__account.default_timezone.localize( EWSDateTime.from_datetime( datetime.combine(now.date() + timedelta(days=1), datetime.min.time()))) room_list_count = 0 room_count = 0 skipped_count = 0 start = datetime.now() try: for room_list in self.__account.protocol.get_roomlists(): self.__logger.debug("processing room list: {}".format( room_list.name)) if not self.__room_list_regex.search(room_list.name): self.__logger.debug( "processing room list {} skipped, not matching regular expression" .format(room_list.name)) continue room_list_count += 1 for room in self.__account.protocol.get_rooms( room_list.email_address): self.__logger.debug("processing room: {}".format( room.name)) if not self.__room_name_regex.search(room.name): self.__logger.debug( "processing room {} skipped, not matching regular expression" .format(room.name)) skipped_count += 1 continue room_count += 1 room_account = self.__get_account(room.email_address) calendar = room_account.calendar.view(start=now, end=end) self.__logger.debug( "checking calendar: start={} end={}".format(now, end)) is_occupied = False will_be_free = now will_be_occupied = self.__account.default_timezone.localize( datetime.max - timedelta(1)) events_count = 0 if calendar.exists(): for i, event in enumerate(calendar): events_count += 1 if event.start <= now <= event.end: is_occupied = True will_be_free = event.end continue if will_be_free == event.start: will_be_free = event.end if not is_occupied: will_be_occupied = calendar[0].start self.__logger.debug( "occupied: {} will_be_free={} will_be_occupied={} events: {}" .format(is_occupied, will_be_free, will_be_occupied, events_count)) meeting_room_occupancy.add_metric( labels=[room_list.name, room.name, room.email_address], value=int(is_occupied)) meeting_room_will_be_occupied.add_metric( labels=[room_list.name, room.name, room.email_address], value=will_be_occupied.timestamp()) meeting_room_will_be_free.add_metric( labels=[room_list.name, room.name, room.email_address], value=will_be_free.timestamp()) today_meetings_left.add_metric( labels=[room_list.name, room.name, room.email_address], value=events_count) self.__logger.info( "finished processing of {} room lists wit total {} rooms and {} rooms skipped, duration {}" .format(room_list_count, room_count, skipped_count, datetime.now() - start)) self.__last_update = datetime.now() except Exception as e: self.__logger.info( "failed to update meeting room data, error: {}".format(e)) errors_total.labels(e.__class__.__name__).inc() up.set(0) return [] up.set(1) return [ meeting_room_occupancy, meeting_room_will_be_occupied, meeting_room_will_be_free, today_meetings_left, ]