Exemplo n.º 1
0
    def get_default_cf(self):
        """Returns a tuple (IMAPIFolder, IMAPITable) that can be used to
           manipulate the Contacts folder and the associated meta
           information"""

        if self.def_cf:
            return self.def_cf

        msgstore = self.get_default_msgstore()
        if self.def_inbox is None:
            self.def_inbox = self.get_default_inbox()

        PR_IPM_CONTACTS_ENTRYID = 0x36D10102
        hr, props = self.def_inbox.GetProps((PR_IPM_CONTACTS_ENTRYID), 0)
        (tag, cf_id) = props[0]

        # check for errors
        if mapitags.PROP_TYPE(tag) == mapitags.PT_ERROR:
            raise TypeError('got PT_ERROR: %16x' % tag)
        elif mapitags.PROP_TYPE(tag) == mapitags.PT_BINARY:
            pass

        cf = msgstore.OpenEntry(cf_id, None, MOD_FLAG)

        return cf
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    def _populate_folders(self, fid=None, depth="  "):
        """Recurse through the entire folder hierarchy of the message store and
        collect the folders that we are interested in and populate the current
        MessageStore's folders object."""

        msgstore = self.get_obj()
        if not fid:
            fid = self.get_ipm_subtree_eid()
            if not fid:
                return

        folder = msgstore.OpenEntry(fid, None, MOD_FLAG)

        htable = folder.GetHierarchyTable(
            (mapi.CONVENIENT_DEPTH | mapi.MAPI_UNICODE))

        htable.SetColumns((mapitags.PR_ENTRYID, mapitags.PR_DISPLAY_NAME,
                           mapitags.PR_FOLDER_TYPE, mapitags.PR_SUBFOLDERS,
                           mapitags.PR_CONTENT_COUNT, mapitags.PR_DEPTH), 0)

        hr = htable.SeekRow(mapi.BOOKMARK_BEGINNING, 0)
        cnt = 0
        while True:
            rows = htable.QueryRows(1, 0)
            if len(rows) != 1:
                break

            ((eidt, eid), (dnt, dn), (ftt, ft), (sft, sf), (cct, cc),
             (dt, d)) = rows[0]
            cnt += 1

            if mapitags.PROP_TYPE(eidt) != mapitags.PT_ERROR:
                logging.debug(
                    '%sEID: %s Name: %-25s Type: %2d Has Sub: %5s '
                    'Depth: %2d Count: %d', depth, base64.b64encode(eid), dn,
                    ft, sf, d, cc)

                if ft == mapi.FOLDER_GENERIC:
                    ftype, f = OLFolder.get_folder_type(msgstore, eid)

                    if ftype == Folder.CONTACT_t:
                        ff = OLContactsFolder(self.ol, eid, dn, f, self)
                    elif ftype == Folder.TASK_t:
                        ff = OLTasksFolder(self.ol, eid, dn, f, self)
                    elif ftype == Folder.NOTE_t:
                        ff = OLNotesFolder(self.ol, eid, dn, f, self)
                    elif ftype == Folder.APPT_t:
                        ff = None
                        logging.info('Appointments not supported. Ignoring.')
                    else:
                        ff = None

                    if ff:
                        self.add_to_folders(ff)
                if sf and eid != self.get_del_items_eid():
                    self._populate_folders(fid=eid, depth=(depth + '  '))
            else:
                logging.error('Hm, Error... cnt: %2d', cnt)
Exemplo n.º 4
0
    def all_entries(self):
        """Return an array of entries in the current folder along with the
        corresponding google IDs in a format that can be directly written to
        the app_state.json file. The value from this for all folders will be
        written to the file as an array field."""

        ret = {'folder': self.name, 'store': self.store.name}
        entries = []

        ctable = self.get_contents()
        ctable.SetColumns(
            (self.prop_tags.valu('GOUT_PR_GCID'), mapitags.PR_ENTRYID), 0)

        while True:
            rows = ctable.QueryRows(1, 0)
            #if this is the last row then stop
            if len(rows) != 1:
                break

            (gid_tag, gid), (entryid_tag, entryid) = rows[0]

            if mapitags.PROP_TYPE(entryid_tag) == mapitags.PT_ERROR:
                logging.error('all_entries(): Error returned while iterating')
                gid = entryid = None
            else:
                entryid = base64.b64encode(entryid)
                if mapitags.PROP_TYPE(gid_tag) == mapitags.PT_ERROR:
                    # Was not synced for whatever reason.
                    logging.debug(
                        ('Folder:all_contents(): Prepped unsynched ' +
                         'items for b64encoded entryid: %s'), entryid)
                    gid = None

            entries.append({'eid': entryid, 'gcid': gid})

        ret.update({'entries': entries, 'entrycnt': len(entries)})
        return ret
Exemplo n.º 5
0
    def _clear_tag(self, tags, dryrun=False):
        """Clear any property whose property tag is the provided array."""

        logging.info('Querying MAPI for all data needed to clear flag')
        ctable = self.get_contents()

        cols = tuple([mt.PR_ENTRYID, mt.PR_DISPLAY_NAME]) + tuple(tags)
        ctable.SetColumns(cols, 0)
        logging.info('Data obtained from MAPI. Clearing one at a time')

        cnt = set()
        errs = set()
        i = 0
        store = self.get_msgstore().get_obj()
        hr = ctable.SeekRow(mapi.BOOKMARK_BEGINNING, 0)

        while True:
            rows = ctable.QueryRows(1, 0)
            # if this is the last row then stop
            if len(rows) != 1:
                break

            (entryid_tag, entryid), (name_tag, name) = rows[0][:2]

            i += 1
            for j in range(2, len(rows[0])):
                (gid_tag, gid) = rows[0][j]

                if mt.PROP_TYPE(gid_tag) != mt.PT_ERROR:
                    if not dryrun:
                        entry = store.OpenEntry(entryid, None,
                                                mapi.MAPI_BEST_ACCESS)
                        hr, ps = entry.DeleteProps([gid_tag])
                        if winerror.FAILED(hr):
                            logging.debug(
                                'Could not delete sync tag for: %s '
                                '(%s), due to: %s', name,
                                base64.b64encode(entryid),
                                winerror.HRESULT_CODE(hr))
                            errs.add(entryid)
                        else:
                            entry.SaveChanges(0)
                            cnt.add(entryid)

        logging.info('Entries cleared: %d. Errors: %d; i: %d', len(cnt),
                     len(errs), i)

        ctable.SetColumns(self.get_def_cols(), 0)
        return (len(errs) == 0)
Exemplo n.º 6
0
    def test_read_emails (self, itemid):
        eid = base64.b64decode(itemid)
        olcf = self.deff
        
        prop_tag = olcf.get_proptags().valu('ASYNK_PR_EMAIL_1')
        store    = olcf.get_msgstore()
        item     = store.get_obj().OpenEntry(eid, None, mapi.MAPI_BEST_ACCESS)

        hr, props = item.GetProps([prop_tag], mapi.MAPI_UNICODE)
        (tag, val) = props[0]
        if mt.PROP_TYPE(tag) == mt.PT_ERROR:
            print 'Prop_Tag (0x%16x) not found. Tag: 0x%16x' % (prop_tag,
                                                                (tag % (2**64)))
        else:
            print 'Email address found: ', val
Exemplo n.º 7
0
    def update_prop (self, prop_tag, prop_val, action):
        self.ol_item = self.get_ol_item()

        try:
            hr, props = self.ol_item.GetProps([prop_tag, mapitags.PR_ACCESS,
                                            mapitags.PR_ACCESS_LEVEL],
                                           mapi.MAPI_UNICODE)
            (tag, val)        = props[0]

            if mapitags.PROP_TYPE(tag) == mapitags.PT_ERROR:
                logging.debug('update_prop(): Prop %s (0x%16x) not found',
                              self.prop_tags.name(tag), prop_tag)
                val = ''            # This could be an int. FIXME
        except Exception, e:
            val = ''            # This could be an int. FIXME
