def load_proptags(self): # Load up all available properties from mt module for name, value in mt.__dict__.iteritems(): if name[:3] == 'PR_': # Store both the full ID (including type) and just the ID. # This is so PR_FOO_A and PR_FOO_W are still # differentiated. Note that in the following call, the value # hash will only contain the full ID. self.put(name=name, value=mt.PROP_ID(value)) self.put(name=name, value=value) # Now Add a bunch of named properties that we are specifically # interested in. self.put(name='ASYNK_PR_FILE_AS', value=self.get_file_as_prop_tag()) self.put(name='ASYNK_PR_EMAIL_1', value=self.get_email_prop_tag(1)) self.put(name='ASYNK_PR_EMAIL_2', value=self.get_email_prop_tag(2)) self.put(name='ASYNK_PR_EMAIL_3', value=self.get_email_prop_tag(3)) self.put(name='ASYNK_PR_IM_1', value=self.get_im_prop_tag(1)) self.put('ASYNK_PR_TASK_DUE_DATE', self.get_task_due_date_tag()) self.put('ASYNK_PR_TASK_STATE', self.get_task_state_tag()) self.put('ASYNK_PR_TASK_RECUR', self.get_task_recur_tag()) self.put('ASYNK_PR_TASK_COMPLETE', self.get_task_complete_tag()) self.put('ASYNK_PR_TASK_DATE_COMPLETED', self.get_task_date_completed_tag()) self.put('ASYNK_PR_CUSTOM_PROPS', self.get_custom_prop_tag()) self.load_sync_proptags()
def print_prop(self, tag, value): prop_type = mapitags.PROP_TYPE(tag) prop_id = mapitags.PROP_ID(tag) if prop_type & mapitags.MV_FLAG: print "Tag: 0x%16x (Multi Value); Value: %s" % (long(tag), value) else: print "Tag: %s; Value: %s" % (mapiutil.GetPropTagName(tag), value)
def DumpItemProp(item, prop, outfile): if type(prop) != type(0): # see if a mapitags contant try: prop = mapitags.__dict__[prop] except KeyError: # resolve as a name props = ((mapi.PS_PUBLIC_STRINGS, prop), ) propIds = obj.GetIDsFromNames(props, 0) prop = mapitags.PROP_TAG(mapitags.PT_UNSPECIFIED, mapitags.PROP_ID(propIds[0])) hr, data = item.GetProps((prop, ), 0) prop_tag, prop_val = data[0] # Do some magic rtf conversion if mapitags.PROP_ID(prop_tag) == mapitags.PROP_ID( mapitags.PR_RTF_COMPRESSED): rtf_stream = item.OpenProperty(mapitags.PR_RTF_COMPRESSED, pythoncom.IID_IStream, 0, 0) html_stream = mapi.WrapCompressedRTFStream(rtf_stream, 0) chunks = [] while 1: chunk = html_stream.Read(4096) if not chunk: break chunks.append(chunk) prop_val = "".join(chunks) elif mapitags.PROP_TYPE(prop_tag)==mapitags.PT_ERROR and \ prop_val in [mapi.MAPI_E_NOT_ENOUGH_MEMORY,'MAPI_E_NOT_ENOUGH_MEMORY']: prop_tag = mapitags.PROP_TAG(mapitags.PT_BINARY, mapitags.PROP_ID(prop_tag)) stream = item.OpenProperty(prop_tag, pythoncom.IID_IStream, 0, 0) chunks = [] while 1: chunk = stream.Read(4096) if not chunk: break chunks.append(chunk) prop_val = "".join(chunks) outfile.write(prop_val)
class PropTags: """This Singleton class represents a set of all the possible mapi property tags. In general the mt module has pretty usable constants defined. However MAPI compllicates things with 'Named Properties' - which are not static, but have to be generated at runtime (not sure what all parameters change it...). This class includes all the mt properties as well as a set of hand selected named properties that are relevant for us here.""" PSETID_Address_GUID = '{00062004-0000-0000-C000-000000000046}' PSETID_Task_GUID = '{00062003-0000-0000-c000-000000000046}' def __init__(self, def_cf, config): self.name_hash = {} self.valu_hash = {} # We use the def_cf to lookup named properties. I suspect this will # have to be changed when we start supporting multiple profiles and # folders... self.def_olcf = def_cf self.def_cf = def_cf.get_fobj() self.config = config self.sync_tags = {} self.load_proptags() def load_proptags(self): # Load up all available properties from mt module for name, value in mt.__dict__.iteritems(): if name[:3] == 'PR_': # Store both the full ID (including type) and just the ID. # This is so PR_FOO_A and PR_FOO_W are still # differentiated. Note that in the following call, the value # hash will only contain the full ID. self.put(name=name, value=mt.PROP_ID(value)) self.put(name=name, value=value) # Now Add a bunch of named properties that we are specifically # interested in. self.put(name='ASYNK_PR_FILE_AS', value=self.get_file_as_prop_tag()) self.put(name='ASYNK_PR_EMAIL_1', value=self.get_email_prop_tag(1)) self.put(name='ASYNK_PR_EMAIL_2', value=self.get_email_prop_tag(2)) self.put(name='ASYNK_PR_EMAIL_3', value=self.get_email_prop_tag(3)) self.put(name='ASYNK_PR_IM_1', value=self.get_im_prop_tag(1)) self.put('ASYNK_PR_TASK_DUE_DATE', self.get_task_due_date_tag()) self.put('ASYNK_PR_TASK_STATE', self.get_task_state_tag()) self.put('ASYNK_PR_TASK_RECUR', self.get_task_recur_tag()) self.put('ASYNK_PR_TASK_COMPLETE', self.get_task_complete_tag()) self.put('ASYNK_PR_TASK_DATE_COMPLETED', self.get_task_date_completed_tag()) self.put('ASYNK_PR_CUSTOM_PROPS', self.get_custom_prop_tag()) self.load_sync_proptags() def load_sync_proptags(self): conf = self.config mydid = self.def_olcf.get_db().get_dbid() olps = conf.get_db_profiles(mydid) for pname, prof in olps.iteritems(): db1id = conf.get_profile_db1(pname) db2id = conf.get_profile_db2(pname) stag = conf.make_sync_label(pname, db1id if db2id == mydid else db2id) prop_tag_valu = self.get_gid_prop_tag(pname) self.put(name=stag, value=prop_tag_valu) self.sync_tags.update({stag: prop_tag_valu}) # self.put(name='ASYNK_PR_GCID', value=self.get_gid_prop_tag('gc')) # self.put(name='ASYNK_PR_BBID', value=self.get_gid_prop_tag('bb')) def valu(self, name): return self.name_hash[name] def name(self, valu): return self.valu_hash[valu] ## The rest of the methods below are internal to the class. def put(self, name, value): self.name_hash[name] = value self.valu_hash[value] = name # Routines to construct the property tags for named property. Intended to # be used only once in the constructor def get_email_prop_tag(self, n): """MAPI is crappy. Email addresses of the EX type do not conatain an SMTP address value for their PR_EMAIL_ADDRESS property tag. While the desired smtp address is present in the system the property tag that will help us fetch it is not a constant and will differ from system to system, and from PST file to PST file. The tag has to be dynamically generated. The routine jumps through the requisite hoops and appends those property tags to the supplied fields array. The augmented fields array is then returned. """ if n <= 1: try: return self.valu('ASYNK_PR_EMAIL_1') except KeyError, e: prop_name = [(self.PSETID_Address_GUID, 0x8084)] prop_type = mt.PT_UNICODE prop_ids = self.def_cf.GetIDsFromNames(prop_name, mapi.MAPI_CREATE) return (prop_type | prop_ids[0]) prev_tag = self.get_email_prop_tag(n - 1) prev_tag_id = mt.PROP_ID(prev_tag) prev_tag_type = mt.PROP_TYPE(prev_tag) return mt.PROP_TAG(prev_tag_type, prev_tag_id + 1)