Example #1
0
    def get_olprops_from_mapi(self, entryid=None):
        """This reads the current contact's entire property list from MAPI and
        returns an array of property tuples"""

        oli = self.get_olitem()

        # prop_list = oli.GetPropList(mapi.MAPI_UNICODE)
        # hr, props = oli.GetProps(prop_list, 0)
        # hr, props = oli.GetProps(self.get_folder().get_def_cols(), 0)

        # The idea here is to get the full property list, and then filter down
        # to the ones we are really interested in. It was getting a bit
        # confusing, as the available property list was getting filtered
        # somewhere upstream, and we were not even seeing basic stuff like
        # PR_BODY and PR_GIVEN_NAME. The following approach works for now,
        # i.e. just set the properties we are keen on.

        hr, props = oli.GetProps(self.get_sync_fields(), 0)
        # hr, props = oli.GetProps(None, 0)

        if (winerror.FAILED(hr)):
            logging.error(
                'get_olprops_from_mapi: Unable to GetProps. Code: %x',
                winerror.HRESULT_CODE(hr))
            logging.error('Formatted error: %s', win32api.FormatMessage(hr))

        return props
Example #2
0
    def create_contact(self, name, email=None, org=None):
        """Save the current contact to Outlook, and returns the entryid of the
        entry."""

        logging.info('Saving to Outlook: %-32s ....', name)
        msg = self.def_cf.CreateMessage(None, 0)

        if not msg:
            return None

        self.props_list = [(mapitags.PR_MESSAGE_CLASS, "IPM.Contact")]
        self.props_list.append((mapitags.PR_DISPLAY_NAME, name))

        fileas_prop_tag = self.get_file_as_prop_tag()
        self.props_list.append((fileas_prop_tag, name))

        self.props_list.append((mapitags.PR_COMPANY_NAME, org))
        self.props_list.append((mapitags.PR_BODY, email))

        hr, res = msg.SetProps(self.props_list)
        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)
Example #3
0
    def get_ipm_subtree_eid (self):
        msgstore = self.get_obj()
        hr, ps   = msgstore.GetProps((mapitags.PR_IPM_SUBTREE_ENTRYID))
        if winerror.FAILED(hr):
            logging.error('Could not get subtree entryid for store: %s. '
                          'Error: 0x%x', self.get_name(),
                          winerror.HRESULT_CODE(hr))
            return None
        tag, eid = ps[0]

        return eid
Example #4
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)
Example #5
0
    def enumerate_ipm_folders (self):
        """Walk through all the folders in the IPM subtree of the message
        store and print one line per folder with some critical information.
        For more information on what a IPM Subtree is, look here:
        http://msdn.microsoft.com/en-us/library/cc815825.aspx """

        msgstore = self.get_obj()
        hr, ps   = msgstore.GetProps((mapitags.PR_IPM_SUBTREE_ENTRYID))
        if winerror.FAILED(hr):
            logging.error('Could not get subtree entryid for store: %s. '
                          'Error: 0x%x', self.get_name(),
                          winerror.HRESULT_CODE(hr))
            return
        tag, ipm_eid = ps[0]

        folder   = msgstore.OpenEntry(ipm_eid, None, MOD_FLAG)
        self.enumerate_all_folders(ipm_eid)
Example #6
0
    def del_itemids(self, itemids):
        """Delete the specified contacts from this folder if they exist. The
        return value is a pair of (success, [failed entrie]). success is true
        if and only all items were deleted successfully."""

        fobj = self.get_fobj()

        retv = True
        retf = []
        for iid in itemids:
            logging.info('Deleting ID: %s...', iid)
            eid = base64.b64decode(iid)
            hr = fobj.DeleteMessages([eid], 0, None, 0)
            if winerror.FAILED(hr):
                retv = False
                retf.append(base64.b64encode(eid))

        return retv, retf
Example #7
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)
Example #8
0
                          store.get_name(), str(e))
            return None

        cclass = OLFolder.get_cclass_from_ftype(ftype)
        try:
            nf = folder.CreateFolder(mapi.FOLDER_GENERIC, fname, 'Comment',
                                     None, 0)
            folder.SaveChanges(0)
        except Exception, e:
            logging.error('Failed to create new folder %s. CreateFolder '
                          'returned  error code: %s', fname,
                          str(e))
            return None

        hr, ps = nf.SetProps([(mapitags.PR_CONTAINER_CLASS, cclass)])
        if winerror.FAILED(hr):
            logging.error('Failed to Set Container class for newly created '
                          'folder %s. Hm. tough luck... Delete the sucker '
                          'manually from Outlook. Sorry for the bother. '
                          'Error Code retruned by SetProps: 0x%x',fname,
                          winerror.HRESULT_CODE(hr))
            return None
        
        hr, ps = nf.GetProps((mapitags.PR_ENTRYID))
        if winerror.FAILED(hr):
            logging.error('Failed to get Entry_ID for newly created '
                          'folder %s. Hm. tough luck... Delete the sucker '
                          'manually from Outlook. Sorry for the bother. '
                          'Error Code retruned by SetProps: 0x%x',fname,
                          winerror.HRESULT_CODE(hr))
            return None