Exemplo n.º 8
0
    def open(self):
        """ 
		Ensures we have a MAPI Session to the exchange server. Returns whether or 
		not a new connection was required (True or False). 
		"""
        if self.connection:
            # Nothing to do if the connection is already open.
            return False
        try:
            mapi.MAPIInitialize(None)
            if self.MAPIProfile <> None:
                MAPIProfile = self.MAPIProfile
            else:
                MAPIProfile = ""
            session = mapi.MAPILogonEx(
                0, MAPIProfile, None,
                mapi.MAPI_EXTENDED | mapi.MAPI_USE_DEFAULT)
            messagestorestable = session.GetMsgStoresTable(0)
            messagestorestable.SetColumns(
                (mapitags.PR_ENTRYID, mapitags.PR_DISPLAY_NAME_A,
                 mapitags.PR_DEFAULT_STORE), 0)
            while True:
                rows = messagestorestable.QueryRows(1, 0)
                #if this is the last row then stop
                if len(rows) != 1:
                    break
                row = rows[0]
                #if this is the default store then stop
                if ((mapitags.PR_DEFAULT_STORE, True) in row):
                    break
            # unpack the row and open the message store
            (eid_tag, eid), (name_tag, name), (def_store_tag, def_store) = row
            msgstore = session.OpenMsgStore(
                0, eid, None, mapi.MDB_NO_DIALOG | mapi.MAPI_BEST_ACCESS)
            # get the outbox
            hr, props = msgstore.GetProps((mapitags.PR_IPM_OUTBOX_ENTRYID), 0)
            (tag, eid) = props[0]
            #check for errors
            if mapitags.PROP_TYPE(tag) == mapitags.PT_ERROR:
                raise TypeError('got PT_ERROR instead of PT_BINARY: %s' % eid)
            self.connection = msgstore.OpenEntry(eid, None,
                                                 mapi.MAPI_BEST_ACCESS)
            return True
        except:
            if not self.fail_silently:
                raise
Exemplo n.º 9
0
    def verify_google_id (self):
        """Internal Test function to check if tag storage works.

        This is intended to be used for debug to retrieve and print the
        value of the Google Contacts Entry ID that is stored in MS
        Outlook.
        """

        prop_tag = self.cf.prop_tags.valu('GOUT_PR_GCID')

        hr, props = self.ol_item.GetProps([prop_tag], mapi.MAPI_UNICODE)
        (tag, val) = props[0]
        if mapitags.PROP_TYPE(tag) == mapitags.PT_ERROR:
            print 'Prop_Tag (0x%16x) not found. Tag: 0x%16x' % (prop_tag,
                                                                (tag % (2**64)))
        else:
            print 'Google ID found for contact. ID: ', val
Exemplo n.º 10
0
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)
Exemplo n.º 11
0
    def save(self):
        """Saves the current (new) contact to Outlook so it is
        persistent. Returns the itemid for the saved entry. Returns None in
        case of an error"""

        ## FIXME: This only takes care of new insertions. In-place updates are
        ## not taken care of by this. As of this time (May 2012) this method
        ## is only invoked for new contact creations. Updates are handld
        ## differently - see folder_ol:batch_update(), so this is not a bug,
        ## just that it would be good to have a single method deal with both
        ## cases.

        fobj = self.get_folder().get_fobj()
        msg = fobj.CreateMessage(None, 0)

        if not msg:
            return None

        olprops = self.get_olprops()

        hr, res = msg.SetProps(olprops)
        if (winerror.FAILED(hr)):
            logging.critical(
                'push_to_outlook(): unable to SetProps (code: %x)',
                winerror.HRESULT_CODE(hr))
            return None

        msg.SaveChanges(mapi.KEEP_OPEN_READWRITE)

        # Now that we have successfully saved the record, let's fetch the
        # entryid and return it to the caller.

        hr, props = msg.GetProps([mt.PR_ENTRYID], mapi.MAPI_UNICODE)
        (tag, val) = props[0]
        if mt.PROP_TYPE(tag) == mt.PT_ERROR:
            logging.error('save: EntryID could not be found. Weird')
            return None
        else:
            logging.debug('Successfully Wrote contact to Outlook : %-32s',
                          self.get_name())
            return self.set_entryid(val)
