wcs/wcs/admin/bounces.py

185 lines
6.6 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 time
import email.Parser
from django.utils.encoding import force_text
from quixote import get_response, redirect
from quixote.directory import Directory
from quixote.html import htmltext, TemplateIO
from ..qommon import _
from ..qommon import errors
from ..qommon import misc
from ..qommon.bounces import Bounce
from ..qommon.backoffice.menu import html_top
from ..qommon.admin.menu import command_icon
from ..qommon.form import *
from ..qommon.misc import get_cfg
def get_email_type_label(type):
from .settings import EmailsDirectory
return EmailsDirectory.emails_dict.get(type, {}).get('description')
class BouncePage(Directory):
_q_exports = ['', 'delete']
def __init__(self, component):
self.bounce = Bounce.get(component)
get_response().breadcrumb.append((component + '/', _('bounce')))
def _q_index(self):
html_top('bounces', title = _('Bounce'))
r = TemplateIO(html=True)
r += htmltext('<div class="form">')
if self.bounce.email_type:
r += htmltext('<div class="title">%s</div>') % _('Email Type')
r += htmltext('<div class="StringWidget content">')
r += _(get_email_type_label(self.bounce.email_type))
r += htmltext('</div>')
r += htmltext('<div class="title">%s</div>') % _('Arrival Time')
r += htmltext('<div class="StringWidget content">')
r += misc.localstrftime(time.localtime(self.bounce.arrival_time))
r += htmltext('</div>')
if self.bounce.addrs:
r += htmltext('<div class="title">%s</div>') % _('Failed Addresses')
r += htmltext('<div class="StringWidget content">')
r += ', '.join(self.bounce.addrs)
r += htmltext('</div>')
if self.bounce.original_rcpts:
r += htmltext('<div class="title">%s</div>') % _('Original Recipients')
r += htmltext('<div class="StringWidget content">')
r += ', '.join(self.bounce.original_rcpts)
r += htmltext('</div>')
r += htmltext('<div class="title">%s</div>') % _('Bounce Message')
r += htmltext('<div class="StringWidget content">')
r += htmltext('<pre style="max-height: 20em;">')
r += self.bounce.bounce_message
r += htmltext('</pre>')
r += htmltext('</div>')
if self.bounce.original_message:
parser = email.Parser.Parser()
msg = parser.parsestr(self.bounce.original_message)
if msg.is_multipart():
for m in msg.get_payload():
if m.get_content_type() == 'text/plain':
break
else:
m = None
elif msg.get_content_type() == 'text/plain':
m = msg
else:
m = None
r += htmltext('<div class="title">%s</div>') % _('Original Message')
r += htmltext('<div class="StringWidget content">')
r += _('Subject: ')
subject, charset = email.Header.decode_header(msg['Subject'])[0]
if charset:
encoding = get_publisher().site_charset
r += force_text(subject, charset).encode(encoding)
else:
r += subject
r += htmltext('</div>')
if m:
r += htmltext('<div class="StringWidget content">')
r += htmltext('<pre>')
r += m.get_payload()
r += htmltext('</pre>')
r += htmltext('</div>')
r += htmltext('</div>') # form
return r.getvalue()
def delete(self):
form = Form(enctype='multipart/form-data')
form.widgets.append(HtmlWidget('<p>%s</p>' % _(
'You are about to irrevocably delete this bounce.')))
form.add_submit('delete', _('Delete'))
form.add_submit('cancel', _('Cancel'))
if form.get_widget('cancel').parse():
return redirect('..')
if not form.is_submitted() or form.has_errors():
get_response().breadcrumb.append(('delete', _('Delete')))
html_top('bounces', title = _('Delete Bounce'))
r = TemplateIO(html=True)
r += htmltext('<h2>%s</h2>') % _('Deleting Bounce')
r += form.render()
return r.getvalue()
else:
self.bounce.remove_self()
return redirect('..')
class BouncesDirectory(Directory):
_q_exports = ['']
def _q_traverse(self, path):
get_response().breadcrumb.append( ('bounces/', _('Bounces')) )
return Directory._q_traverse(self, path)
def is_visible(self, *args):
return bool(get_cfg('emails', {}).get('bounce_handler') is True)
def _q_index(self):
html_top('bounces', title = _('Bounces'))
bounces = Bounce.select(ignore_errors=True)
bounces.sort(lambda x,y: cmp(x.arrival_time, y.arrival_time))
r = TemplateIO(html=True)
r += htmltext('<ul class="biglist">')
for bounce in bounces:
r += htmltext('<li>')
r += htmltext('<strong class="label">')
r += misc.localstrftime(time.localtime(bounce.arrival_time))
if bounce.email_type:
r += ' - '
r += _(get_email_type_label(bounce.email_type))
r += htmltext('</strong>')
r += htmltext('<p class="details">')
if bounce.addrs:
r += ', '.join(bounce.addrs)
r += htmltext('</p>')
r += htmltext('<p class="commands">')
r += command_icon('%s/' % bounce.id, 'view')
r += command_icon('%s/delete' % bounce.id, 'remove', popup = True)
r += htmltext('</p></li>')
r += htmltext('</ul>')
return r.getvalue()
def _q_lookup(self, component):
try:
return BouncePage(component)
except KeyError:
raise errors.TraversalError()