wcs/wcs/ctl/process_bounce.py

100 lines
3.1 KiB
Python

# w.c.s. - web application for online forms
# Copyright (C) 2005-2010 Entr'ouvert
#
# 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, see <http://www.gnu.org/licenses/>.
import sys
import time
import os
import email.Parser
from Bouncers import BouncerAPI
from ..qommon.ctl import Command
COMMA_SPACE = ', '
class CmdProcessBounce(Command):
name = 'process_bounce'
def execute(self, base_options, sub_options, args):
from ..qommon.tokens import Token
from ..qommon.bounces import Bounce
from .. import publisher
try:
publisher.WcsPublisher.configure(self.config)
pub = publisher.WcsPublisher.create_publisher(
register_tld_names=False)
except:
# not much we can do if we don't have a publisher object :/
return
try:
parser = email.Parser.Parser()
msg = parser.parse(sys.stdin)
addrs = self.get_bounce_addrs(msg)
if addrs is None:
# not a bounce
return
try:
to = msg['To']
local_part, server_part = to.split('@')
token_id = local_part.split('+')[1]
except (IndexError, KeyError):
return
pub.app_dir = os.path.join(pub.app_dir, server_part)
if not os.path.exists(pub.app_dir):
return
try:
token = Token.get(token_id)
except KeyError:
return
if token.type != 'email-bounce':
return
token.remove_self()
bounce = Bounce()
bounce.arrival_time = time.time()
bounce.bounce_message = msg.as_string()
bounce.addrs = addrs
bounce.original_message = token.email_message
bounce.original_rcpts = token.email_rcpts
bounce.email_type = token.email_type
bounce.store()
except:
pub.notify_of_exception(sys.exc_info(), context='[BOUNCE]')
sys.exit(1)
@classmethod
def get_bounce_addrs(cls, msg):
bouncers_dir = os.path.join(os.path.dirname(__file__), 'Bouncers')
sys.path.append(bouncers_dir)
for modname in BouncerAPI.BOUNCE_PIPELINE:
__import__(modname)
addrs = sys.modules[modname].process(msg)
if addrs is BouncerAPI.Stop:
return None # Stop means to ignore message
if addrs:
return addrs
return None # didn't find any match
CmdProcessBounce.register()