📄 addin.py
字号:
_("Large selection")) return None ret = [] ms = self.manager.message_store for i in range(sel.Count): item = sel.Item(i+1) try: msgstore_message = ms.GetMessage(item) if msgstore_message.IsFilterCandidate(): ret.append(msgstore_message) except ms.NotFoundException: pass except ms.MsgStoreException, details: print "Unexpected error fetching message" traceback.print_exc() print details if len(ret) == 0: self.manager.ReportError(_("No filterable mail items are selected"), _("No selection")) return None if allow_multi: return ret return ret[0] # The Outlook event handlers def OnActivate(self): self.manager.LogDebug(3, "OnActivate", self) # See comments for OnNewExplorer below. # *sigh* - OnActivate seems too early too for Outlook 2000, # but Outlook 2003 seems to work here, and *not* the folder switch etc # Outlook 2000 crashes when a second window is created and we use this # event # OnViewSwitch however seems useful, so we ignore this. pass def OnSelectionChange(self): self.manager.LogDebug(3, "OnSelectionChange", self) # See comments for OnNewExplorer below. if not self.have_setup_ui: self.SetupUI() # Prime the button views. self.OnFolderSwitch() def OnClose(self): self.manager.LogDebug(3, "Explorer window closing", self) self.explorers_collection._DoDeadExplorer(self) self.explorers_collection = None self.toolbar = None self.close() # disconnect events. def OnBeforeFolderSwitch(self, new_folder, cancel): self.manager.LogDebug(3, "OnBeforeFolderSwitch", self) def OnFolderSwitch(self): self.manager.LogDebug(3, "OnFolderSwitch", self) # Yet another worm-around for our event timing woes. This may # be the first event ever seen for this explorer if, eg, # "Outlook Today" is the initial Outlook view. if not self.have_setup_ui: self.SetupUI() # Work out what folder we are in. outlook_folder = self.CurrentFolder if outlook_folder is None or \ outlook_folder.DefaultItemType != constants.olMailItem: show_delete_as = False show_recover_as = False else: show_delete_as = True show_recover_as = False try: mapi_folder = self.manager.message_store.GetFolder(outlook_folder) look_id = self.manager.config.filter.spam_folder_id if mapi_folder is not None and look_id: look_folder = self.manager.message_store.GetFolder(look_id) if mapi_folder == look_folder: # This is the Spam folder - only show "recover" show_recover_as = True show_delete_as = False # Check if uncertain look_id = self.manager.config.filter.unsure_folder_id if mapi_folder is not None and look_id: look_folder = self.manager.message_store.GetFolder(look_id) if mapi_folder == look_folder: show_recover_as = True show_delete_as = True except: print "Error finding the MAPI folders for a folder switch event" # As this happens once per move, we should only display it once. self.manager.ReportErrorOnce(_( "There appears to be a problem with the SpamBayes" " configuration\r\n\r\nPlease select the SpamBayes" " manager, and run the\r\nConfiguration Wizard to" " reconfigure the filter."), _("Invalid SpamBayes Configuration")) traceback.print_exc() if self.but_recover_as is not None: self.but_recover_as.Visible = show_recover_as if self.but_delete_as is not None: self.but_delete_as.Visible = show_delete_as def OnBeforeViewSwitch(self, new_view, cancel): self.manager.LogDebug(3, "OnBeforeViewSwitch", self) def OnViewSwitch(self): self.manager.LogDebug(3, "OnViewSwitch", self) if not self.have_setup_ui: self.SetupUI()# Events from our "Explorers" collection (not an Explorer instance)class ExplorersEvent: def Init(self, manager): assert manager self.manager = manager self.explorers = [] self.button_event_map = {} def Close(self): while self.explorers: self._DoDeadExplorer(self.explorers[0]) self.explorers = None def _DoNewExplorer(self, explorer): explorer = DispatchWithEvents(explorer, ExplorerWithEvents) explorer.Init(self.manager, self) self.explorers.append(explorer) return explorer def _DoDeadExplorer(self, explorer): self.explorers.remove(explorer) if len(self.explorers)==0: # No more explorers - disconnect all events. # (not doing this causes shutdown problems) for tag, button in self.button_event_map.items(): closer = getattr(button, "Close", None) if closer is not None: closer() self.button_event_map = {} def OnNewExplorer(self, explorer): # NOTE - Outlook has a bug, as confirmed by many on Usenet, in # that OnNewExplorer is too early to access the CommandBars # etc elements. We hack around this by putting the logic in # the first OnActivate call of the explorer itself. # Except that doesn't always work either - sometimes # OnActivate will cause a crash when selecting "Open in New Window", # so we tried OnSelectionChanges, which works OK until there is a # view with no items (eg, Outlook Today) - so at the end of the # day, we can never assume we have been initialized! self._DoNewExplorer(explorer)# The outlook Plugin COM object itself.class OutlookAddin: _com_interfaces_ = ['_IDTExtensibility2'] _public_methods_ = [] _reg_clsctx_ = pythoncom.CLSCTX_INPROC_SERVER _reg_clsid_ = "{3556EDEE-FC91-4cf2-A0E4-7489747BAB10}" _reg_progid_ = "SpamBayes.OutlookAddin" _reg_policy_spec_ = "win32com.server.policy.EventHandlerPolicy" def __init__(self): self.folder_hooks = {} self.application = None def OnConnection(self, application, connectMode, addin, custom): # Handle failures during initialization so that we are not # automatically disabled by Outlook. # Our error reporter is in the "manager" module, so we get that first locale.setlocale(locale.LC_NUMERIC, "C") # see locale comments above import manager try: self.application = application self.manager = None # if we die while creating it! # Create our bayes manager self.manager = manager.GetManager(application) assert self.manager.addin is None, "Should not already have an addin" self.manager.addin = self # Only now will the import of "spambayes.Version" work, as the # manager is what munges sys.path for us. from spambayes.Version import get_current_version v = get_current_version() vstring = v.get_long_version(ADDIN_DISPLAY_NAME) if not hasattr(sys, "frozen"): vstring += " from source" print vstring major, minor, spack, platform, ver_str = win32api.GetVersionEx() print "on Windows %d.%d.%d (%s)" % \ (major, minor, spack, ver_str) print "using Python", sys.version from time import asctime, localtime print "Log created", asctime(localtime()) self.explorers_events = None # create at OnStartupComplete if connectMode == constants.ext_cm_AfterStartup: # We are being enabled after startup, which means we don't get # the 'OnStartupComplete()' event - call it manually so we # bootstrap code that can't happen until startup is complete. self.OnStartupComplete(None) except: print "Error connecting to Outlook!" traceback.print_exc() # We can't translate this string, as we haven't managed to load # the translation tools. manager.ReportError( "There was an error initializing the SpamBayes addin\r\n\r\n" "Please re-start Outlook and try again.") def OnStartupComplete(self, custom): # Setup all our filters and hooks. We used to do this in OnConnection, # but a number of 'strange' bugs were reported which I suspect would # go away if done during this later event - and this later place # does seem more "correct" than the initial OnConnection event. if self.manager.never_configured: import dialogs dialogs.ShowWizard(0, self.manager) if self.manager.config.filter.enabled: # A little "sanity test" to help the user. If our status is # 'enabled', then it means we have previously managed to # convince the manager dialog to enable. If for some reason, # we no folder definitions but are 'enabled', then it is likely # something got hosed and the user doesn't know. # Note that we could display the config wizard here, but this # has rarely been reported in the wild since the very early # days, so could possibly die. if not self.manager.config.filter.spam_folder_id or \ not self.manager.config.filter.watch_folder_ids: msg = _("It appears there was an error loading your configuration\r\n\r\n" \ "Please re-configure SpamBayes via the SpamBayes dropdown") self.manager.ReportError(msg) # But continue on regardless. self.FiltersChanged() try: self.ProcessMissedMessages() except: print "Error processing missed messages!" traceback.print_exc() else: # We should include this fact in the log, as I suspect a # a number of "it doesn't work" bugs are simply related to not # being enabled. The new Wizard should help, but things can # still screw up. self.manager.LogDebug(0, _("*** SpamBayes is NOT enabled, so " \ "will not filter incoming mail. ***")) # Toolbar and other UI stuff must be setup once startup is complete. explorers = self.application.Explorers if self.manager is not None: # If we successfully started up. # and Explorers events so we know when new explorers spring into life. self.explorers_events = WithEvents(explorers, ExplorersEvent) self.explorers_events.Init(self.manager) # And hook our UI elements to all existing explorers for i in range(explorers.Count): explorer = explorers.Item(i+1) explorer = self.explorers_events._DoNewExplorer(explorer) explorer.OnFolderSwitch() def ProcessMissedMessages(self): from time import clock config = self.manager.config.filter manager = self.manager field_name = manager.config.general.field_score_name for folder in manager.message_store.GetFolderGenerator( config.watch_folder_ids, config.watch_include_sub): event_hook = self._GetHookForFolder(folder) # Note event_hook may be none in some strange cases where we # were unable to hook the events for the folder. This is # generally caused by a temporary Outlook issue rather than a # problem of ours we need to address. if event_hook is None: manager.LogDebug(0, "Skipping processing of missed messages in folder '%s', " "as it is not available" % folder.name) elif event_hook.use_timer: print "Processing missed spam in folder '%s' by starting a timer" \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -