Simple Feedback Forms with Python CGI
Simple Job, Simple Script
formmail has worked well for me on several occasions, but I don't like being dependant on a large Perl script to do something as simple as submitting comments via e-mail. If the operation is kept simple then it can be easily adapted to specific requirements, and that's the goal here.
testform.html
I like the idea of embedding the basic paramiters of a form in hidden HTML fields because it puts control in the hands of the web page authors. To pass this information on I simply created a simple page that the webmaster I was working with could copy from.
<html> <head> <title></title> <body> <form action="/cgi-bin/submit.cgi" method="POST"> <input type="hidden" name="to" value="theman@eradman.com" /> <input type="hidden" name="from" value="sysadmin@teisprint.net" /> <input type="hidden" name="nextpage" value="../thankyou.html" /> <input type="hidden" name="subject" value="Online form submission" /> <table> <tr><td>Name:</td><td><input type="text" name="name" /></td></tr> <tr><td>E-mail:</td><td><input type="text" name="email" /></td></tr> <tr><td colspan="2"><textarea name="message" rows="14" cols="52"></textarea></td></tr> <tr><td></td><td><input type="submit" /></td></tr> </form>
There are a number of hidden fields in the form that you need to modify to make it work for you. from is where bounces will go. to is the destination address you want to send the messages to. subject is title of the messages it sends to your e-mail account. nextpage is the location you want to show after submitting the form. Right now it redirects their browser to ../thankyou.html
submit.cgi
First task is to make this script executable:
% chmod 755 cgi-bin/submit.cgi
#!/usr/bin/env python import smtplib import cgi import os from datetime import datetime import string import urlparse def debug(message): print "Content-type: text/html" print """ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C/DTD XHTML 1.0 Strict//EN" "DTD/xhtml11-strict.dtd"> <html> <head>Form Submission</head> <body> <pre> %s </pre> </body> </html>""" % message def process_form(): req_fields = {"from":None, "to":None, "subject":None, "nextpage":None} valid_urls = ["mycompany.org", "www.mycompany.org"] url = urlparse.urlparse(os.environ["HTTP_REFERER"]) if url[1] not in valid_urls: debug("The site calling this script is not autnorized to send e-mail.") return form = cgi.FieldStorage() """ Add extra data to the submission: """ field_list = "\ndate: %s\n" % datetime.now().strftime("%A, %B %d, %Y") """ Iterate through submitted form and check for required fields """ for field in form.keys(): value = form[field].value if req_fields.has_key(field): req_fields[field] = value else: field_list = field_list + "%s: %s\n" % (field, value) for key in req_fields: if req_fields[key] == None: debug("A required field is missing: %s" % key) return """ Add the From: and To: headers at the start """ msg = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (req_fields["from"], req_fields["to"], req_fields["subject"])) msg = msg + field_list server = smtplib.SMTP("localhost") server.sendmail(req_fields["from"], req_fields["to"], msg) server.quit() """ Output redirection instead of xhtml """ print "Location: %s" % req_fields["nextpage"] print if __name__ == "__main__": process_form()
The output of CGI scripts usually limited by the web server, so to diagnose this script run it from the command with a fake environment:
% env HTTP_REFERER="www.mycompany.org/feedback.html" ./submit.cgi