📄 pop3proxy_tray.py
字号:
#!/usr/bin/env python"""A script to provide an icon in the Windows taskbar tray to control thePOP3 proxy."""# This module is part of the spambayes project, which is Copyright 2002-3# The Python Software Foundation and is covered by the Python Software# Foundation license.__author__ = "Tony Meyer <ta-meyer@ihug.co.nz>, Adam Walker"__credits__ = "Mark Hammond, all the Spambayes folk."try: True, Falseexcept NameError: # Maintain compatibility with Python 2.2 True, False = 1, 0# Heavily based on the win32gui_taskbar.py demo from Mark Hammond's# win32 extensions.import osimport sysimport webbrowserimport threadimport tracebackverbose = 0# This should just be imported from dialogs.dlgutils, but# I'm not sure that we can import from the Outlook2000# directory, because I don't think it gets installed.##from spambayes.Outlook2000.dialogs.dlgutils import SetWaitCursordef SetWaitCursor(wait): import win32gui, win32con if wait: hCursor = win32gui.LoadCursor(0, win32con.IDC_WAIT) else: hCursor = win32gui.LoadCursor(0, 0) win32gui.SetCursor(hCursor)import win32conimport winerrorfrom win32api import *from win32gui import *from win32api import error as win32api_errorfrom win32service import *# If we are not running in a console, redirect all print statements to the# win32traceutil collector.# You can view output either from Pythonwin's "Tools->Trace Collector Debugging Tool",# or simply run "win32traceutil.py" from a command prompt.try: GetConsoleTitle()except win32api_error: # No console - if we are running from Python sources, # redirect to win32traceutil, but if running from a binary # install, redirect to a log file. # Want to move to logging module later, so for now, we # hack together a simple logging strategy. if hasattr(sys, "frozen"): temp_dir = GetTempPath() for i in range(3,0,-1): try: os.unlink(os.path.join(temp_dir, "SpamBayesServer%d.log" % (i+1))) except os.error: pass try: os.rename( os.path.join(temp_dir, "SpamBayesServer%d.log" % i), os.path.join(temp_dir, "SpamBayesServer%d.log" % (i+1)) ) except os.error: pass # Open this log, as unbuffered so crashes still get written. sys.stdout = open(os.path.join(temp_dir,"SpamBayesServer1.log"), "wt", 0) sys.stderr = sys.stdout else: import win32traceutil# Work out our "application directory", which is# the directory of our main .py/.exe file we# are running from.try: if hasattr(sys, "frozen"): if sys.frozen == "dll": # Don't think we will ever run as a .DLL, but... this_filename = win32api.GetModuleFileName(sys.frozendllhandle) else: this_filename = os.path.abspath(sys.argv[0]) else: this_filename = os.path.abspath(__file__)except NameError: # no __file__ this_filename = os.path.abspath(sys.argv[0])this_dir = os.path.dirname(this_filename)if not hasattr(sys, "frozen"): # Allow for those without SpamBayes on the PYTHONPATH sys.path.insert(-1, this_dir) sys.path.insert(-1, os.path.dirname(this_dir)) sys.path.insert(-1, os.path.join(os.path.dirname(this_dir),"scripts"))import sb_serverfrom spambayes import Dibblerfrom spambayes.Options import optionsWM_TASKBAR_NOTIFY = win32con.WM_USER + 20START_STOP_ID = 1024runningStatus = (SERVICE_START_PENDING, SERVICE_RUNNING, SERVICE_CONTINUE_PENDING)stoppedStatus = (SERVICE_PAUSED, SERVICE_STOP_PENDING, SERVICE_STOPPED)serviceName = "pop3proxy"def IsServerRunningAnywhere(): import win32event mutex_name = "SpamBayesServer" try: hmutex = win32event.CreateMutex(None, True, mutex_name) try: return GetLastError()==winerror.ERROR_ALREADY_EXISTS finally: hmutex.Close() except win32event.error, details: if details[0] != winerror.ERROR_ACCESS_DENIED: raise # Mutex created by some other user - it does exist! return Trueclass MainWindow(object): def __init__(self): # The ordering here is important - it is the order that they will # appear in the menu. As dicts don't have an order, this means # that the order is controlled by the id. Any items where the # function is None will appear as separators. self.control_functions = {START_STOP_ID : ("Stop SpamBayes", self.Stop), 1025 : ("-", None), 1026 : ("Review messages ...", self.OpenReview), 1027 : ("View information ...", self.OpenInterface), 1028 : ("Configure ...", self.OpenConfig), 1029 : ("Check for latest version", self.CheckVersion), 1030 : ("-", None), # This could become a submenu, like the Outlook plug-in has, at # some point, if necessary. For the moment, the only help is a # simple troubleshooting guide, so we'll just open that. 1031 : ("Help", self.GetHelp), 1032 : ("-", None), 1099 : ("Exit SpamBayes", self.OnExit), } msg_TaskbarRestart = RegisterWindowMessage("TaskbarCreated"); message_map = { msg_TaskbarRestart: self.OnTaskbarRestart, win32con.WM_DESTROY: self.OnDestroy, win32con.WM_COMMAND: self.OnCommand, WM_TASKBAR_NOTIFY : self.OnTaskbarNotify, } self.have_prepared_state = False self.last_started_state = None # Only bothering to try the service on Windows NT platforms self.use_service = \ GetVersionEx()[3]==win32con.VER_PLATFORM_WIN32_NT # Create the Window. hinst = GetModuleHandle(None) # This will replaced with a real configure dialog later # This is mainly to work around not being able to register a window # class with Python 2.3 dialogTemplate = [['SpamBayes', (14, 10, 246, 187), -1865809852 & ~win32con.WS_VISIBLE, None, (8, 'Tahoma')],] self.hwnd = CreateDialogIndirect(hinst, dialogTemplate, 0, message_map) # Get the custom icon startedIconPathName = "%s\\..\\windows\\resources\\sb-started.ico" % \ (os.path.dirname(sb_server.__file__),) stoppedIconPathName = "%s\\..\\windows\\resources\\sb-stopped.ico" % \ (os.path.dirname(sb_server.__file__),) if hasattr(sys, "frozen"): self.hstartedicon = self.hstoppedicon = None hexe = GetModuleHandle(None) icon_flags = win32con.LR_DEFAULTSIZE self.hstartedicon = LoadImage(hexe, 1000, win32con.IMAGE_ICON, 16, 16, icon_flags) self.hstoppedicon = LoadImage(hexe, 1010, win32con.IMAGE_ICON, 16, 16, icon_flags) else: # If we have no icon we fail in all sorts of places - so may as # well make it here :) icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE self.hstartedicon = LoadImage(hinst, startedIconPathName, win32con.IMAGE_ICON, 16, 16, icon_flags) self.hstoppedicon = LoadImage(hinst, stoppedIconPathName, win32con.IMAGE_ICON, 16, 16, icon_flags) self._AddTaskbarIcon() self.started = IsServerRunningAnywhere() self.tip = None if self.use_service and not self.IsServiceAvailable(): print "Service not available. Using thread." self.use_service = False # Start up sb_server if not self.started: self.Start() else: print "The server is already running externally - not starting " \ "a local server" def _AddTaskbarIcon(self): flags = NIF_ICON | NIF_MESSAGE | NIF_TIP nid = (self.hwnd, 0, flags, WM_TASKBAR_NOTIFY, self.hstartedicon, "SpamBayes") try: Shell_NotifyIcon(NIM_ADD, nid) except win32api_error: # Apparently can be seen as XP is starting up. Certainly can # be seen if explorer.exe is not running when started. print "Ignoring error adding taskbar icon - explorer may not " \ "be running (yet)." # The TaskbarRestart message will fire in this case, and # everything will work out :) def BuildToolTip(self): tip = None if self.started: if self.use_service: tip = "SpamBayes running." else: tip = "SpamBayes %i spam %i ham %i unsure %i sessions %i active" %\ (sb_server.state.numSpams, sb_server.state.numHams, sb_server.state.numUnsure, sb_server.state.totalSessions, sb_server.state.activeSessions) else: tip = "SpamBayes is not running" return tip def UpdateIcon(self): flags = NIF_TIP | NIF_ICON if self.started: hicon = self.hstartedicon else: hicon = self.hstoppedicon self.tip = self.BuildToolTip() nid = (self.hwnd, 0, flags, WM_TASKBAR_NOTIFY, hicon, self.tip) if self.started: self.control_functions[START_STOP_ID] = ("Stop SpamBayes", self.Stop) else: self.control_functions[START_STOP_ID] = ("Start SpamBayes", self.Start) Shell_NotifyIcon(NIM_MODIFY, nid) def IsServiceAvailable(self): try: schSCManager = OpenSCManager(None, None, SC_MANAGER_CONNECT) schService = OpenService(schSCManager, serviceName, SERVICE_QUERY_STATUS) if schService: CloseServiceHandle(schService) return schService != None except win32api_error, details: if details[0] != winerror.ERROR_SERVICE_DOES_NOT_EXIST: print "Unexpected windows error querying for service" print details return False def GetServiceStatus(self): schSCManager = OpenSCManager(None, None, SC_MANAGER_CONNECT) schService = OpenService(schSCManager, serviceName, SERVICE_QUERY_STATUS) ssStatus = QueryServiceStatus(schService) CloseServiceHandle(schService) return ssStatus[1] def StartService(self): schSCManager = OpenSCManager(None, None, SC_MANAGER_CONNECT) schService = OpenService(schSCManager, serviceName, SERVICE_START | SERVICE_QUERY_STATUS) # we assume IsServiceAvailable() was called before ssStatus = QueryServiceStatus(schService) if ssStatus[1] in runningStatus: self.started = True CloseServiceHandle(schService) return StartService(schService, None) ssStatus = QueryServiceStatus(schService) dwStartTickCount = GetTickCount() dwOldCheckPoint = ssStatus[5] while ssStatus[1] == SERVICE_START_PENDING: dwWaitTime = ssStatus[6] / 10; if dwWaitTime < 1000: dwWaitTime = 1000 elif dwWaitTime > 10000: dwWaitTime = 10000 Sleep(dwWaitTime); ssStatus = QueryServiceStatus(schService) if ssStatus[5] > dwOldCheckPoint: dwStartTickCount = GetTickCount() dwOldCheckPoint = ssStatus[5] else:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -