some module refactoring

darcs-hash:20070627202236-86b55-8a2b80e157cdfb307943c9e2643fc0cd97e87ec7.gz
This commit is contained in:
David Rousselie
2007-06-27 22:22:36 +02:00
parent 545b0dca1c
commit 620b500e0b
6 changed files with 240 additions and 161 deletions

View File

@@ -1,2 +1,33 @@
"""Jabber component classes""" """Jabber component classes"""
__revision__ = "" __revision__ = ""
import re
from jcl.jabber import Handler
from jcl.model.account import Account
from jmc.model.account import NoAccountError, SMTPAccount
class MailHandler(Handler):
"""Define filter for email address in JID"""
def __init__(self):
Handler.__init__(self)
self.dest_jid_regexp = re.compile(".*%.*")
def filter(self, stanza, lang_class):
"""Return empty array if JID match '.*%.*@componentJID'"""
node = stanza.get_to().node
if node is not None and self.dest_jid_regexp.match(node):
bare_from_jid = unicode(stanza.get_from().bare())
accounts = Account.select(Account.q.user_jid == bare_from_jid)
if accounts.count() == 0:
raise NoAccountError()
else:
default_account = accounts.newClause(\
SMTPAccount.q.default_account == True)
if default_account.count() > 0:
return default_account
else:
return accounts
return None

View File

@@ -31,19 +31,18 @@ from pyxmpp.message import Message
from pyxmpp.jid import JID from pyxmpp.jid import JID
from jcl.model.account import Account, PresenceAccount, LegacyJID from jcl.model.account import Account, PresenceAccount, LegacyJID
from jcl.jabber.component import Handler, DefaultSubscribeHandler, \ from jcl.jabber.component import Handler, AccountManager
DefaultUnsubscribeHandler, DefaultPresenceHandler, AccountManager
from jcl.jabber.feeder import FeederComponent, Feeder, MessageSender, \ from jcl.jabber.feeder import FeederComponent, Feeder, MessageSender, \
HeadlineSender, FeederHandler HeadlineSender, FeederHandler
from jmc.jabber.message import SendMailMessageHandler, \
RootSendMailMessageHandler
from jmc.jabber.presence import MailSubscribeHandler, \
MailUnsubscribeHandler, MailPresenceHandler
from jmc.model.account import MailAccount, IMAPAccount, POP3Account, \ from jmc.model.account import MailAccount, IMAPAccount, POP3Account, \
SMTPAccount SMTPAccount
from jmc.lang import Lang from jmc.lang import Lang
class NoAccountError(Exception):
"""Error raised when no corresponding account is found."""
pass
class MailComponent(FeederComponent): class MailComponent(FeederComponent):
"""Jabber Mail Component main implementation""" """Jabber Mail Component main implementation"""
@@ -224,156 +223,6 @@ class MailSender(HeadlineSender):
message = None message = None
return message return message
class MailHandler(Handler):
"""Define filter for email address in JID"""
def __init__(self):
Handler.__init__(self)
self.dest_jid_regexp = re.compile(".*%.*")
def filter(self, stanza, lang_class):
"""Return empty array if JID match '.*%.*@componentJID'"""
node = stanza.get_to().node
if node is not None and self.dest_jid_regexp.match(node):
bare_from_jid = unicode(stanza.get_from().bare())
accounts = Account.select(Account.q.user_jid == bare_from_jid)
if accounts.count() == 0:
raise NoAccountError()
else:
default_account = accounts.newClause(\
SMTPAccount.q.default_account == True)
if default_account.count() > 0:
return default_account
else:
return accounts
return None
class MailPresenceHandler(DefaultPresenceHandler):
"""Define filter for legacy JIDs presence handling"""
def __init__(self):
Handler.__init__(self)
self.dest_jid_regexp = re.compile(".*%.*")
def filter(self, stanza, lang_class):
"""Return empty array if JID match '.*%.*@componentJID'"""
node = stanza.get_to().node
if node is not None and self.dest_jid_regexp.match(node):
bare_from_jid = unicode(stanza.get_from().bare())
return [] # Not None
return None
class SendMailMessageHandler(MailHandler):
def __init__(self):
MailHandler.__init__(self)
self.__logger = logging.getLogger(\
"jmc.jabber.component.SendMailMessageHandler")
def send_mail_result(self, message, lang_class, to_email):
return [Message(from_jid=message.get_to(),
to_jid=message.get_from(),
subject=lang_class.send_mail_ok_subject,
body=lang_class.send_mail_ok_body % (to_email))]
def handle(self, message, lang_class, accounts):
to_node = message.get_to().node
to_email = to_node.replace('%', '@', 1)
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):
"""Handle message sent to root JID"""
def __init__(self):
SendMailMessageHandler.__init__(self)
self.to_regexp = re.compile("^\s*(to|TO|To)\s*:\s*(?P<to_email>.*)")
self.__logger = logging.getLogger(\
"jmc.jabber.component.RootSendMailMessageHandler")
def filter(self, message, lang_class):
name = message.get_to().node
bare_from_jid = unicode(message.get_from().bare())
accounts = SMTPAccount.select(\
AND(SMTPAccount.q.default_account == True,
SMTPAccount.q.user_jid == bare_from_jid))
if accounts.count() != 1:
self.__logger.error("No default account found for user " +
str(bare_from_jid))
if accounts.count() == 0:
accounts = SMTPAccount.select(\
SMTPAccount.q.user_jid == bare_from_jid)
return accounts
def handle(self, message, lang_class, accounts):
to_email = None
lines = message.get_body().split('\n')
message_body = []
while to_email is None \
and lines:
line = lines.pop(0)
match = self.to_regexp.match(line)
if match:
to_email = match.group("to_email")
else:
message_body.append(line)
message_body.extend(lines)
if to_email is not None:
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(),
to_jid=message.get_from(),
stanza_type="error",
subject=lang_class.send_mail_error_no_to_header_subject,
body=lang_class.send_mail_error_no_to_header_body)]
class MailSubscribeHandler(DefaultSubscribeHandler, MailHandler):
"""Use DefaultSubscribeHandler handle method and MailHandler filter.
Filter email address in JID. Accept and add to LegacyJID table.
"""
def __init__(self):
DefaultSubscribeHandler.__init__(self)
MailHandler.__init__(self)
def filter(self, stanza, lang_class):
return MailHandler.filter(self, stanza, lang_class)
def handle(self, stanza, lang_class, accounts):
result = DefaultSubscribeHandler.handle(self, stanza, lang_class, accounts)
to_node = stanza.get_to().node
to_email = to_node.replace('%', '@', 1)
LegacyJID(legacy_address=to_email,
jid=unicode(stanza.get_to()),
account=accounts[0])
return result
class MailUnsubscribeHandler(DefaultUnsubscribeHandler, MailHandler):
"""Use DefaultUnsubscribeHandler handle method and MailHandler filter.
"""
def __init__(self):
DefaultUnsubscribeHandler.__init__(self)
MailHandler.__init__(self)
def filter(self, stanza, lang_class):
return MailHandler.filter(self, stanza, lang_class)
def handle(self, stanza, lang_class, accounts):
result = DefaultUnsubscribeHandler.handle(self, stanza, lang_class, accounts)
legacy_jid = LegacyJID.select(\
LegacyJID.q.jid == unicode(stanza.get_to()))
if legacy_jid.count() == 1:
legacy_jid[0].destroySelf()
return result
class MailFeederHandler(FeederHandler): class MailFeederHandler(FeederHandler):
def filter(self, stanza, lang_class): def filter(self, stanza, lang_class):
"""Return only email account type to check mail from """Return only email account type to check mail from

