def test_success_conversion(store, icaltomapi, message): ical = open(os.path.join(dir_path, 'ics/success.ics'), 'rb').read() # As defined in namedprops.h DISPID_APPT_TS_REF = 0x25 NAMED_PROP_UID = MAPINAMEID(PSETID_Kopano_CalDav, MNID_ID, DISPID_APPT_TS_REF) NAMED_PROP_CATEGORY = MAPINAMEID(PS_PUBLIC_STRINGS, MNID_STRING, 'Keywords') properties = store.GetIDsFromNames([NAMED_PROP_UID, NAMED_PROP_CATEGORY], MAPI_CREATE) EXPECTED_MESSAGES = 1 UID = CHANGE_PROP_TYPE(properties[0], PT_BINARY) #0x85100102 CATEGORY = CHANGE_PROP_TYPE(properties[1], PT_MV_UNICODE) #0x850B101E START_DATE_PT_SYSTIME = 135547524000000000 END_DATE_PT_SYSTIME = 135547920000000000 prop_dic = { UID: [b'*****@*****.**'], PR_SUBJECT: [b'A dream holiday in the mountains'], CATEGORY: [['Holidays']], PR_SENDER_NAME_W: ['John Holidays'], PR_SENDER_EMAIL_ADDRESS_W: ['*****@*****.**'], PR_START_DATE: [FileTime(START_DATE_PT_SYSTIME)], PR_END_DATE: [FileTime(END_DATE_PT_SYSTIME)], } assert_item_count_from_ical(icaltomapi, ical, EXPECTED_MESSAGES) assert_properties_from_ical(icaltomapi, message, prop_dic)
def test_get(message): ids = message.GetIDsFromNames([MAPINAMEID(b'1234567890123456', MNID_ID, 20)], MAPI_CREATE) assert len(ids) == 1 assert PROP_ID(ids[0]) >= 0x8500 assert PROP_TYPE(ids[0]) == PT_UNSPECIFIED ids = message.GetIDsFromNames([MAPINAMEID(b'1234567890123456', MNID_ID, 20)], 0) assert len(ids) == 1 assert PROP_ID(ids[0]) >= 0x8500 assert PROP_TYPE(ids[0]) == PT_UNSPECIFIED
def test_createnewmulti(message): ids = message.GetIDsFromNames([MAPINAMEID(b'1234567890123456', MNID_ID, 10), MAPINAMEID(b'1234567890123456', MNID_ID,11)], MAPI_CREATE) assert len(ids) == 2 assert PROP_ID(ids[0]) >= 0x8500 assert PROP_ID(ids[1]) >= 0x8500 tag = ids[1] ids = message.GetIDsFromNames([MAPINAMEID(b'1234567890123456', MNID_ID, 11), MAPINAMEID(b'1234567890123456', MNID_ID,12)], MAPI_CREATE) assert len(ids) == 2 assert PROP_ID(ids[0]) >= 0x8500 assert PROP_ID(ids[1]) >= 0x8500 assert tag == ids[0]
def test_round_trip_all_day_dstart_dend_style_not_date_incorrect(store, icaltomapi, mapitoical, message): ical = open(os.path.join(dir_path, 'ics/allday_dstart_dend_style_incorrect.ics'), 'rb').read() # As defined in namedprops.h DISPID_ALL_DAY_EVENT = 0x8215 EXPECTED_MESSAGES = 1 START_DATE_PT_SYSTIME = 132587712000000000 END_DATE_PT_SYSTIME = 132588576000000000 ALL_DAY_NAMEID = MAPINAMEID(PSETID_Appointment, MNID_ID, DISPID_ALL_DAY_EVENT) ALL_DAY_PROP = CHANGE_PROP_TYPE( store.GetIDsFromNames([ALL_DAY_NAMEID], MAPI_CREATE)[0], PT_BOOLEAN ) prop_dic = { PR_START_DATE: [FileTime(START_DATE_PT_SYSTIME)], PR_END_DATE: [FileTime(END_DATE_PT_SYSTIME)], ALL_DAY_PROP: [False] } assert_item_count_from_ical(icaltomapi, ical, EXPECTED_MESSAGES) assert_properties_from_ical(icaltomapi, message, prop_dic) # Reverting back to ical. mapitoical.AddMessage(message, '', 0) method, converted_ical = mapitoical.Finalize(icalmapi.M2IC_NO_VTIMEZONE) split_ical = converted_ical.split(b'\r\n') assert b'PUBLISH' == method assert b'DTSTART:20210226T000000Z' in split_ical assert b'DTEND:20210227T000000Z' in split_ical
def test_creategetstring(message): name = MAPINAMEID(b'1234567890123456', MNID_STRING, u'testCreateGetString') ids = message.GetIDsFromNames([name], MAPI_CREATE) ids = message.GetNamesFromIDs(ids, None, 0) assert len(ids) == 1 assert repr(ids[0]) == repr(name)
def test_createget(message): name = MAPINAMEID(b'1234567890123456', MNID_ID, 30) ids = message.GetIDsFromNames([name], MAPI_CREATE) ids = message.GetNamesFromIDs(ids, None, 0) assert len(ids) == 1 assert repr(ids[0]) == repr(name)
def _name_id(self, name_tuple): id_ = self._name_id_cache.get(name_tuple) if id_ is None: named_props = [MAPINAMEID(*name_tuple)] # TODO use MAPI_CREATE, or too dangerous because of # potential db overflow? id_ = self.mapiobj.GetIDsFromNames(named_props, 0)[0] self._name_id_cache[name_tuple] = id_ return id_
def test_createnew2(message): ids = message.GetIDsFromNames([MAPINAMEID(b'1234567890123456', MNID_ID, 5)], MAPI_CREATE) assert len(ids) == 1 assert PROP_ID(ids[0]) >= 0x8500 assert PROP_TYPE(ids[0]) == PT_UNSPECIFIED tag = ids[0] ids = message.GetIDsFromNames([MAPINAMEID(b'1234567890123456', MNID_ID, 5)], MAPI_CREATE) assert len(ids) == 1 assert PROP_ID(ids[0]) >= 0x8500 assert PROP_TYPE(ids[0]) == PT_UNSPECIFIED assert tag == ids[0] ids = message.GetIDsFromNames([MAPINAMEID(b'1234567890123456', MNID_ID, 6)], MAPI_CREATE) assert len(ids) == 1 assert PROP_ID(ids[0]) >= 0x8500 assert PROP_TYPE(ids[0]) == PT_UNSPECIFIED assert tag != ids[0]
def test_getmulti(message): name = MAPINAMEID(b'1234567890123456', MNID_ID, 40) ids = message.GetIDsFromNames([name], MAPI_CREATE) ids += [PROP_TAG(PT_UNSPECIFIED, 0x9000)] ids = message.GetNamesFromIDs(ids, None, 0) assert len(ids) == 2 assert repr(ids[0]) == repr(name) assert repr(ids[1]) == 'None'
def occurrences(self, start=None, end=None): if start and end: startstamp = time.mktime(start.timetuple()) endstamp = time.mktime(end.timetuple()) # XXX use shortcuts and default type (database) to avoid MAPI snake wrestling NAMED_PROPS = [ MAPINAMEID(PSETID_Appointment, MNID_ID, x) for x in (33293, 33294, 33315) ] ids = self.mapiobj.GetIDsFromNames(NAMED_PROPS, 0) startdate = ids[0] | PT_SYSTIME enddate = ids[1] | PT_SYSTIME recurring = ids[2] | PT_BOOLEAN # only look at non-recurring items which overlap and all recurring items restriction = SOrRestriction([ SAndRestriction([ SPropertyRestriction( RELOP_GT, enddate, SPropValue(enddate, unixtime(startstamp))), SPropertyRestriction( RELOP_LT, startdate, SPropValue(startdate, unixtime(endstamp))), ]), SAndRestriction([ SPropertyRestriction(RELOP_EQ, recurring, SPropValue(recurring, True)) ]) ]) table = Table( self.server, self.mapiobj, self.mapiobj.GetContentsTable(MAPI_DEFERRED_ERRORS), PR_CONTAINER_CONTENTS, columns=[PR_ENTRYID], ) table.mapitable.Restrict(restriction, 0) for row in table.rows(): entryid = _benc(row[0].value) for occurrence in self.item(entryid).occurrences(start, end): yield occurrence else: for item in self: for occurrence in item.occurrences(start, end): yield occurrence
def test_microsoft_style_not_all_day_if_not_midnight_incorrect(store, icaltomapi, message): ical = open(os.path.join(dir_path, 'ics/allday_ms_style_incorrect.ics'), 'rb').read() # As defined in namedprops.h DISPID_ALL_DAY_EVENT = 0x8215 ALL_DAY_NAMEID = MAPINAMEID(PSETID_Appointment, MNID_ID, DISPID_ALL_DAY_EVENT) ALL_DAY_PROP = CHANGE_PROP_TYPE( store.GetIDsFromNames([ALL_DAY_NAMEID], MAPI_CREATE)[0], PT_BOOLEAN ) EXPECTED_MESSAGES = 1 IS_ALL_DAY = [False] assert_item_count_from_ical(icaltomapi, ical, EXPECTED_MESSAGES) assert_property_value_from_ical(icaltomapi, message, ALL_DAY_PROP, IS_ALL_DAY)
0x31, 0x7A, 0x21, 0x0C, 0xC1, 0x5B) PSETID_CONTACT_FOLDER_RECIPIENT = DEFINE_GUID(0x0AAA42FE, 0xC718, 0x101A, 0xE8, 0x85, 0x0B, 0x65, 0x1C, 0x24, 0x00, 0x00) PSETID_ZMT = DEFINE_GUID(0x8acdbf85, 0x4738, 0x4dc4, 0x94, 0xa9, 0xd4, 0x89, 0xa8, 0x3e, 0x5c, 0x41) PSETID_CalendarAssistant = DEFINE_GUID(0x11000E07, 0xB51B, 0x40D6, 0xAF, 0x21, 0xCA, 0xA8, 0x5E, 0xDA, 0xB1, 0xD0) PS_EC_IMAP = DEFINE_GUID(0x00f5f108, 0x8e3f, 0x46c7, 0xaf, 0x72, 0x5e, 0x20, 0x1c, 0x23, 0x49, 0xe7) PSETID_KC = DEFINE_GUID(0x63aed8c8, 0x4049, 0x4b75, 0xbc, 0x88, 0x96, 0xdf, 0x9d, 0x72, 0x3f, 0x2f) NAMED_PROPS_INTERNET_HEADERS = [ MAPINAMEID(PS_INTERNET_HEADERS, MNID_STRING, u'x-original-to'), ] NAMED_PROPS_ARCHIVER = [ MAPINAMEID(PSETID_Archive, MNID_STRING, u'store-entryids'), MAPINAMEID(PSETID_Archive, MNID_STRING, u'item-entryids'), MAPINAMEID(PSETID_Archive, MNID_STRING, u'stubbed'), MAPINAMEID(PSETID_Archive, MNID_STRING, u'ref-store-entryid'), MAPINAMEID(PSETID_Archive, MNID_STRING, u'ref-item-entryid'), MAPINAMEID(PSETID_Archive, MNID_STRING, u'ref-prev-entryid'), MAPINAMEID(PSETID_Archive, MNID_STRING, u'flags') ] NAMED_PROPS_KC = [MAPINAMEID(PSETID_KC, MNID_ID, 0x0001)] NAMED_PROP_CATEGORY = MAPINAMEID(PS_PUBLIC_STRINGS, MNID_STRING, u'Keywords')
def test_badid1(message): with pytest.raises(RuntimeError) as excinfo: message.GetIDsFromNames([MAPINAMEID(b'1234567890123456', MNID_STRING, b'test')], 0) assert 'Must pass unicode string for MNID_STRING' in str(excinfo)
def test_badid3(message): ids = message.GetIDsFromNames([MAPINAMEID(b'1234567890123456', MNID_STRING, u'nonexist')], 0) assert len(ids) == 1 assert ids[0] == PROP_TAG(PT_ERROR, 0)
def test_badid2(message): ids = message.GetIDsFromNames([MAPINAMEID(b'1234567890123456', MNID_ID, 1)], 0) assert len(ids) == 1 assert ids[0] == PROP_TAG(PT_ERROR, 0)
def occurrences(self, start=None, end=None, page_start=None, page_limit=None, order=None): count = 0 pos = 0 if start and end: startstamp = time.mktime(start.timetuple()) endstamp = time.mktime(end.timetuple()) # XXX use shortcuts and default type (database) to avoid MAPI snake wrestling NAMED_PROPS = [ MAPINAMEID(PSETID_Appointment, MNID_ID, x) for x in (33285, 33293, 33294, 33315, 33301, 33333, 33334) ] ids = self.mapiobj.GetIDsFromNames(NAMED_PROPS, MAPI_CREATE) busystatus = ids[0] | PT_LONG startdate = ids[1] | PT_SYSTIME enddate = ids[2] | PT_SYSTIME recurring = ids[3] | PT_BOOLEAN all_day = ids[4] | PT_BOOLEAN clip_start = ids[5] | PT_SYSTIME clip_end = ids[6] | PT_SYSTIME restriction = SOrRestriction([ # non-recurring: normal start/end SAndRestriction([ SPropertyRestriction( RELOP_GT, enddate, SPropValue(enddate, unixtime(startstamp))), SPropertyRestriction( RELOP_LT, startdate, SPropValue(startdate, unixtime(endstamp))), ]), # recurring: range start/end SAndRestriction([ SPropertyRestriction( RELOP_GT, clip_end, SPropValue(clip_end, unixtime(startstamp))), SPropertyRestriction( RELOP_LT, clip_start, SPropValue(clip_start, unixtime(endstamp))), ]), # exceptions: exception start/end in attachment SAndRestriction([ SPropertyRestriction(RELOP_EQ, recurring, SPropValue(recurring, True)), SSubRestriction( PR_MESSAGE_ATTACHMENTS, SAndRestriction([ SPropertyRestriction( RELOP_LT, PR_EXCEPTION_STARTTIME, SPropValue(PR_EXCEPTION_STARTTIME, unixtime(endstamp))), SPropertyRestriction( RELOP_GT, PR_EXCEPTION_ENDTIME, SPropValue(PR_EXCEPTION_ENDTIME, unixtime(startstamp))), ])) ]) ]) columns = [ PR_ENTRYID, PR_SUBJECT_W, # watch out: table unicode data is max 255 chars PR_LAST_MODIFICATION_TIME, PR_CHANGE_KEY, startdate, enddate, recurring, all_day, busystatus ] table = Table( self.server, self.mapiobj, self.mapiobj.GetContentsTable(MAPI_DEFERRED_ERRORS), PR_CONTAINER_CONTENTS, columns=columns, ) table.mapitable.Restrict(restriction, 0) for row in table.rows(): item = _item.Item(self, entryid=row[0].value, content_flag=self.content_flag, cache=dict(zip(columns, row))) for occurrence in item.occurrences(start, end): if page_start is None or pos >= page_start: yield occurrence count += 1 if page_limit is not None and count >= page_limit: break pos += 1 if page_limit is not None and count >= page_limit: break else: for item in self: for occurrence in item.occurrences(start, end): if page_start is None or pos >= page_start: yield occurrence count += 1 if page_limit is not None and count >= page_limit: break pos += 1 if page_limit is not None and count >= page_limit: break