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

📄 manager.py

📁 用python实现的邮件过滤器
💻 PY
📖 第 1 页 / 共 3 页
字号:
            print "* SpamBayes, and running a win32all version pre 154."            print "* If you work with multiple Outlook profiles, it is recommended"            print "* you upgrade - see http://starship.python.net/crew/mhammond"""        return profile_name    def LoadConfig(self):        # Insist on English numeric conventions in config file.        # See addin.py, and [725466] Include a proper locale fix in Options.py        import locale; locale.setlocale(locale.LC_NUMERIC, "C")        profile_name = self.GetProfileName()        self.config_filename = os.path.join(self.data_directory, profile_name + ".ini")        self.never_configured = not os.path.exists(self.config_filename)        # Now load it up        self._MergeConfigFile(self.config_filename)        # Set global verbosity from the options file.        self.verbose = self.config.general.verbose        if self.verbose:            self.LogDebug(self.verbose, "System verbosity set to", self.verbose)        # Do any migrations - first the old pickle into the new format.        self.MigrateOldPickle()        # Then any options we change (particularly any 'experimental' ones we        # consider important)        import config        config.MigrateOptions(self.options)        if self.verbose > 1:            print "Dumping loaded configuration:"            print self.options.display()            print "-- end of configuration --"    def MigrateOldPickle(self):        assert self.config is not None, "Must have a config"        pickle_filename = os.path.join(self.data_directory,                                       "default_configuration.pck")        try:            f = open(pickle_filename, 'rb')        except IOError:            self.LogDebug(1, "No old pickle file to migrate")            return        print "Migrating old pickle '%s'" % pickle_filename        try:            try:                old_config = cPickle.load(f)            except:                print "FAILED to load old pickle"                traceback.print_exc()                msg = _("There was an error loading your old\r\n" \                        "SpamBayes configuration file.\r\n\r\n" \                        "It is likely that you will need to re-configure\r\n" \                        "SpamBayes before it will function correctly.")                self.ReportError(msg)                # But we can't abort yet - we really should still try and                # delete it, as we aren't gunna work next time in this case!                old_config = None        finally:            f.close()        if old_config is not None:            for section, items in old_config.__dict__.items():                print " migrating section '%s'" % (section,)                # exactly one value wasn't in a section - now in "general"                dict = getattr(items, "__dict__", None)                if dict is None:                    dict = {section: items}                    section = "general"                for name, value in dict.items():                    sect = getattr(self.config, section)                    setattr(sect, name, value)        # Save the config, then delete the pickle so future attempts to        # migrate will fail.  We save first, so failure here means next        # attempt should still find the pickle.        self.LogDebug(1, "pickle migration doing initial configuration save")        try:            self.LogDebug(1, "pickle migration removing '%s'" % pickle_filename)            os.remove(pickle_filename)        except os.error:            msg = _("There was an error migrating and removing your old\r\n" \                    "SpamBayes configuration file.  Configuration changes\r\n" \                    "you make are unlikely to be reflected next\r\n" \                    "time you start Outlook.  Please try rebooting.")            self.ReportError(msg)    def GetClassifier(self):        """Return the classifier we're using."""        return self.classifier_data.bayes    def SaveConfig(self):        # Insist on english numeric conventions in config file.        # See addin.py, and [725466] Include a proper locale fix in Options.py        import locale; locale.setlocale(locale.LC_NUMERIC, "C")        # Update our runtime verbosity from the options.        self.verbose = self.config.general.verbose        print "Saving configuration ->", self.config_filename.encode("mbcs", "replace")        assert self.config and self.options, "Have no config to save!"        if self.verbose > 1:            print "Dumping configuration to save:"            print self.options.display()            print "-- end of configuration --"        self.options.update_file(self.config_filename)    def Save(self):        # No longer save the config here - do it explicitly when changing it        # (prevents lots of extra pickle writes, for no good reason.  Other        # alternative is a dirty flag for config - this is simpler)        if self.classifier_data.dirty:            self.classifier_data.Save()        else:            self.LogDebug(1, "Bayes database is not dirty - not writing")    def Close(self):        global _mgr        self._KillNotifyTimer()        self.classifier_data.Close()        self.config = self.options = None        if self.message_store is not None:            self.message_store.Close()            self.message_store = None        self.outlook = None        self.addin = None        # If we are the global manager, reset that        if _mgr is self:            _mgr = None    def score(self, msg, evidence=False):        """Score a msg.        If optional arg evidence is specified and true, the result is a        two-tuple            score, clues        where clues is a list of the (word, spamprob(word)) pairs that        went into determining the score.  Else just the score is returned.        """        email = msg.GetEmailPackageObject()        try:            return self.classifier_data.bayes.spamprob(bayes_tokenize(email), evidence)        except AssertionError:            # See bug 706520 assert fails in classifier            # For now, just tell the user.            msg = _("It appears your SpamBayes training database is corrupt.\r\n\r\n" \                    "We are working on solving this, but unfortunately you\r\n" \                    "must re-train the system via the SpamBayes manager.")            self.ReportErrorOnce(msg)            # and disable the addin, as we are hosed!            self.config.filter.enabled = False            raise    def GetDisabledReason(self):        # Gets the reason why the plugin can not be enabled.        # If return is None, then it can be enabled (and indeed may be!)        # Otherwise return is the string reason        config = self.config.filter        ok_to_enable = operator.truth(config.watch_folder_ids)        if not ok_to_enable:            return _("You must define folders to watch for new messages.  " \                     "Select the 'Filtering' tab to define these folders.")        ok_to_enable = operator.truth(config.spam_folder_id)        if not ok_to_enable:            return _("You must define the folder to receive your certain spam.  " \                     "Select the 'Filtering' tab to define this folder.")        # Check that the user hasn't selected the same folder as both        # 'Spam' or 'Unsure', and 'Watch' - this would confuse us greatly.        ms = self.message_store        unsure_folder = None # unsure need not be specified.        if config.unsure_folder_id:            try:                unsure_folder = ms.GetFolder(config.unsure_folder_id)            except ms.MsgStoreException, details:                return _("The unsure folder is invalid: %s") % (details,)        try:            spam_folder = ms.GetFolder(config.spam_folder_id)        except ms.MsgStoreException, details:            return _("The spam folder is invalid: %s") % (details,)        if ok_to_enable:            for folder in ms.GetFolderGenerator(config.watch_folder_ids,                                                config.watch_include_sub):                bad_folder_type = None                if unsure_folder is not None and unsure_folder == folder:                    bad_folder_type = _("unsure")                    bad_folder_name = unsure_folder.GetFQName()                if spam_folder == folder:                    bad_folder_type = _("spam")                    bad_folder_name = spam_folder.GetFQName()                if bad_folder_type is not None:                    return _("You can not specify folder '%s' as both the " \                             "%s folder, and as being watched.") \                             % (bad_folder_name, bad_folder_type)        return None    def ShowManager(self):        import dialogs        dialogs.ShowDialog(0, self, self.config, "IDD_MANAGER")        # And re-save now, just incase Outlook dies on the way down.        self.SaveConfig()        # And update the cutoff values in bayes_options (which the        # stats use) to our thresholds.        bayes_options["Categorization", "spam_cutoff"] = \                                        self.config.filter.spam_threshold \                                        / 100.0        bayes_options["Categorization", "ham_cutoff"] = \                                        self.config.filter.unsure_threshold \                                        / 100.0        # And tell the addin that our filters may have changed.        if self.addin is not None:            self.addin.FiltersChanged()    def ShowFilterNow(self):        import dialogs        dialogs.ShowDialog(0, self, self.config, "IDD_FILTER_NOW")        # And re-save now, just incase Outlook dies on the way down.        self.SaveConfig()    def ShowHtml(self,url):        """Displays the main SpamBayes documentation in your Web browser"""        import sys, os, urllib        if urllib.splittype(url)[0] is None: # just a file spec            if hasattr(sys, "frozen"):                # New binary is in ../docs/outlook relative to executable.                fname = os.path.join(os.path.dirname(sys.argv[0]),                                     "../docs/outlook",                                     url)                if not os.path.isfile(fname):                    # Still support same directory as to the executable.                    fname = os.path.join(os.path.dirname(sys.argv[0]),                                         url)            else:                # (ie, main Outlook2000) dir                fname = os.path.join(os.path.dirname(__file__),                                        url)            fname = os.path.abspath(fname)            if not os.path.isfile(fname):                self.ReportError("Can't find "+url)                return            url = fname        # else assume it is valid!        from dialogs import SetWaitCursor        SetWaitCursor(1)        os.startfile(url)        SetWaitCursor(0)    def HandleNotification(self, disposition):        if self.config.notification.notify_sound_enabled:            if disposition == "Yes":                self.received_spam += 1            elif disposition == "No":                self.received_ham += 1            else:                self.received_unsure += 1            self._StartNotifyTimer()            def _StartNotifyTimer(self):        # First kill any existing timer        self._KillNotifyTimer()        # And start a new timer.        delay = self.config.notification.notify_accumulate_delay        self._DoStartNotifyTimer(delay)            def _DoStartNotifyTimer(self, delay):        assert thread.get_ident() == self.owner_thread_ident        assert self.notify_timer_id is None, "Shouldn't start a timer when already have one"        assert isinstance(delay, types.FloatType), "Timer values are float seconds"        # And start a new timer.        assert delay, "No delay means no timer!"        delay = int(delay*1000) # convert to ms.        self.notify_timer_id = timer.set_timer(delay, self._NotifyTimerFunc)        self.LogDebug(1, "Notify timer started - id=%d, delay=%d" % (self.notify_timer_id, delay))            def _KillNotifyTimer(self):        assert thread.get_ident() == self.owner_thread_ident        if self.notify_timer_id is not None:            timer.kill_timer(self.notify_timer_id)            self.LogDebug(2, "The notify timer with id=%d was stopped" % self.notify_timer_id)            self.notify_timer_id = None            def _NotifyTimerFunc(self, event, time):        # Kill the timer first        assert thread.get_ident() == self.owner_thread_ident        self.LogDebug(1, "The notify timer with id=%s fired" % self.notify_timer_id)        self._KillNotifyTimer()                import winsound        config = self.config.notification        sound_opts = winsound.SND_FILENAME | winsound.SND_ASYNC | winsound.SND_NOSTOP | winsound.SND_NODEFAULT        self.LogDebug(3, "Notify received ham=%d, unsure=%d, spam=%d" %                      (self.received_ham, self.received_unsure, self.received_spam))        if self.received_ham > 0 and len(config.notify_ham_sound) > 0:            self.LogDebug(3, "Playing ham sound '%s'" % config.notify_ham_sound)            winsound.PlaySound(config.notify_ham_sound, sound_opts)        elif self.received_unsure > 0 and len(config.notify_unsure_sound) > 0:            self.LogDebug(3, "Playing unsure sound '%s'" % config.notify_unsure_sound)            winsound.PlaySound(config.notify_unsure_sound, sound_opts)        elif self.received_spam > 0 and len(config.notify_spam_sound) > 0:            self.LogDebug(3, "Playing spam sound '%s'" % config.notify_spam_sound)            winsound.PlaySound(config.notify_spam_sound, sound_opts)        # Reset received counts to zero after notify.        self.received_ham = self.received_unsure = self.received_spam = 0_mgr = Nonedef GetManager(outlook = None):    global _mgr    if _mgr is None:        if outlook is None:            outlook = win32com.client.Dispatch("Outlook.Application")        _mgr = BayesManager(outlook=outlook)    return _mgrdef ShowManager(mgr):    mgr.ShowManager()def main(verbose_level = 1):    mgr = GetManager()    mgr.verbose = max(mgr.verbose, verbose_level)    ShowManager(mgr)    mgr.Save()    mgr.Close()    return 0def usage():    print "Usage: manager [-v ...]"    sys.exit(1)if __name__=='__main__':    verbose = 1    import getopt    opts, args = getopt.getopt(sys.argv[1:], "v")    if args:        usage()    for opt, val in opts:        if opt=="-v":            verbose += 1        else:            usage()    sys.exit(main(verbose))

⌨️ 快捷键说明

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