108
src/jmc/jabber/message.py Normal file
View File

@@ -0,0 +1,108 @@
##
## message.py
## Login : David Rousselie <dax@happycoders.org>
## Started on Wed Jun 27 22:08:23 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
##
import logging
import re
from sqlobject.sqlbuilder import AND
from pyxmpp.message import Message
from jmc.jabber import MailHandler
from jmc.model.account import SMTPAccount
class SendMailMessageHandler(MailHandler):
def __init__(self):
MailHandler.__init__(self)
self.__logger = logging.getLogger(\
"jmc.jabber.component.SendMailMessageHandler")
def send_mail_result(self, message, lang_class, to_email):
return [Message(from_jid=message.get_to(),
to_jid=message.get_from(),
subject=lang_class.send_mail_ok_subject,
body=lang_class.send_mail_ok_body % (to_email))]
def handle(self, stanza, lang_class, data):
message = stanza
accounts = data
to_node = message.get_to().node
to_email = to_node.replace('%', '@', 1)
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):
"""Handle message sent to root JID"""
def __init__(self):
SendMailMessageHandler.__init__(self)
self.to_regexp = re.compile("^\s*(to|TO|To)\s*:\s*(?P<to_email>.*)")
self.__logger = logging.getLogger(\
"jmc.jabber.component.RootSendMailMessageHandler")
def filter(self, stanza, lang_class):
name = stanza.get_to().node
bare_from_jid = unicode(stanza.get_from().bare())
accounts = SMTPAccount.select(\
AND(SMTPAccount.q.default_account == True,
SMTPAccount.q.user_jid == bare_from_jid))
if accounts.count() != 1:
self.__logger.error("No default account found for user " +
str(bare_from_jid))
if accounts.count() == 0:
accounts = SMTPAccount.select(\
SMTPAccount.q.user_jid == bare_from_jid)
return accounts
def handle(self, stanza, lang_class, data):
message = stanza
accounts = data
to_email = None
lines = message.get_body().split('\n')
message_body = []
while to_email is None \
and lines:
line = lines.pop(0)
match = self.to_regexp.match(line)
if match:
to_email = match.group("to_email")
else:
message_body.append(line)
message_body.extend(lines)
if to_email is not None:
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(),
to_jid=message.get_from(),
stanza_type="error",
subject=lang_class.send_mail_error_no_to_header_subject,
body=lang_class.send_mail_error_no_to_header_body)]

View File

@@ -0,0 +1,84 @@
##
## presence.py
## Login : David Rousselie <dax@happycoders.org>
## Started on Wed Jun 27 22:05:08 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
##
import re
from jcl.jabber.presence import DefaultPresenceHandler, \
DefaultSubscribeHandler, DefaultUnsubscribeHandler
from jcl.model.account import LegacyJID
from jcl.jabber import Handler
from jmc.jabber import MailHandler
class MailPresenceHandler(DefaultPresenceHandler):
"""Define filter for legacy JIDs presence handling"""
def __init__(self):
Handler.__init__(self)
self.dest_jid_regexp = re.compile(".*%.*")
def filter(self, stanza, lang_class):
"""Return empty array if JID match '.*%.*@componentJID'"""
node = stanza.get_to().node
if node is not None and self.dest_jid_regexp.match(node):
bare_from_jid = unicode(stanza.get_from().bare())
return [] # Not None
return None
class MailSubscribeHandler(DefaultSubscribeHandler, MailHandler):
"""Use DefaultSubscribeHandler handle method and MailHandler filter.
Filter email address in JID. Accept and add to LegacyJID table.
"""
def __init__(self):
DefaultSubscribeHandler.__init__(self)
MailHandler.__init__(self)
def filter(self, stanza, lang_class):
return MailHandler.filter(self, stanza, lang_class)
def handle(self, stanza, lang_class, accounts):
result = DefaultSubscribeHandler.handle(self, stanza, lang_class, accounts)
to_node = stanza.get_to().node
to_email = to_node.replace('%', '@', 1)
LegacyJID(legacy_address=to_email,
jid=unicode(stanza.get_to()),
account=accounts[0])
return result
class MailUnsubscribeHandler(DefaultUnsubscribeHandler, MailHandler):
"""Use DefaultUnsubscribeHandler handle method and MailHandler filter.
"""
def __init__(self):
DefaultUnsubscribeHandler.__init__(self)
MailHandler.__init__(self)
def filter(self, stanza, lang_class):
return MailHandler.filter(self, stanza, lang_class)
def handle(self, stanza, lang_class, accounts):
result = DefaultUnsubscribeHandler.handle(self, stanza, lang_class, accounts)
legacy_jid = LegacyJID.select(\
LegacyJID.q.jid == unicode(stanza.get_to()))
if legacy_jid.count() == 1:
legacy_jid[0].destroySelf()
return result

View File

@@ -38,11 +38,14 @@ from jcl.jabber.tests.component import DefaultSubscribeHandler_TestCase, \
from jcl.jabber.tests.feeder import FeederMock, SenderMock from jcl.jabber.tests.feeder import FeederMock, SenderMock
from jmc.model.account import MailAccount, IMAPAccount, POP3Account, \ from jmc.model.account import MailAccount, IMAPAccount, POP3Account, \
SMTPAccount SMTPAccount, NoAccountError
from jmc.jabber.component import MailComponent, SendMailMessageHandler, \ from jmc.jabber import MailHandler
RootSendMailMessageHandler, MailHandler, MailSubscribeHandler, \ from jmc.jabber.message import SendMailMessageHandler, \
MailUnsubscribeHandler, NoAccountError, MailFeederHandler, \ RootSendMailMessageHandler
MailPresenceHandler, MailAccountManager, MailSender from jmc.jabber.presence import MailSubscribeHandler, \
MailUnsubscribeHandler, MailPresenceHandler
from jmc.jabber.component import MailComponent, MailFeederHandler, \
MailAccountManager, MailSender
from jmc.lang import Lang from jmc.lang import Lang
if sys.platform == "win32": if sys.platform == "win32":

View File

@@ -45,6 +45,10 @@ from jmc.lang import Lang
IMAP4_TIMEOUT = 10 IMAP4_TIMEOUT = 10
POP3_TIMEOUT = 10 POP3_TIMEOUT = 10
class NoAccountError(Exception):
"""Error raised when no corresponding account is found."""
pass
## All MY* classes are implemented to add a timeout (settimeout) ## All MY* classes are implemented to add a timeout (settimeout)
## while connecting ## while connecting
class MYIMAP4(imaplib.IMAP4): class MYIMAP4(imaplib.IMAP4):