📄 autoconfigure.py
字号:
#!/usr/bin/env python"""Automatically set up the user's mail client and SpamBayes.Example usage: >>> configure("mailer name")Where "mailer name" is any of the names below.Currently works with: o Eudora (POP3/SMTP only) o Mozilla Mail (POP3/SMTP only) o M2 (Opera Mail) (POP3/SMTP only) o Outlook Express (POP3/SMTP only) o PocoMail (POP3/SMTP only)To do: o Establish which mail client(s) are installed in a more clever way. o This will create some unnecessary proxies in some cases. For example, if I have my client set up to get mail from pop.example.com for the user 'tmeyer' and the user 'tonym', two proxies will be created, but only one is necessary. We should check the existing proxies before adding a new one. o Other mail clients? Other platforms? o This won't work all that well if multiple mail clients are used (they will end up trying to use the same ports). In such a case, we really need to keep track of if the server is being proxied already, and reuse ports, but this is complicated. o We currently don't make any moves to protect the original file, so if something does wrong, it's corrupted. We also write into the file, rather than a temporary one and then copy across. This should all be fixed. Richie's suggestion is for the script to create a clone of an existing account with the new settings. Then people could test the cloned account, and if they're happy with it they can either delete their old account or delete the new one and run the script again in "modify" rather than "clone" mode. This sounds like a good idea, although a lot of work... o Suggestions?"""# 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>"__credits__ = "All the Spambayes folk."try: True, Falseexcept NameError: # Maintain compatibility with Python 2.2 True, False = 1, 0## Tested with:## o Eudora 5.2 on Windows XP## o Mozilla 1.3 on Windows XP## o Opera 7.11 on Windows XP## o Outlook Express 6 on Windows XPimport reimport osimport sysimport typesimport socketimport shutilimport StringIOimport ConfigParsertry: import win32gui import win32api import win32con import pywintypes from win32com.shell import shell, shellconexcept ImportError: # The ImportError is delayed until these are needed - if we # did it here, the functions that don't need these would still # fail. (And having "import win32api" in lots of functions # didn't seem to make much sense). win32api = win32con = shell = shellcon = win32gui = pywintypes = Nonefrom spambayes import oe_mailboxfrom spambayes import OptionsClassfrom spambayes.Options import options, optionsPathnamedef move_to_next_free_port(port): # Increment port until we get to one that isn't taken. # I doubt this will work if there is a firewall that prevents # localhost connecting to particular ports, but I'm not sure # how else we can do this - Richie says that bind() doesn't # necessarily fail if the port is already bound. while True: try: port += 1 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("127.0.0.1", port)) s.close() except socket.error: portStr = str(port) if portStr in options["pop3proxy", "listen_ports"] or \ portStr in options["smtpproxy", "listen_ports"]: continue else: return port# Let's be safe and use high ports, starting at 1110 and 1025, and going up# as required.pop_proxy_port = move_to_next_free_port(1109)smtp_proxy_port = move_to_next_free_port(1024)def configure_eudora(config_location): """Configure Eudora to use the SpamBayes POP3 and SMTP proxies, and configure SpamBayes to proxy the servers that Eudora was connecting to. """ ini_filename = "%s%seudora.ini" % (config_location, os.sep) c = ConfigParser.ConfigParser() c.read(ini_filename) translate = {("PopServer", "POPPort") : "pop3proxy", ("SMTPServer", "SMTPPort") : "smtpproxy", } pop_proxy = pop_proxy_port smtp_proxy = smtp_proxy_port results = [] for sect in c.sections(): if sect.startswith("Persona-") or sect == "Settings": if c.get(sect, "UsesIMAP") == "0": # Eudora stores the POP3 server name in two places. # Why? Who cares. We do the popaccount one # separately, because it also has the username. p = c.get(sect, "popaccount") c.set(sect, "popaccount", "%s@localhost" % \ (p[:p.index('@')],)) for (eud_name, eud_port), us_name in translate.items(): try: port = c.get(sect, eud_port) except ConfigParser.NoOptionError: port = None if us_name.lower()[:4] == "pop3": if port is None: port = 110 pop_proxy = move_to_next_free_port(pop_proxy) proxy_port = pop_proxy else: if port is None: port = 25 smtp_proxy = move_to_next_free_port(smtp_proxy) proxy_port = smtp_proxy server = "%s:%s" % (c.get(sect, eud_name), port) options[us_name, "remote_servers"] += (server,) options[us_name, "listen_ports"] += (proxy_port,) results.append("[%s] Proxy %s on localhost:%s" % \ (sect, server, proxy_port)) c.set(sect, eud_name, "localhost") c.set(sect, eud_port, proxy_port) else: # Setup imapfilter instead pass out = file(ini_filename, "w") c.write(out) out.close() options.update_file(optionsPathname) # Setup filtering rule # This assumes that the spam and unsure folders already exist! # (Creating them shouldn't be that difficult - it's just a mbox file, # and I think the .toc file is automatically created). Left for # another day, however. filter_filename = "%s%sFilters.pce" % (config_location, os.sep) spam_folder_name = "Junk" unsure_folder_name = "Possible Junk" header_name = options["Headers", "classification_header_name"] spam_tag = options["Headers", "header_spam_string"] unsure_tag = options["Headers", "header_unsure_string"] # We are assuming that a rules file already exists, otherwise there # is a bit more to go at the top. filter_rules = "rule SpamBayes-Spam\n" \ "transfer %s.mbx\n" \ "incoming\n" \ "header %s\n" \ "verb contains\n" \ "value %s\n" \ "conjunction ignore\n" \ "header \n" \ "verb contains\n" \ "value \n" \ "rule SpamBayes-Unsure\n" \ "transfer %s.mbx\n" \ "incoming\n" \ "header %s\n" \ "verb contains\n" \ "value %s\n" \ "conjunction ignore\n" \ "header \n" \ "verb contains\n" \ "value \n" % (spam_folder_name, header_name, spam_tag, unsure_folder_name, header_name, unsure_tag) filter_file = file(filter_filename, "a") filter_file.write(filter_rules) filter_file.close() return resultsdef configure_mozilla(config_location): """Configure Mozilla to use the SpamBayes POP3 and SMTP proxies, and configure SpamBayes to proxy the servers that Mozilla was connecting to.""" prefs_file = file("%s%sprefs.js" % (config_location, os.sep), "r") prefs = prefs_file.read() prefs_file.close() save_prefs = prefs pop_accounts = {} smtp_accounts = {} r = re.compile(r"user_pref\(\"mail.server.server(\d+).(real)?hostname\", \"([^\"]*)\"\);") current_pos = 0 results = [] while True: m = r.search(prefs[current_pos:]) if not m: break server_num = m.group(1) real = m.group(2) or '' server = m.group(3) current_pos += m.end() old_pref = 'user_pref("mail.server.server%s.%shostname", "%s");' % \ (server_num, real, server) # Find the port, if there is one port_string = 'user_pref("mail.server.server%s.port", ' % \ (server_num,) port_loc = prefs.find(port_string) if port_loc == -1: port = "110" old_port = None else: loc_plus_len = port_loc + len(port_string) end_of_number = loc_plus_len + prefs[loc_plus_len:].index(')') port = prefs[loc_plus_len : end_of_number] old_port = "%s%s);" % (port_string, port) # Find the type of connection type_string = 'user_pref("mail.server.server%s.type", "' % \ (server_num,) type_loc = prefs.find(type_string) if type_loc == -1: # no type, so ignore this one continue type_loc += len(type_string) account_type = prefs[type_loc : \ type_loc + prefs[type_loc:].index('"')] if account_type == "pop3": new_pref = 'user_pref("mail.server.server%s.%shostname", ' \ '"127.0.0.1");' % (server_num, real) if not pop_accounts.has_key(server_num) or real: pop_accounts[server_num] = (new_pref, old_pref, old_port, server, port) elif account_type == "imap": # Setup imapfilter instead pass proxy_port = pop_proxy_port for num, (pref, old_pref, old_port, server, port) in pop_accounts.items():
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -