diff options
author | David Rousselie <dax@happycoders.org> | 2007-06-18 21:58:13 +0400 |
---|---|---|
committer | David Rousselie <dax@happycoders.org> | 2007-06-18 21:58:13 +0400 |
commit | 86a1367f26dd347b6afc197725679f1b10e561ac (patch) | |
tree | 869615c02dbd531d649538e05c858b014f26f07c /src | |
parent | d6b91f8d02195fee85499bb09870ebabd47a8b42 (diff) |
SMTP send_email real implementation
darcs-hash:20070618175813-86b55-990d6242426508e186abfc454d69fc9e0cd424b0.gz
Diffstat (limited to 'src')
-rw-r--r-- | src/jmc/jabber/component.py | 17 | ||||
-rw-r--r-- | src/jmc/jabber/tests/component.py | 38 | ||||
-rw-r--r-- | src/jmc/model/account.py | 118 | ||||
-rw-r--r-- | src/jmc/model/tests/account.py | 202 | ||||
-rw-r--r-- | src/jmc/model/tests/server.py | 18 |
5 files changed, 314 insertions, 79 deletions
diff --git a/src/jmc/jabber/component.py b/src/jmc/jabber/component.py index 1164cbd..71ec10c 100644 --- a/src/jmc/jabber/component.py +++ b/src/jmc/jabber/component.py @@ -243,9 +243,11 @@ class SendMailMessageHandler(MailHandler): def handle(self, message, lang_class, accounts): to_node = message.get_to().node to_email = to_node.replace('%', '@', 1) - accounts[0].send_email(to_email, - message.get_subject(), - message.get_body()) + accounts[0].send_email(\ + accounts[0].create_email(accounts[0].default_from, + to_email, + message.get_subject(), + message.get_body())) return self.send_mail_result(message, lang_class, to_email) class RootSendMailMessageHandler(SendMailMessageHandler): @@ -253,7 +255,7 @@ class RootSendMailMessageHandler(SendMailMessageHandler): def __init__(self): SendMailMessageHandler.__init__(self) - self.to_regexp = re.compile("^\s*(to|TO)\s*:\s*(?P<to_email>.*)") + self.to_regexp = re.compile("^\s*(to|TO|To)\s*:\s*(?P<to_email>.*)") self.__logger = logging.getLogger(\ "jmc.jabber.component.RootSendMailMessageHandler") @@ -285,8 +287,11 @@ class RootSendMailMessageHandler(SendMailMessageHandler): message_body.append(line) message_body.extend(lines) if to_email is not None: - accounts[0].send_email(to_email, message.get_subject(), - "\n".join(message_body)) + accounts[0].send_email(\ + accounts[0].create_email(accounts[0].default_from, + to_email, + message.get_subject(), + "\n".join(message_body))) return self.send_mail_result(message, lang_class, to_email) else: return [Message(from_jid=message.get_to(), diff --git a/src/jmc/jabber/tests/component.py b/src/jmc/jabber/tests/component.py index 9cf85c6..8004fa4 100644 --- a/src/jmc/jabber/tests/component.py +++ b/src/jmc/jabber/tests/component.py @@ -142,6 +142,16 @@ class MockPOP3Account(MockMailAccount, POP3Account): IMAPAccount._init(self, *args, **kw) MockMailAccount._init(self) +class MockSMTPAccount(object): + def __init__(self): + self.default_from = "user1@test.com" + + def create_email(self, from_email, to_email, subject, body): + return (from_email, to_email, subject, body) + + def send_email(self, email): + self.email = email + class MailComponent_TestCase(unittest.TestCase): def setUp(self): if os.path.exists(DB_PATH): @@ -525,16 +535,11 @@ class SendMailMessageHandler_TestCase(unittest.TestCase): to_jid="user%test.com@jcl.test.com", subject="message subject", body="message body") - class MockSMTPAccount(object): - def send_email(self, to_email, subject, body): - self.to_email = to_email - self.subject = subject - self.body = body accounts = [MockSMTPAccount()] result = self.handler.handle(message, Lang.en, accounts) - self.assertEquals(accounts[0].to_email, "user@test.com") - self.assertEquals(accounts[0].subject, "message subject") - self.assertEquals(accounts[0].body, "message body") + self.assertEquals(accounts[0].email[1], "user@test.com") + self.assertEquals(accounts[0].email[2], "message subject") + self.assertEquals(accounts[0].email[3], "message body") self.assertEquals(len(result), 1) self.assertEquals(result[0].stanza_type, "message") self.assertEquals(result[0].get_from(), "user%test.com@jcl.test.com") @@ -632,16 +637,12 @@ class RootSendMailMessageHandler_TestCase(unittest.TestCase): subject="message subject", body="to: user@test.com\n" \ "message body\nother line") - class MockSMTPAccount(object): - def send_email(self, to_email, subject, body): - self.to_email = to_email - self.subject = subject - self.body = body accounts = [MockSMTPAccount()] result = self.handler.handle(message, Lang.en, accounts) - self.assertEquals(accounts[0].to_email, "user@test.com") - self.assertEquals(accounts[0].subject, "message subject") - self.assertEquals(accounts[0].body, "message body\nother line") + self.assertEquals(accounts[0].email[1], "user@test.com") + self.assertEquals(accounts[0].email[2], "message subject") + self.assertEquals(accounts[0].email[3], + "message body\nother line") self.assertEquals(len(result), 1) self.assertEquals(result[0].get_type(), None) self.assertEquals(result[0].get_from(), "jcl.test.com") @@ -656,11 +657,6 @@ class RootSendMailMessageHandler_TestCase(unittest.TestCase): to_jid="jcl.test.com", subject="message subject", body="message body") - class MockSMTPAccount(object): - def send_email(self, to_email, subject, body): - self.to_email = to_email - self.subject = subject - self.body = body accounts = [MockSMTPAccount()] result = self.handler.handle(message, Lang.en, accounts) self.assertEquals(len(result), 1) diff --git a/src/jmc/model/account.py b/src/jmc/model/account.py index 250018d..9edae05 100644 --- a/src/jmc/model/account.py +++ b/src/jmc/model/account.py @@ -4,18 +4,18 @@ ## Login : <dax@happycoders.org> ## Started on Fri Jan 19 18:21:44 2007 David Rousselie ## $Id$ -## +## ## Copyright (C) 2007 David Rousselie ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. -## +## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. -## +## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -24,12 +24,15 @@ import sys import logging import email -import email.Header +from email.Header import Header +from email.MIMEText import MIMEText +from email.MIMEMultipart import MIMEMultipart import traceback import poplib import imaplib import socket +import smtplib from sqlobject.inheritance import InheritableSQLObject from sqlobject.col import StringCol, IntCol, BoolCol @@ -80,9 +83,9 @@ class MYPOP3(poplib.POP3): self.port = port msg = "getaddrinfo returns an empty list" self.sock = None - for res in socket.getaddrinfo(self.host, - self.port, - 0, + for res in socket.getaddrinfo(self.host, + self.port, + 0, socket.SOCK_STREAM): af, socktype, proto, canonname, sa = res try: @@ -103,7 +106,7 @@ class MYPOP3(poplib.POP3): self.welcome = self._getresp() class MYPOP3_SSL(poplib.POP3_SSL): - def __init__(self, host, port=poplib.POP3_SSL_PORT, keyfile=None, + def __init__(self, host, port=poplib.POP3_SSL_PORT, keyfile=None, certfile=None): self.host = host self.port = port @@ -112,7 +115,7 @@ class MYPOP3_SSL(poplib.POP3_SSL): self.buffer = "" msg = "getaddrinfo returns an empty list" self.sock = None - for res in socket.getaddrinfo(self.host, self.port, 0, + for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM): af, socktype, proto, canonname, sa = res try: @@ -154,11 +157,11 @@ class MailAccount(PresenceAccount): interval = IntCol(default=5) store_password = BoolCol(default=True) live_email_only = BoolCol(default=False) - + lastcheck = IntCol(default=0) waiting_password_reply = BoolCol(default=False) first_check = BoolCol(default=True) - + def _init(self, *args, **kw): """MailAccount init Initialize class attributes""" @@ -167,7 +170,7 @@ class MailAccount(PresenceAccount): self.connection = None self.connected = False self.default_lang_class = Lang.en - + def _get_register_fields(cls, real_class=None): """See Account._get_register_fields """ @@ -204,13 +207,13 @@ class MailAccount(PresenceAccount): ("interval", "text-single", None, account.int_post_func, lambda bare_from_jid: 5)] - + get_register_fields = classmethod(_get_register_fields) def _get_default_port(cls): return 42 get_default_port = classmethod(_get_default_port) - + def _get_presence_actions_fields(cls): """See PresenceAccount._get_presence_actions_fields """ @@ -226,7 +229,7 @@ class MailAccount(PresenceAccount): MailAccount.DIGEST), 'offline_action': (cls.possibles_actions, PresenceAccount.DO_NOTHING)} - + get_presence_actions_fields = classmethod(_get_presence_actions_fields) def get_decoded_part(self, part, charset_hint): @@ -255,7 +258,7 @@ class MailAccount(PresenceAccount): (type, value, stack, 5)) return result - + def format_message(self, email_msg, include_body = True): from_decoded = email.Header.decode_header(email_msg["From"]) charset_hint = None @@ -312,7 +315,7 @@ class MailAccount(PresenceAccount): print >>sys.stderr, \ "".join(traceback.format_exception (type, value, stack, 5)) - + result += u"\n\n" if include_body: @@ -329,7 +332,7 @@ class MailAccount(PresenceAccount): def format_message_summary(self, email_msg): return self.format_message(email_msg, False) - + def get_status_msg(self): return self.get_type() + "://" + self.login + "@" + self.host + ":" + \ unicode(self.port) @@ -371,13 +374,13 @@ class IMAPAccount(MailAccount): [("mailbox", "text-single", None, account.default_post_func, lambda bare_from_jid: "INBOX")] - + get_register_fields = classmethod(_get_register_fields) def _get_default_port(cls): """Return default IMAP server port""" return 143 - + get_default_port = classmethod(_get_default_port) def _init(self, *args, **kw): @@ -388,7 +391,7 @@ class IMAPAccount(MailAccount): if self.ssl: return "imaps" return "imap" - + def get_status(self): return MailAccount.get_status(self) + "/" + self.mailbox @@ -426,7 +429,7 @@ class IMAPAccount(MailAccount): return self.format_message(\ email.message_from_string(data[0][1])) return u"Error while fetching mail " + str(index) - + def get_mail_summary(self, index): self.__logger.debug("Getting mail summary " + str(index)) typ, data = self.connection.select(self.mailbox, True) @@ -444,13 +447,13 @@ class IMAPAccount(MailAccount): def mark_all_as_read(self): self.get_mail_list() - + type = property(get_type) class POP3Account(MailAccount): nb_mail = IntCol(default=0) lastmail = IntCol(default=0) - + def _init(self, *args, **kw): MailAccount._init(self, *args, **kw) self.__logger = logging.getLogger("jmc.model.account.POP3Account") @@ -458,7 +461,7 @@ class POP3Account(MailAccount): def _get_default_port(cls): """Return default POP3 server port""" return 110 - + get_default_port = classmethod(_get_default_port) def get_type(self): @@ -470,7 +473,7 @@ class POP3Account(MailAccount): def connect(self): self.__logger.debug("Connecting to POP3 server " - + self.login + "@" + self.host + ":" + + + self.login + "@" + self.host + ":" + str(self.port) + ". SSL=" + str(self.ssl)) if self.ssl: self.connection = MYPOP3_SSL(self.host, self.port) @@ -482,7 +485,7 @@ class POP3Account(MailAccount): self.connection.user(self.login) self.connection.pass_(self.password) self.connected = True - + def disconnect(self): self.__logger.debug("Disconnecting from POP3 server " @@ -493,7 +496,7 @@ class POP3Account(MailAccount): def get_mail_list(self): self.__logger.debug("Getting mail list") count, size = self.connection.stat() - self.nb_mail = count + self.nb_mail = count return [str(i) for i in range(1, count + 1)] def get_mail(self, index): @@ -535,7 +538,7 @@ class POP3Account(MailAccount): def mark_all_as_read(self): self.get_mail_list() self.lastmail = self.nb_mail - + class SMTPAccount(Account): """Send email account""" @@ -559,7 +562,7 @@ class SMTPAccount(Account): def _get_default_port(cls): """Return default SMTP server port""" return 25 - + get_default_port = classmethod(_get_default_port) def _get_register_fields(cls, real_class=None): @@ -628,12 +631,55 @@ class SMTPAccount(Account): ("default_account", "boolean", None, default_account_post_func, default_account_default_func)] - + get_register_fields = classmethod(_get_register_fields) - def send_email(self, to_email, subject, body): + def create_email(self, from_email, to_email, subject, body): + """Create new email""" + email = MIMEText(body) + email['Subject'] = Header(str(subject)) + email['From'] = Header(str(from_email)) + email['To'] = Header(str(to_email)) + return email + + def __say_hello(self, connection): + if not (200 <= connection.ehlo()[0] <= 299): + (code, resp) = connection.helo() + if not (200 <= code <= 299): + raise SMTPHeloError(code, resp) + + def send_email(self, email): + """Send email according to current account parameters""" self.__logger.debug("Sending email:\n" - "From: " + self.default_from + "\n" + - "To: " + to_email + "\n" + - "Subject: " + subject + "\n\n" + - body) + + str(email)) + smtp_connection = smtplib.SMTP() + if self.__logger.getEffectiveLevel() == logging.DEBUG: + smtp_connection.set_debuglevel(1) + smtp_connection.connect(self.host, self.port) + self.__say_hello(smtp_connection) + if self.tls: + smtp_connection.starttls() + self.__say_hello(smtp_connection) + if self.login is not None and len(self.login) > 0: + auth_methods = smtp_connection.esmtp_features["auth"].split() + auth_methods.reverse() + current_error = None + for auth_method in auth_methods: + self.__logger.debug("Trying to authenticate using " + + auth_method + " method") + smtp_connection.esmtp_features["auth"] = auth_method + try: + smtp_connection.login(self.login, self.password) + current_error = None + self.__logger.debug("Successfuly to authenticate using " + + auth_method + " method") + break + except smtplib.SMTPAuthenticationError, error: + self.__logger.debug("Failed to authenticate using " + + auth_method + " method") + current_error = error + if current_error is not None: + raise current_error + smtp_connection.sendmail(str(email['From']), str(email['To']), + email.as_string()) + smtp_connection.quit() diff --git a/src/jmc/model/tests/account.py b/src/jmc/model/tests/account.py index c9d205f..e5a1e15 100644 --- a/src/jmc/model/tests/account.py +++ b/src/jmc/model/tests/account.py @@ -4,18 +4,18 @@ ## Login : <dax@happycoders.org> ## Started on Wed Feb 14 08:23:17 2007 David Rousselie ## $Id$ -## +## ## Copyright (C) 2007 David Rousselie ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. -## +## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. -## +## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -168,7 +168,7 @@ class POP3Account_TestCase(InheritableAccount_TestCase): self.pop3_account.ssl = False del account.hub.threadConnection self.account_class = POP3Account - + def tearDown(self): account.hub.threadConnection = connectionForURI('sqlite://' + self.db_url) POP3Account.dropTable(ifExists = True) @@ -210,7 +210,7 @@ class POP3Account_TestCase(InheritableAccount_TestCase): return inner test_connection = make_test() - + test_get_mail_list = \ make_test(["+OK 2 20\r\n"], \ ["STAT\r\n"], \ @@ -340,7 +340,7 @@ class IMAPAccount_TestCase(InheritableAccount_TestCase): self.imap_account.disconnect() self.failUnless(self.server.verify_queries()) return inner - + test_connection = make_test() test_get_mail_list = make_test([lambda data: "* 42 EXISTS\n* 1 RECENT\n* OK" +\ @@ -433,7 +433,7 @@ class SMTPAccount_TestCase(Account_TestCase): value = post_func("False", None, "user1@test.com") self.assertTrue(value) del account.hub.threadConnection - + def test_default_account_post_func_true(self): account.hub.threadConnection = connectionForURI('sqlite://' + self.db_url) account11 = SMTPAccount(user_jid="user1@test.com", @@ -466,6 +466,194 @@ class SMTPAccount_TestCase(Account_TestCase): self.assertTrue(account12.default_account) del account.hub.threadConnection + def test_create_email(self): + account.hub.threadConnection = connectionForURI('sqlite://' + self.db_url) + account11 = SMTPAccount(user_jid="user1@test.com", + name="account11", + jid="account11@jmc.test.com") + del account.hub.threadConnection + email = account11.create_email("from@test.com", + "to@test.com", + "subject", + "body") + self.assertEqual(email['From'], "from@test.com") + self.assertEqual(email['To'], "to@test.com") + self.assertEqual(email['Subject'], "subject") + self.assertEqual(email.get_payload(), "body") + + def make_test(self, responses=None, queries=None, core=None): + def inner(): + self.server = server.DummyServer("localhost", 1025) + thread.start_new_thread(self.server.serve, ()) + self.server.responses = [] + if responses: + self.server.responses += responses + self.server.responses += ["221 localhost closing connection\r\n"] + self.server.queries = [] + if queries: + self.server.queries += queries + self.server.queries += ["quit\r\n"] + if core: + account.hub.threadConnection = connectionForURI('sqlite://' + + self.db_url) + core(self) + del account.hub.threadConnection + self.failUnless(self.server.verify_queries()) + return inner + + def test_send_email_esmtp_no_auth(self): + account.hub.threadConnection = connectionForURI('sqlite://' + + self.db_url) + smtp_account = SMTPAccount(user_jid="user1@test.com", + name="account11", + jid="account11@jmc.test.com") + smtp_account.host = "localhost" + smtp_account.port = 1025 + del account.hub.threadConnection + email = smtp_account.create_email("from@test.com", + "to@test.com", + "subject", + "body") + test_func = self.make_test(["220 localhost ESMTP\r\n", + "250-localhost Hello 127.0.0.1\r\n" + + "250-SIZE 52428800\r\n" + + "250-PIPELINING\r\n" + + "250 HELP\r\n", + "250 OK\r\n", + "250 Accepted\r\n", + "354 Enter message\r\n", + None, None, None, None, + None, None, None, None, + "250 OK\r\n"], + ["ehlo \[127.0.0.1\]\r\n", + "mail FROM:<" + str(email['From']) + ">.*", + "rcpt TO:<" + str(email['To']) + ">\r\n", + "data\r\n"] + + email.as_string().split("\n") + [".\r\n"], + lambda self: \ + smtp_account.send_email(email)) + test_func() + + def test_send_email_no_auth(self): + account.hub.threadConnection = connectionForURI('sqlite://' + + self.db_url) + smtp_account = SMTPAccount(user_jid="user1@test.com", + name="account11", + jid="account11@jmc.test.com") + smtp_account.host = "localhost" + smtp_account.port = 1025 + del account.hub.threadConnection + email = smtp_account.create_email("from@test.com", + "to@test.com", + "subject", + "body") + test_func = self.make_test(["220 localhost SMTP\r\n", + "504 ESMTP not supported\r\n", + "250-localhost Hello 127.0.0.1\r\n" + + "250-SIZE 52428800\r\n" + + "250-PIPELINING\r\n" + + "250 HELP\r\n", + "250 OK\r\n", + "250 Accepted\r\n", + "354 Enter message\r\n", + None, None, None, None, + None, None, None, None, + "250 OK\r\n"], + ["ehlo \[127.0.0.1\]\r\n", + "helo \[127.0.0.1\]\r\n", + "mail FROM:<" + str(email['From']) + ">.*", + "rcpt TO:<" + str(email['To']) + ">\r\n", + "data\r\n"] + + email.as_string().split("\n") + [".\r\n"], + lambda self: \ + smtp_account.send_email(email)) + test_func() + + def test_send_email_esmtp_auth(self): + account.hub.threadConnection = connectionForURI('sqlite://' + + self.db_url) + smtp_account = SMTPAccount(user_jid="user1@test.com", + name="account11", + jid="account11@jmc.test.com") + smtp_account.host = "localhost" + smtp_account.port = 1025 + smtp_account.login = "user" + smtp_account.password = "pass" + del account.hub.threadConnection + email = smtp_account.create_email("from@test.com", + "to@test.com", + "subject", + "body") + test_func = self.make_test(["220 localhost ESMTP\r\n", + "250-localhost Hello 127.0.0.1\r\n" + + "250-SIZE 52428800\r\n" + + "250-AUTH PLAIN LOGIN CRAM-MD5\r\n" + + "250-PIPELINING\r\n" + + "250 HELP\r\n", + "334 ZGF4IDNmNDM2NzY0YzBhNjgyMTQ1MzhhZGNiMjE2YTYxZjRm\r\n", + "235 Authentication succeeded\r\n", + "250 OK\r\n", + "250 Accepted\r\n", + "354 Enter message\r\n", + None, None, None, None, + None, None, None, None, + "250 OK\r\n"], + ["ehlo \[127.0.0.1\]\r\n", + "AUTH CRAM-MD5\r\n", + ".*\r\n", + "mail FROM:<" + str(email['From']) + ">.*", + "rcpt TO:<" + str(email['To']) + ">\r\n", + "data\r\n"] + + email.as_string().split("\n") + [".\r\n"], + lambda self: \ + smtp_account.send_email(email)) + test_func() + + def test_send_email_esmtp_auth_method2(self): + account.hub.threadConnection = connectionForURI('sqlite://' + + self.db_url) + smtp_account = SMTPAccount(user_jid="user1@test.com", + name="account11", + jid="account11@jmc.test.com") + smtp_account.host = "localhost" + smtp_account.port = 1025 + smtp_account.login = "user" + smtp_account.password = "pass" + del account.hub.threadConnection + email = smtp_account.create_email("from@test.com", + "to@test.com", + "subject", + "body") + test_func = self.make_test(["220 localhost ESMTP\r\n", + "250-localhost Hello 127.0.0.1\r\n" + + "250-SIZE 52428800\r\n" + + "250-AUTH PLAIN LOGIN CRAM-MD5\r\n" + + "250-PIPELINING\r\n" + + "250 HELP\r\n", + "334 ZGF4IDNmNDM2NzY0YzBhNjgyMTQ1MzhhZGNiMjE2YTYxZjRm\r\n", + "535 Incorrect Authentication data\r\n", + "334 asd235r4\r\n", + "235 Authentication succeeded\r\n", + "250 OK\r\n", + "250 Accepted\r\n", + "354 Enter message\r\n", + None, None, None, None, + None, None, None, None, + "250 OK\r\n"], + ["ehlo \[127.0.0.1\]\r\n", + "AUTH CRAM-MD5\r\n", + ".*\r\n", + "AUTH LOGIN .*\r\n", + ".*\r\n", + "mail FROM:<" + str(email['From']) + ">.*", + "rcpt TO:<" + str(email['To']) + ">\r\n", + "data\r\n"] + + email.as_string().split("\n") + [".\r\n"], + lambda self: \ + smtp_account.send_email(email)) + test_func() + + def suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(MailAccount_TestCase, 'test')) diff --git a/src/jmc/model/tests/server.py b/src/jmc/model/tests/server.py index 1b939aa..a318091 100644 --- a/src/jmc/model/tests/server.py +++ b/src/jmc/model/tests/server.py @@ -1,20 +1,20 @@ ## ## dummy_server.py ## Login : David Rousselie <david.rousselie@happycoders.org> -## Started on Fri May 13 12:53:17 2005 +## Started on Fri May 13 12:53:17 2005 ## $Id: dummy_server.py,v 1.1 2005/07/11 20:39:31 dax Exp $ -## -## Copyright (C) 2005 +## +## Copyright (C) 2005 ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. -## +## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. -## +## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -75,7 +75,7 @@ class DummyServer: self.responses = None self.queries = None self.real_queries = [] - + def serve(self): conn = None try: @@ -150,7 +150,7 @@ class XMLDummyServer(DummyServer): r = self._reader.feed(data) except: type, value, stack = sys.exc_info() - print "".join (traceback.format_exception + print "".join (traceback.format_exception (type, value, stack, 5)) raise # TODO verify got all data </stream> @@ -175,7 +175,7 @@ class XMLDummyServer(DummyServer): self.socket = None except: type, value, stack = sys.exc_info() - print "".join (traceback.format_exception + print "".join (traceback.format_exception (type, value, stack, 5)) raise @@ -205,5 +205,5 @@ def test(): if __name__ == '__main__': test() - + |