""" open/dulcinea/lib/ui/feedback.qpy """ import sys from qp.mail.send import sendmail from qp.fill.directory import Directory from qp.fill.form import Form from qp.fill.html import href, url_unquote from qp.fill.widget import HiddenWidget, StringWidget, TextWidget from qp.pub.common import get_user, get_request, redirect, header, footer from qp.pub.common import get_publisher, get_fields from qpy import xml, xml_quote from smtplib import SMTPResponseException, SMTPRecipientsRefused from traceback import print_exc class FeedbackDirectory(Directory): def get_exports(self): yield ('', '_q_index', 'Feedback', None) def _q_index(self): return Feedback().form() class Feedback: def form(self): request = get_request() if request.get_method() != 'POST': # we use the query string to pass data but we don't want to # have widgets parse themselves get_fields().clear() user = get_user() form = Form(use_tokens=bool(user)) form.add(HiddenWidget, "referrer", request.get_environ("HTTP_REFERER") or "/") form.add(StringWidget, "subject", self.get_subject(), title="Subject", size=50) if user: realname = user.format_realname() email = user.get_email() else: realname = None email = None form.add(StringWidget, "real_name", realname, title="Your name", size=50) form.add(StringWidget, "sender", email, title="Your e-mail address", size=50, required=True) form.add(TextWidget, "message", title="Message", rows=10, cols=65, required=True, wrap='hard') form.add_submit("send", "Send E-mail") form.add_submit("cancel", "Cancel") referrer = form['referrer'] if form.get('cancel'): redirect(referrer) if not form.is_submitted() or form.has_errors(): return self.render(form) try: sendmail( form["subject"] or "Site feedback", (("Feedback from: %s\n\n" % (referrer or "(unknown)")) + form["message"]), self.get_recipients(), from_addr=(form["sender"], form.get("real_name", "")), smtp_sender=form["sender"]) # Handling SMTP errors is a bit tricky because Exim doesn't # always return an SMTP error at the obvious point. (Eg. for # bogus sender addresses, it might be configured to return the # error right after the "MAIL FROM" command, or not until after # the DATA command. Currently the latter is the case on our server. # It also seems to depend on whether there are one or multiple # recipient addresses.) I *think* these two "except" statements # should handle all "bogus sender address" errors, which is what # we're really concerned with here. except SMTPResponseException: # Currently, this happens (in the form of SMTPDataError) for # bogus sender addresses with multiple recipients. print_exc(1, sys.stderr) form.set_error("sender", "We need your full email address here.") return self.render(form) except SMTPRecipientsRefused: # This is the what happens for bogus *sender* addresses when # there's *only one* recipient. Note that err.recipients is # a dictionary like this: # {'gw@not.org': # (550, 'cannot route to sender address ')} # so we have to dig around a bit to get the real error # message. print_exc(1, sys.stderr) err = sys.exc_info()[1] print(err.recipients) form.set_error("sender", "We need your full email address here.") return self.render(form) return self.thanks(referrer) def thanks:xml(self, referrer): title = "Thank You" header(title) "Thank you for your feedback. " if referrer: "Please follow the link below to return to the page " "you were reading. " '

' href(referrer, referrer) '

' footer(title) def get_recipients(self): query_list = get_request().get_query().split(',') if len(query_list) == 1: addresses = query_list else: addresses = query_list[:-1] feedback_domain = get_publisher().get_feedback_domain() feedback_addresses = get_publisher().get_feedback_addresses() full_addresses = ["%s@%s" % (address, feedback_domain) for address in addresses if address in feedback_addresses] if not full_addresses: full_addresses = ["webmaster@%s" % feedback_domain] return full_addresses def get_subject(self): query_list = get_request().get_query().split(',') if len(query_list) > 1: return url_unquote(query_list[-1].replace('+', ' ')) else: return "" def render:xml(self, form): title = "Feedback" header(title) '
' 'Email to: ' ', '.join([xml(xml_quote(addr).replace("@", "@")) for addr in self.get_recipients()]) '
' form.render() # catch nasty robots (target should easy to find even for stupid # parsers) '\n' footer(title)