Exemplo n.º 12
0
    def enumerate_all_folders(self, folder_eid=None, depth='  '):
        """Walk through the entire folder hierarchy of the message store and
        print one line per folder with some critical information. 

        This is a recursive function. If you want to start enumerating at the
        root folder of the current message store, invoke this routine without
        any arguments. The defaults will ensure the root folder if fetched and
        folders will be recursively enumerated.
        """

        msgstore = self.get_obj()
        folder = msgstore.OpenEntry(folder_eid, None, MOD_FLAG)
        htable = folder.GetHierarchyTable(
            (mapi.CONVENIENT_DEPTH | mapi.MAPI_UNICODE))

        htable.SetColumns((mapitags.PR_ENTRYID, mapitags.PR_DISPLAY_NAME,
                           mapitags.PR_FOLDER_TYPE, mapitags.PR_SUBFOLDERS,
                           mapitags.PR_CONTENT_COUNT, mapitags.PR_DEPTH), 0)

        hr = htable.SeekRow(mapi.BOOKMARK_BEGINNING, 0)
        cnt = 0
        while True:
            rows = htable.QueryRows(1, 0)
            if len(rows) != 1:
                logging.debug('\tbreaking... %d', len(rows))
                break

            ((eidt, eid), (dnt, dn), (ftt, ft), (sft, sf), (cct, cc),
             (dt, d)) = rows[0]
            cnt += 1

            if mapitags.PROP_TYPE(eidt) != mapitags.PT_ERROR:
                logging.debug(
                    '%sEID: %s Name: %-25s Type: %2d Has Sub: %5s '
                    'Depth: %2d Count: %d', depth, base64.b64encode(eid), dn,
                    ft, sf, d, cc)
                if sf:
                    self.enumerate_all_folders(folder_eid=eid,
                                               depth=(depth + '  '))
            else:
                logging.error('H, error in enumeraate! :-)')
Exemplo n.º 13
0
def SendEMAPIMail(Subject="",
                  Message="",
                  SendTo=None,
                  SendCC=None,
                  SendBCC=None,
                  MAPIProfile=None):
    """Sends an email to the recipient using the extended MAPI interface
    Subject and Message are strings
    Send{To,CC,BCC} are comma-separated address lists
    MAPIProfile is the name of the MAPI profile"""

    # initialize and log on
    mapi.MAPIInitialize(None)
    session = mapi.MAPILogonEx(0, MAPIProfile, None,
                               mapi.MAPI_EXTENDED | mapi.MAPI_USE_DEFAULT)
    messagestorestable = session.GetMsgStoresTable(0)
    messagestorestable.SetColumns(
        (mapitags.PR_ENTRYID, mapitags.PR_DISPLAY_NAME_A,
         mapitags.PR_DEFAULT_STORE), 0)

    while True:
        rows = messagestorestable.QueryRows(1, 0)
        #if this is the last row then stop
        if len(rows) != 1:
            break
        row = rows[0]
        #if this is the default store then stop
        if ((mapitags.PR_DEFAULT_STORE, True) in row):
            break

    # unpack the row and open the message store
    (eid_tag, eid), (name_tag, name), (def_store_tag, def_store) = row
    msgstore = session.OpenMsgStore(0, eid, None,
                                    mapi.MDB_NO_DIALOG | mapi.MAPI_BEST_ACCESS)

    # get the outbox
    hr, props = msgstore.GetProps((mapitags.PR_IPM_OUTBOX_ENTRYID), 0)
    (tag, eid) = props[0]
    #check for errors
    if mapitags.PROP_TYPE(tag) == mapitags.PT_ERROR:
        raise TypeError('got PT_ERROR instead of PT_BINARY: %s' % eid)
    outboxfolder = msgstore.OpenEntry(eid, None, mapi.MAPI_BEST_ACCESS)

    # create the message and the addrlist
    message = outboxfolder.CreateMessage(None, 0)
    # note: you can use the resolveaddress functions for this. but you may get headaches
    pal = []

    def makeentry(recipient, recipienttype):
        return ((mapitags.PR_RECIPIENT_TYPE,
                 recipienttype), (mapitags.PR_SEND_RICH_INFO, False),
                (mapitags.PR_DISPLAY_TYPE, 0), (mapitags.PR_OBJECT_TYPE, 6),
                (mapitags.PR_EMAIL_ADDRESS_A,
                 recipient), (mapitags.PR_ADDRTYPE_A,
                              'SMTP'), (mapitags.PR_DISPLAY_NAME_A, recipient))

    if SendTo:
        pal.extend([
            makeentry(recipient, mapi.MAPI_TO)
            for recipient in SendTo.split(",")
        ])
    if SendCC:
        pal.extend([
            makeentry(recipient, mapi.MAPI_CC)
            for recipient in SendCC.split(",")
        ])
    if SendBCC:
        pal.extend([
            makeentry(recipient, mapi.MAPI_BCC)
            for recipient in SendBCC.split(",")
        ])

    # add the resolved recipients to the message
    message.ModifyRecipients(mapi.MODRECIP_ADD, pal)
    message.SetProps([(mapitags.PR_BODY_A, Message),
                      (mapitags.PR_SUBJECT_A, Subject)])

    # save changes and submit
    outboxfolder.SaveChanges(0)
    message.SubmitMessage(0)
Exemplo n.º 14
0
    def prep_sync_lists(self, destid, sl, synct_sto=None, cnt=0):
        """See the documentation in folder.Folder"""

        pname = sl.get_pname()
        conf = self.get_config()
        pdb1id = conf.get_profile_db1(pname)
        oldi = conf.get_itemids(pname)
        stag = conf.make_sync_label(pname, destid)

        logging.info('Querying MAPI for status of Contact Entries')

        ## Sort the DBIds so dest1 has the 'lower' ID
        dest1 = self.get_db().get_dbid()
        if dest1 > destid:
            dest2 = dest1
            dest1 = destid
        else:
            dest2 = destid

        ctable = self.get_contents()
        stp = self.get_proptags().sync_tags[stag]

        cols = (mt.PR_ENTRYID, mt.PR_LAST_MODIFICATION_TIME,
                mt.PR_DISPLAY_NAME, stp)
        ctable.SetColumns(cols, 0)

        i = 0

        synct_str = self.get_config().get_last_sync_start(pname)
        if not synct_sto:
            synct_sto = self.get_config().get_last_sync_stop(pname)
        synct = iso8601.parse(synct_sto)
        logging.debug('Last Start iso str : %s', synct_str)
        logging.debug('Last Stop  iso str : %s', synct_sto)
        logging.debug('Current Time       : %s', iso8601.tostring(time.time()))

        logging.info('Data obtained from MAPI. Processing...')

        newi = {}
        while True:
            rows = ctable.QueryRows(1, 0)
            #if this is the last row then stop
            if len(rows) != 1:
                break

            ((entryid_tag, entryid), (tt, modt), (name_tag, name),
             (gid_tag, gid)) = rows[0]
            b64_entryid = base64.b64encode(entryid)

            newi.update({b64_entryid: gid})

            if mt.PROP_TYPE(gid_tag) == mt.PT_ERROR:
                # Was not synced for whatever reason.
                logging.debug('New      Outlook Contact: %20s %s', name,
                              b64_entryid)
                sl.add_new(b64_entryid)
            else:
                if mt.PROP_TYPE(tt) == mt.PT_ERROR:
                    logging.debug('Impossible! Entry has no timestamp. i = %d',
                                  i)
                else:
                    if utils.utc_time_to_local_ts(modt) <= synct:
                        sl.add_unmod(b64_entryid)
                    else:
                        logging.debug('Modified Outlook Contact: %20s %s',
                                      name, b64_entryid)
                        sl.add_mod(b64_entryid, gid)

            i += 1
            if cnt != 0 and i >= cnt:
                break

        ctable.SetColumns(self.get_def_cols(), 0)

        kss = newi.keys()
        for x, y in oldi.iteritems():
            if not x in kss and not y in kss:
                logging.debug('Deleted Outlook Contact: %s:%s', x, y)
                if pdb1id == self.get_dbid():
                    sl.add_del(x, y)
                else:
                    sl.add_del(y, x)
Exemplo n.º 15
0
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)
Exemplo n.º 16
0
 def check_tag_error (self, tag):
     if mapitags.PROP_TYPE(tag) == mapitags.PT_ERROR:
         raise TypeError('got PT_ERROR: %16x' % tag)
     elif mapitags.PROP_TYPE(tag) == mapitags.PT_BINARY:
         pass