⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msgstore.py

📁 用python实现的邮件过滤器
💻 PY
📖 第 1 页 / 共 5 页
字号:
        store = self._GetMessageStore(store_id)        if flags is None:            flags = mapi.MAPI_MODIFY | USE_DEFERRED_ERRORS        return store.OpenEntry(item_id, iid, flags)    # Normalize an "external" hex ID to an internal binary ID.    def NormalizeID(self, item_id):        assert type(item_id)==type(()), \               "Item IDs must be a tuple (not a %r)" % item_id        try:            store_id, entry_id = item_id            return mapi.BinFromHex(store_id), mapi.BinFromHex(entry_id)        except ValueError:            raise MsgStoreException(None, "The specified ID '%s' is invalid" % (item_id,))    def _GetSubFolderIter(self, folder):        table = folder.GetHierarchyTable(0)        rows = mapi.HrQueryAllRows(table,                                   (PR_ENTRYID, PR_STORE_ENTRYID, PR_DISPLAY_NAME_A),                                   None,                                   None,                                   0)        for (eid_tag, eid), (store_eid_tag, store_eid), (name_tag, name) in rows:            item_id = store_eid, eid            sub = self._OpenEntry(item_id)            table = sub.GetContentsTable(0)            yield MAPIMsgStoreFolder(self, item_id, name, table.GetRowCount(0))            for store_folder in self._GetSubFolderIter(sub):                yield store_folder    def GetFolderGenerator(self, folder_ids, include_sub):        for folder_id in folder_ids:            try:                folder_id = self.NormalizeID(folder_id)            except MsgStoreException, details:                print "NOTE: Skipping invalid folder", details                continue            try:                folder = self._OpenEntry(folder_id)                table = folder.GetContentsTable(0)            except pythoncom.com_error, details:                # We will ignore *all* such errors for the time                # being, but give verbose details for results we don't                # know about                if IsNotAvailableCOMException(details):                    print "NOTE: Skipping folder for this session - temporarily unavailable"                elif IsNotFoundCOMException(details):                    print "NOTE: Skipping deleted folder"                else:                    print "WARNING: Unexpected MAPI error opening folder"                    print GetCOMExceptionString(details)                continue            rc, props = folder.GetProps( (PR_DISPLAY_NAME_A,), 0)            yield MAPIMsgStoreFolder(self, folder_id, props[0][1],                                     table.GetRowCount(0))            if include_sub:                for f in self._GetSubFolderIter(folder):                    yield f    def GetFolder(self, folder_id):        # Return a single folder given the ID.        try: # catch all MAPI errors            try:                # See if this is an Outlook folder item                sid = mapi.BinFromHex(folder_id.StoreID)                eid = mapi.BinFromHex(folder_id.EntryID)                folder_id = sid, eid            except AttributeError:                # No 'EntryID'/'StoreID' properties - a 'normal' ID                folder_id = self.NormalizeID(folder_id)            folder = self._OpenEntry(folder_id)            table = folder.GetContentsTable(0)            # Ensure we have a long-term ID.            rc, props = folder.GetProps( (PR_ENTRYID, PR_DISPLAY_NAME_A), 0)            folder_id = folder_id[0], props[0][1]            return MAPIMsgStoreFolder(self, folder_id, props[1][1],                                  table.GetRowCount(0))        except pythoncom.com_error, details:            raise MsgStoreExceptionFromCOMException(details)    def GetMessage(self, message_id):        # Return a single message given either the ID, or an Outlook        # message representing the object.        try: # catch all MAPI exceptions.            try:                eid = mapi.BinFromHex(message_id.EntryID)                sid = mapi.BinFromHex(message_id.Parent.StoreID)                message_id = sid, eid            except AttributeError:                # No 'EntryID'/'StoreID' properties - a 'normal' ID                message_id = self.NormalizeID(message_id)            mapi_object = self._OpenEntry(message_id)            hr, data = mapi_object.GetProps(MAPIMsgStoreMsg.message_init_props,0)            return MAPIMsgStoreMsg(self, data)        except pythoncom.com_error, details:            raise MsgStoreExceptionFromCOMException(details)    def YieldReceiveFolders(self, msg_class = "IPM.Note"):        # Get the main receive folder for each message store.        tab = self.session.GetMsgStoresTable(0)        rows = mapi.HrQueryAllRows(tab,                                    (PR_ENTRYID,),   # columns to retrieve                                    None,            # all rows                                    None,            # any sort order is fine                                    0)               # any # of results is fine        for row in rows:            # get first entry, a (property_tag, value) pair, for PR_ENTRYID            eid_tag, store_eid = row[0]            try:                store = self._GetMessageStore(store_eid)                folder_eid, ret_class = store.GetReceiveFolder(msg_class, 0)                hex_folder_eid = mapi.HexFromBin(folder_eid)                hex_store_eid = mapi.HexFromBin(store_eid)            except pythoncom.com_error, details:                if not IsNotAvailableCOMException(details):                    print "ERROR enumerating a receive folder -", details                continue            try:                folder = self.GetFolder((hex_store_eid, hex_folder_eid))                # For 'unconfigured' stores, or "stand-alone" PST files,                # this is a root folder - so not what we wan't.  Only return                # folders with a parent.                if folder.GetParent() is not None:                    yield folder            except MsgStoreException, details:                print "ERROR opening receive folder -", details                # but we just continue                continue_MapiTypeMap = {    type(0.0): PT_DOUBLE,    type(0): PT_I4,    type(''): PT_STRING8,    type(u''): PT_UNICODE,    # In Python 2.2.2, bool isn't a distinct type (type(1==1) is type(0)).#    type(1==1): PT_BOOLEAN,}def GetPropFromStream(mapi_object, prop_id):    try:        stream = mapi_object.OpenProperty(prop_id,                                          pythoncom.IID_IStream,                                          0, 0)        chunks = []        while 1:            chunk = stream.Read(4096)            if not chunk:                break            chunks.append(chunk)        return "".join(chunks)    except pythoncom.com_error, d:        print "Error getting property", mapiutil.GetPropTagName(prop_id), \              "from stream:", d        return ""def GetPotentiallyLargeStringProp(mapi_object, prop_id, row):    got_tag, got_val = row    if PROP_TYPE(got_tag) == PT_ERROR:        ret = ""        if got_val == mapi.MAPI_E_NOT_FOUND:            pass # No property for this message.        elif got_val == mapi.MAPI_E_NOT_ENOUGH_MEMORY:            # Too big for simple properties - get via a stream            ret = GetPropFromStream(mapi_object, prop_id)        else:            tag_name = mapiutil.GetPropTagName(prop_id)            err_string = mapiutil.GetScodeString(got_val)            print "Warning - failed to get property %s: %s" % (tag_name,                                                                err_string)    else:        ret = got_val    return ret# Some nasty stuff for getting RTF out of the messagedef GetHTMLFromRTFProperty(mapi_object, prop_tag = PR_RTF_COMPRESSED):    try:        rtf_stream = mapi_object.OpenProperty(prop_tag, pythoncom.IID_IStream,                                              0, 0)        html_stream = mapi.WrapCompressedRTFStream(rtf_stream, 0)        html = mapi.RTFStreamToHTML(html_stream)    except pythoncom.com_error, details:        if not IsNotFoundCOMException(details):            print "ERROR getting RTF body", details        return ""    # html may be None if RTF not originally from HTML, but here we    # always want a string    return html or ''class MAPIMsgStoreFolder:    def __init__(self, msgstore, id, name, count):        self.msgstore = msgstore        self.id = id        self.name = name        self.count = count    def __repr__(self):        return "<%s '%s' (%d items), id=%s/%s>" % (self.__class__.__name__,                                                self.name,                                                self.count,                                                mapi.HexFromBin(self.id[0]),                                                mapi.HexFromBin(self.id[1]))    def __eq__(self, other):        if other is None: return False        ceid = self.msgstore.session.CompareEntryIDs        return ceid(self.id[0], other.id[0]) and \               ceid(self.id[1], other.id[1])    def __ne__(self, other):        return not self.__eq__(other)    def GetID(self):        return mapi.HexFromBin(self.id[0]), mapi.HexFromBin(self.id[1])    def GetFQName(self):        parts = []        parent = self        while parent is not None:            parts.insert(0, parent.name)            try:                # Ignore errors fetching parents - the caller just wants the                # name - it may not be correctly 'fully qualified', but at                # least we get something.                parent = parent.GetParent()            except MsgStoreException:                break        # We now end up with [0] being an empty string??, [1] being the        # information store root folder name, etc.  Outlook etc all just        # use the information store name here.        if parts and not parts[0]:            del parts[0]        # Don't catch exceptions on the item itself - that is fatal,        # and should be caught by the caller.        # Replace the "root" folder name with the information store name        # as Outlook, our Folder selector etc do.        mapi_store = self.msgstore._GetMessageStore(self.id[0])        hr, data = mapi_store.GetProps((PR_DISPLAY_NAME_A,), 0)        name = data[0][1]        if parts:            # and replace with new name            parts[0] = name        else:            # This can happen for the very root folder (ie, parent of the            # top-level folder shown by Outlook.  This folder should *never*            # be used directly.            parts = [name]            print "WARNING: It appears you are using the top-level root of " \                  "the information store as a folder.  You probably don't "\                  "want to do that"        return "/".join(parts)    def _FolderFromMAPIFolder(self, mapifolder):        # Finally get the display name.        hr, data = mapifolder.GetProps((PR_ENTRYID, PR_DISPLAY_NAME_A,), 0)        eid = self.id[0], data[0][1]        name = data[1][1]        count = mapifolder.GetContentsTable(0).GetRowCount(0)        return MAPIMsgStoreFolder(self.msgstore, eid, name, count)    def GetParent(self):        # return a folder object with the parent, or None if there is no        # parent (ie, a top-level folder).  Raises an exception if there is        # an error fetching the parent (which implies something wrong with the        # item itself, rather than this being top-level)        try:            folder = self.msgstore._OpenEntry(self.id)            prop_ids = PR_PARENT_ENTRYID,            hr, data = folder.GetProps(prop_ids,0)            # Put parent ids together            parent_eid = data[0][1]            parent_id = self.id[0], parent_eid            if hr != 0 or \

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -