#!/usr/local/bin/python2.3
"""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, False
except 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 XP
import re
import os
import sys
import types
import socket
import shutil
import StringIO
import ConfigParser
try:
import win32gui
import win32api
import win32con
import pywintypes
from win32com.shell import shell, shellcon
except 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 = None
from spambayes import oe_mailbox
from spambayes import OptionsClass
from spambayes.Options import options, optionsPathname
def 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 results
def 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():
server = "%s:%s" % (server, port)
proxy_port = move_to_next_free_port(proxy_port)
port_pref = 'user_pref("mail.server.server%s.port", %s);' % \
(num, proxy_port)
options["pop3proxy", "remote_servers"] += (server,)
options["pop3proxy", "listen_ports"] += (proxy_port,)
if old_port is None:
pref = "%s\n%s" % (pref, port_pref)
else:
save_prefs = save_prefs.replace(old_port, port_pref)
save_prefs = save_prefs.replace(old_pref, pref)
results.append("[%s] Proxy %s on localhost:%s" % \
(num, server, proxy_port))
# Do the SMTP server.
# Mozilla recommends that only advanced users setup more than one,
# so we'll just set that one up. Advanced users can setup SpamBayes
# themselves <wink>.
prefs = save_prefs
r = re.compile(r"user_pref\(\"mail.smtpserver.smtp(\d+).hostname\", \"([^\"]*)\"\);")
current_pos = 0
while True:
m = r.search(prefs[current_pos:])
if not m:
break
current_pos = m.end()
server_num = m.group(1)
server = m.group(2)
old_pref = 'user_pref("mail.smtpserver.smtp%s.hostname", ' \
'"%s");' % (server_num, server)
new_pref = 'user_pref("mail.smtpserver.smtp%s.hostname", ' \
'"127.0.0.1");' % (server_num,)
# Find the port
port_string = 'user_pref("mail.smtpserver.smtp1.port", '
port_loc = prefs.find(port_string)
if port_loc == -1:
port = "25"
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 = 'user_pref("mail.smtpserver.smtp%s.port", %s);' % \
(server_num, port)
smtp_accounts[server_num] = (new_pref, old_pref, old_port,
server, port)
proxy_port = smtp_proxy_port
for num, (pref, old_pref, old_port, server, port) in smtp_accounts.items():
server = "%s:%s" % (server, port)
proxy_port = move_to_next_free_port(proxy_port)
port_pref = 'user_pref("mail.smtpserver.smtp%s.port", %s);' % \
(num, proxy_port)
options["smtpproxy", "remote_servers"] += (server,)
options["smtpproxy", "listen_ports"] += (proxy_port,)
if old_port is None:
pref = "%s\n%s" % (pref, port_pref)
else:
save_prefs = save_prefs.replace(old_port, port_pref)
save_prefs = save_prefs.replace(old_pref, pref)
results.append("[%s] Proxy %s on localhost:%s" % \
(num, server, proxy_port))
prefs_file = file("%s%sprefs.js" % (config_location, os.sep), "w")
prefs_file.write(save_prefs)
prefs_file.close()
options.update_file(optionsPathname)
# Setup filtering rules.
# Assumes that the folders already exist! I don't know how difficult
# it would be to create new Mozilla mail folders.
filter_filename = "%s%smsgFilterRules.dat" % (config_location, os.sep)
store_name = "" # how do we get this?
spam_folder_url = "mailbox:////%s//Junk%20Mail" % (store_name,)
unsure_folder_url = "mailbox:////%s//Possible%20Junk" % (store_name,)
header_name = options["Headers", "classification_header_name"]
spam_tag = options["Headers", "header_spam_string"]
unsure_tag = options["Headers", "header_unsure_string"]
rule = 'name="SpamBayes-Spam"\n' \
'enabled="yes"\n' \
'type="1"\n' \
'action="Move to folder"\n' \
'actionValue="%s"\n' \
'condition="OR (\"%s\",contains,%s)"\n' \
'name="SpamBayes-Unsure"\n' \
'enabled="yes"\n' \
'type="1"\n' \
'action="Move to folder"\n' \
'actionValue="%s"\n' \
'condition="OR (\"%s\",contains,%s)"\n' % \
(spam_folder_url, header_name, spam_tag,
unsure_folder_url, header_name, unsure_tag)
# This should now be written to the file, but I'm not sure how we
# determine which subdirectory it goes into - does it have to go
# into them all?
# We are assuming that a rules file already exists, otherwise there
# is a bit more to go at the top.
return results
def configure_m2(config_location):
"""Configure M2 (Opera's mailer) to use the SpamBayes POP3 and SMTP
proxies, and configure SpamBayes to proxy the servers that M2 was
connecting to."""
ini_filename = os.path.join(config_location, "Mail", "accounts.ini")
ini_file = file(ini_filename, "r")
faked_up = StringIO.StringIO()
faked_up.write(";") # Missing at the start
faked_up.write(ini_file.read())
faked_up.seek(0)
ini_file.close()
c = ConfigParser.ConfigParser()
c.readfp(faked_up)
translate = {("Incoming Servername", "Incoming Port") : "pop3proxy",
("Outgoing Servername", "Outgoing Port") : "smtpproxy",
}
pop_proxy = pop_proxy_port
smtp_proxy = smtp_proxy_port
results = []
for sect in c.sections():
if sect.startswith("Account") and sect != "Accounts":
if c.get(sect, "Incoming Protocol") == "POP":
for (m2_name, m2_port), us_name in translate.items():
try:
port = c.get(sect, m2_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, m2_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, m2_name, "localhost")
c.set(sect, m2_port, proxy_port)
elif c.get(sect, "Incoming Protocol") == "IMAP":
# Setup imapfilter instead
pass
out = file(ini_filename, "w")
c.write(out)
out.close()
options.update_file(optionsPathname)
# Setting up a filter in M2 is very simple, but I'm not sure what the
# right rule is - M2 doesn't move mail, it just displays a subset.
# If someone can describe the best all-purpose rule, I'll pop it in
# here.
return results
def configure_outlook_express(unused):
"""Configure OE to use the SpamBayes POP3 and SMTP proxies, and
configure SpamBayes to proxy the servers that OE was connecting to."""
# Requires win32all to be available (or for someone to write a
# Mac version <wink>)
if win32api is None:
raise ImportError("win32 extensions required")
accounts = oe_mailbox.OEAccountKeys()
translate = {("POP3 Server", "POP3 Port") : "pop3proxy",
("SMTP Server", "SMTP Port") : "smtpproxy",
}
pop_proxy = pop_proxy_port
smtp_proxy = smtp_proxy_port
results = []
for proto, subkey, account in accounts:
if proto == "POP3":
for (server_key, port_key), sect in translate.items():
server = "%s:%s" % (account[server_key][0],
account[port_key][0])
if sect[:4] == "pop3":
pop_proxy = move_to_next_free_port(pop_proxy)
proxy = pop_proxy
else:
smtp_proxy = move_to_next_free_port(smtp_proxy)
proxy = smtp_proxy
options[sect, "remote_servers"] += (server,)
options[sect, "listen_ports"] += (proxy,)
win32api.RegSetValueEx(subkey, server_key, 0,
win32con.REG_SZ, "127.0.0.1")
win32api.RegSetValueEx(subkey, port_key, 0,
win32con.REG_SZ, str(proxy))
results.append("[%s] Proxy %s on localhost:%s" % \
(account["Account Name"][0], server, proxy))
elif proto == "IMAP4":
# Setup imapfilter instead.
pass
options.update_file(optionsPathname)
# Outlook Express rules are done in much the same way. Should one
# be set up to work with notate_to or notate_subject? (and set that
# option, obviously)
return results
def configure_pegasus_mail(config_location):
"""Configure Pegasus Mail to use the SpamBayes POP3 and SMTP proxies,
and configure SpamBayes to proxy the servers that Pegasus Mail was
connecting to."""
# We can't use ConfigParser here, as we want 'surgical' editing,
# so we want to use out OptionsClass. There is the additional trouble
# that the Pegasus Mail config file doesn't have a section header.
pop_proxy = pop_proxy_port
smtp_proxy = smtp_proxy_port
results = []
for filename in os.listdir(config_location):
if filename.lower().startswith("pop") or filename.lower().startswith("smt"):
full_filename = os.path.join(config_location, filename)
working_filename = "%s.tmp" % (filename, )
shutil.copyfile(filename, working_filename)
c = OptionsClass.OptionsClass()
c.merge_file(working_filename)
server = "%s:%s" % (c.get("all", "host"), c.get("all", "port"))
if filename[:3] == "pop":
pop_proxy = move_to_next_free_port(pop_proxy)
proxy = pop_proxy
sect = "pop3proxy"
else:
smtp_proxy = move_to_next_free_port(smtp_proxy)
proxy = smtp_proxy
sect = "smtpproxy"
options[sect, "remote_servers"] += (server,)
options[sect, "listen_ports"] += (proxy,)
# Write in the new options!!
c.set("all", "host", "127.0.0.1")
c.set("all", "port", proxy)
c.update_file(working_filename)
results.append("[%s] Proxy %s on localhost:%s" % \
(c.get("all", "title"), server, proxy))
elif filename.lower() == "IMAP.PM":
# Setup imapfilter instead.
pass
# Pegasus Mail has a 'weight' system for determining junk mail.
# The best plan would probably be to just add to this. Something like:
rules_filename = os.path.join(config_location, "spambust.dat")
header_name = options["Headers", "classification_header_name"]
spam_tag = options["Headers", "header_spam_string"]
unsure_tag = options["Headers", "header_unsure_string"]
ham_tag = options["Headers", "header_ham_string"]
spam_weight = 500
ham_weight = -500
unsure_weight = -50 # leave judgement up to the rest of the rules
rule = '# SpamBayes adjustments\n' \
'if header "%s" contains "%s" weight %s\n' \
'if header "%s" contains "%s" weight %s\n' \
'if header "%s" contains "%s" wieght %s\n\n' % \
(header_name, spam_tag, spam_weight,
header_name, unsure_tag, unsure_weight,
header_name, ham_tag, ham_weight)
rules_file = file(rules_filename, "a")
rules_file.write(rule)
rules_file.close()
return results
def pocomail_accounts_filename():
if win32api is None:
# If we don't have win32, then we don't know.
return ""
key = "Software\\Poco Systems Inc"
pop_proxy = pop_proxy_port
smtp_proxy = smtp_proxy_port
try:
reg = win32api.RegOpenKeyEx(win32con.HKEY_CURRENT_USER, key)
except pywintypes.error:
# It seems that we don't have PocoMail
return ""
else:
subkey_name = "%s\\%s" % (key, win32api.RegEnumKey(reg, 0))
reg = win32api.RegOpenKeyEx(win32con.HKEY_CURRENT_USER,
subkey_name)
pocomail_path = win32api.RegQueryValueEx(reg, "Path")[0]
return os.path.join(pocomail_path, "accounts.ini")
def configure_pocomail(pocomail_accounts_file):
if os.path.exists(pocomail_accounts_file):
f = open(pocomail_accounts_file, "r")
accountName = ""
pocomail_accounts = { }
# Builds the dictionary with all the existing accounts.
for line in f.readlines():
line = line.rstrip('\n\r')
if line == '':
continue
if line[0] == '[' and line[-1] == ']':
accountName = line[1:-1]
pocomail_accounts[accountName] = { }
else:
separator = line.find('=')
optionName = line[:separator]
optionValue = line[separator + 1:]
if optionName == "POPServer":
pop3 = optionValue.split(':')
if len(pop3) == 1:
pop3.append(110)
server = "%s:%s" % tuple(pop3)
proxy = pop_proxy
pop_proxy = move_to_next_free_port(pop_proxy)
if not server in options["pop3proxy", "remote_servers"]:
options["pop3proxy", "remote_servers"] += (server,)
options["pop3proxy", "listen_ports"] += (proxy,)
else:
serverIndex = 0
for remoteServer in options["pop3proxy",
"remote_servers"]:
if remoteServer == server:
break
serverIndex += 1
proxy = options["pop3proxy", "listen_ports"][serverIndex]
optionValue = "%s:%s" % ('localhost', proxy)
pocomail_accounts[accountName][optionName] = optionValue
f.close()
f = open(pocomail_accounts_file, "w")
for accountName in pocomail_accounts.keys():
f.write('[' + accountName + ']\n')
for optionName, optionValue in pocomail_accounts[accountName].items():
f.write("%s=%s\n" % (optionName, optionValue))
f.write('\n')
f.close()
options.update_file(optionsPathname)
# Add a filter to pocomail
pocomail_filters_file = os.path.join(pocomail_path, "filters.ini")
if os.path.exists(pocomail_filters_file):
f = open(pocomail_filters_file, "r")
pocomail_filters = { }
filterName = ""
for line in f.readlines():
line = line.rstrip('\n\r')
if line == '': continue
if line[0] == '[' and line[-1] == ']':
filterName = line[1:-1]
pocomail_filters[filterName] = []
elif line[0] != '{':
pocomail_filters[filterName].append(line)
f.close()
spamBayesFilter = 'spam,X-Spambayes-Classification,move,' \
'"Junk Mail",0,0,,,0,,,move,In,0,0,,0,,,' \
'move,In,0,0,,0,,,move,In,0,0,,0,,,move,' \
'In,0,0,,0,,,move,In,0,0,1,0'
if pocomail_filters.has_key("Incoming") and \
spamBayesFilter not in pocomail_filters["Incoming"]:
pocomail_filters["Incoming"].append(spamBayesFilter)
f = open(pocomail_filters_file, "w")
f.write('{ Filter list generated by PocoMail 3.01 (1661)' \
'- Licensed Version}\n')
for filterName in pocomail_filters.keys():
f.write('\n[' + filterName + ']\n')
for filter in pocomail_filters[filterName]:
f.write(filter + '\n')
f.close()
return []
def find_config_location(mailer):
"""Attempt to find the location of the config file for
the given mailer, to pass to the configure_* scripts
above."""
# Requires win32all to be available, until someone
# fixes the function to look in the right places for *nix/Mac.
if win32api is None:
raise ImportError("win32 extensions required")
if mailer in ["Outlook Express", ]:
# Outlook Express can be configured without a
# config location, because it's all in the registry.
return ""
windowsUserDirectory = shell.SHGetFolderPath(0,shellcon.CSIDL_APPDATA,0,0)
potential_locations = \
{"Eudora" : ("%(wud)s%(sep)sQualcomm%(sep)sEudora",),
"Mozilla" : \
("%(wud)s%(sep)sMozilla%(sep)sProfiles%(sep)s%(user)s",
"%(wud)s%(sep)sMozilla%(sep)sProfiles%(sep)sdefault",),
"M2" : ("%(wud)s%(sep)sOpera%(sep)sOpera7",),
"PocoMail" : (pocomail_accounts_filename(),),
}
# We try with the username that the user uses
# for Windows, even though that might not be the same as their profile
# names for mailers. We can get smarter later.
username = win32api.GetUserName()
loc_dict = {"sep" : os.sep,
"wud" : windowsUserDirectory,
"user" : username}
for loc in potential_locations[mailer]:
loc = loc % loc_dict
if os.path.exists(loc):
return loc
return None
def configure(mailer):
"""Automatically configure the specified mailer and SpamBayes."""
loc = find_config_location(mailer)
if loc is None:
# Can't set it up, so do nothing.
return
funcs = {"Eudora" : configure_eudora,
"Mozilla" : configure_mozilla,
"M2" : configure_m2,
"Outlook Express" : configure_outlook_express,
"PocoMail" : configure_pocomail,
}
return funcs[mailer](loc)
def is_installed(mailer):
"""Return True if we believe that the mailer is installed."""
# For the simpler mailers, we believe it is installed if the
# configuration path can be found and exists.
config_location = find_config_location(mailer)
if config_location:
if os.path.exists(config_location):
return True
return False
# For the ones based in the registry, we have different
# techniques.
if mailer == "Outlook Express":
if oe_mailbox.OEIsInstalled():
return True
return False
# If we don't know, guess that it isn't.
return False
def offer_to_configure(mailer):
"""If the mailer appears to be installed, offer to set it up for
SpamBayes (and SpamBayes for it)."""
# At the moment, the test we use to check if the mailer is installed
# is whether a valid path to the configuration file can be found.
# This is ok, except for those that are setup in the registry - there
# will always be a valid path, whether they are installed or not.
if find_config_location(mailer) is not None:
confirm_text = "Would you like %s setup for SpamBayes, and " \
"SpamBayes setup with your %s settings?\n" \
"(This is alpha software! We recommend that you " \
"only do this if you know how to re-setup %s " \
"if necessary.)" % (mailer, mailer, mailer)
ans = MessageBox(confirm_text, "Configure?",
win32con.MB_YESNO | win32con.MB_ICONQUESTION)
if ans == win32con.IDYES:
results = configure(mailer)
if results is None:
MessageBox("Configuration unsuccessful.", "Error",
win32con.MB_OK | win32con.MB_ICONERROR)
else:
text = "Configuration complete.\n\n" + "\n".join(results)
MessageBox(text, "Complete", win32con.MB_OK)
def GetConsoleHwnd():
"""Returns the window handle of the console window in which this script is
running, or 0 if not running in a console window. This function is taken
directly from Pythonwin\dllmain.cpp in the win32all source, ported to
Python."""
# fetch current window title
try:
oldWindowTitle = win32api.GetConsoleTitle()
except:
return 0
# format a "unique" NewWindowTitle
newWindowTitle = "%d/%d" % (win32api.GetTickCount(),
win32api.GetCurrentProcessId())
# change current window title
win32api.SetConsoleTitle(newWindowTitle)
# ensure window title has been updated
import time
time.sleep(0.040)
# look for NewWindowTitle
hwndFound = win32gui.FindWindow(0, newWindowTitle)
# restore original window title
win32api.SetConsoleTitle(oldWindowTitle)
return hwndFound
hwndOwner = GetConsoleHwnd()
def MessageBox(message, title=None, style=win32con.MB_OK):
return win32gui.MessageBox(hwndOwner, message, title, style)
if __name__ == "__main__":
pmail_ini_dir = "C:\\Program Files\\PMAIL\\MAIL\\ADMIN"
for mailer in ["Eudora", "Mozilla", "M2", "Outlook Express", "PocoMail"]:
#print find_config_location(mailer)
#configure(mailer)
offer_to_configure(mailer)
syntax highlighted by Code2HTML, v. 0.9.1