diff options
Diffstat (limited to 'www-apps/pyblosxom-plugins/files/contact.py')
-rw-r--r-- | www-apps/pyblosxom-plugins/files/contact.py | 390 |
1 files changed, 0 insertions, 390 deletions
diff --git a/www-apps/pyblosxom-plugins/files/contact.py b/www-apps/pyblosxom-plugins/files/contact.py deleted file mode 100644 index d3fcf38..0000000 --- a/www-apps/pyblosxom-plugins/files/contact.py +++ /dev/null @@ -1,390 +0,0 @@ -""" -Provides a form to send an email to the blog-owner. - -If you make any changes to this plugin, please send a patch to -<sa+pyblosxom at c-area dot ch> so I can incorporate them. -Thanks! - - -To install: -1) Put contact.py in your plugin directory. -2) In config.py add 'contact' to py['load_plugins'] -3) Add the following variables to config.py: - py['contact_urltrigger'] = "/contact" # optional, this is the default - py['contact_smtp_server'] = "localhost" # required - py['contact_smtp_to'] = "you@example.com" # required -4) Optionally create a template named contact.<flavour> in your flavour directory. - If no contact.<flavour> exists a simple default is used. See _default_template below. - - -Dependencies: - - My compatibility plugin if you're not using pyblosxom 1.2+. - - -$Id: contact.py,v 1.6 2005/08/25 13:21:48 sar Exp $ -""" -__author__ = "Steven Armstrong <sa at c-area dot ch>" -__version__ = "$Revision: 1.6 $ $Date: 2005/08/25 13:21:48 $" -__url__ = "http://www.c-area.ch/code/" -__description__ = "Provides a form to send an email to the blog-owner." -__license__ = "GPL 2+" - - -# Python imports -import urlparse - -# Pyblosxom imports -from Pyblosxom.renderers.blosxom import Renderer -from Pyblosxom import tools - - -# Variables -TRIGGER = "/contact" -TRIGGER_KEY = "contact_urltrigger" -INIT_KEY = "contact_initiated" -MESSAGE_KEY = "contact_error_message" -_form_fields = ['name', 'email', 'subject', 'message'] - -_default_template = """ -<div> -<h2>Contact me</h2> -<div style="display:block;">$contact_error_message</div> -<form name="contactForm" id="contactForm" method="post" action="$base_url$contact_urltrigger"> -<div class="contactLine"> - <div class="contactLabel"> - <label class="contactLine" for="name" title="Your name">Name</label> - </div> - <input type="text" name="name" id="name" value="$contact_name" /><br /> -</div> -<div class="contactLine"> - <div class="contactLabel"> - <label class="contactLine" for="email" title="Your email address">Email</label> - </div> - <input type="text" name="email" id="email" value="$contact_email" /><br /> -</div> -<div class="contactLine"> - <div class="contactLabel"> - <label class="contactLine" for="subject" title="Subject of your message">Subject</label> - </div> - <input class="contactLine" type="text" name="subject" id="subject" value="$contact_subject" /><br /> -</div> -<div class="contactText"> - <div class="contactLabel"> - <label class="contactText" for="message" title="Your message">Message</label> - </div> - <textarea name="message" id="message" style="height:150px;">$contact_message</textarea><br /> -</div> -<div class="contactSubmit"> - <div class="contactButton"> - <input class="contactSubmit" type="submit" value="Send" style="width:auto; margin-right:0;" /> - </div> - <div class="contactButton"> - <input class="contactSubmit" type="reset" value="Reset" style="width:auto; margin-right:0;" /> - </div> -</div> -</form> -</div> -""" - -################################################################################ -## -## Helper functions -## -################################################################################ - -rfc822_specials = '()<>@,;:\\"[]' - -def isAddressValid(addr): - ''' - Taken from - - http://www.secureprogramming.com/?action=view&feature=recipes&recipeid=1 - - Posted by Matt Messier on Tue, Sep 02, 2003 (06:19 PM) GMT - - >>> isAddressValid('djfhdfh') - 0 - >>> isAddressValid('djfhdfh@test.com') - 8 - >>> isAddressValid('dj@fhdfh@test.com') - 0 - >>> isAddressValid('dj\@fhdfh@test.com') - 0 - >>> isAddressValid('dj"@"fhdfh@test.com') - 0 - >>> isAddressValid('dj" "fhdfh@test.com') - 0 - >>> isAddressValid('dj\" \"fhdfh@test.com') - 0 - >>> isAddressValid('dj." ".fhdfh@test.com') - 13 - >>> isAddressValid('dj."@ ".fhdfh@test.com') - 14 - >>> isAddressValid('dj."@<> ".fhdfh@test.com') - 16 - >>> isAddressValid('dj."@<>ü ".fhdfh@test.com') - 0 - >>> isAddressValid('dj<>fhdfh@test.com') - 0 - >>> isAddressValid('dj\<\>fhdfh@test.com') - 0 - >>> isAddressValid('dj\ fhdfh@test.com') - 0 - >>> isAddressValid('dj\\ fhdfh@test.com') - 0 - >>> isAddressValid('djfhdfh@test.com.de') - 8 - >>> isAddressValid('djfhdfh@test.co<m.de') - 0 - ''' - # Ported from Recipe 3.9 in Secure Programming Cookbook for C and C++ by - # John Viega and Matt Messier (O'Reilly 2003) - - # First we validate the name portion (name@domain) - c = 0 - while c < len(addr): - if addr[c] == '"' and (not c or addr[c - 1] == '.' or addr[c - 1] == '"'): - c = c + 1 - while c < len(addr): - if addr[c] == '"': - c = c + 1 - break - if addr[c] == '\\' and addr[c + 1] == ' ': - c = c + 2 - continue - if ord(addr[c]) < 32 or ord(addr[c]) >= 127: return 0 - c = c + 1 - else: return 0 - if addr[c] == '@': break - if addr[c] != '.': return 0 - c = c + 1 - continue - if addr[c] == '@': break - if ord(addr[c]) <= 32 or ord(addr[c]) >= 127: return 0 - if addr[c] in rfc822_specials: return 0 - c = c + 1 - if not c or addr[c - 1] == '.': return 0 - - # Next we validate the domain portion (name@domain) - domain = c = c + 1 - if domain >= len(addr): return 0 - count = 0 - while c < len(addr): - if addr[c] == '.': - if c == domain or addr[c - 1] == '.': return 0 - count = count + 1 - if ord(addr[c]) <= 32 or ord(addr[c]) >= 127: return 0 - if addr[c] in rfc822_specials: return 0 - c = c + 1 - - ## The final return statement was modified to return the split point - ## (position of @) so that the email can split in its two subsections. - if count >= 1: - return domain - - -def verify_installation(request): - config = request.getConfiguration() - retval = 1 - - if not 'contact_urltrigger' in config: - print "Missing optional property: 'contact_urltrigger'" - print "Using the default of '%s'" % TRIGGER - - _required = ['contact_smtp_server', 'contact_smtp_to'] - for prop in _required: - if not prop in config: - print "Missing required property: '%s'" % prop - retval = 0 - - return retval - - - -class ContactRenderer(Renderer): - - def render(self, header=1): - config = self._request.getConfiguration() - data = self._request.getData() - - # root_datadir is normaly set after the cb_pathinfo callback. - # but if a plugin implements cb_handle (as this one does), - # cb_pathinfo is never called. - # if root_datadir is not set and flavourdir is not set in config.py - # an exception is thrown in BlosxomRenderer._getFlavour. - # so set root_datadir here explicitly to prevent that. - if not 'root_datadir' in data: - data['root_datadir'] = config['datadir'] - - # initialize flavour - self.flavour = self._getFlavour(data.get('flavour', 'html')) - data['content-type'] = self.flavour['content_type'].strip() - if header: - self.addHeader("Status", "200 OK") - if self._needs_content_type and data['content-type'] != "": - self.addHeader('Content-type', '%s; charset=%s' % (data['content-type'], config.get('blog_encoding', 'iso-8859-1'))) - self.showHeaders() - - d = {} - d.update(config) - d.update(data) - - if 'head' in self.flavour: - self._outputFlavour(d, 'head') - - if not 'contact' in self.flavour: - self.flavour['contact'] = _default_template - self._outputFlavour(d, 'contact') - - if 'foot' in self.flavour: - self._outputFlavour(d, 'foot') - - self.rendered = 1 - - - -def _update_config(config): - if TRIGGER_KEY in config: - global TRIGGER - TRIGGER = config[TRIGGER_KEY] - else: - # set this explicitly so it's available in templates - config[TRIGGER_KEY] = TRIGGER - - -def _handle_post(request): - form = request.getForm() - data = request.getData() - http = request.getHttp() - config = request.getConfiguration() - - email = {} - error = False - error_messages = [] - - if not 'HTTP_REFERER' in http or \ - not http['HTTP_REFERER'].startswith('://'.join(urlparse.urlsplit(config['base_url'])[0:1])): - data[MESSAGE_KEY] = "Posting from foreign hosts not allowed.<br />\nUse the form below to send your message." - return - - for field in _form_fields: - if not field in form: - error_messages.append("Missing required field '%s'." % field) - error = True - else: - # strip markup - parser = tools.Stripper() - parser.feed(form[field].value) - email[field] = parser.gettext() - - if 'email' in email.keys() and not isAddressValid(email['email']): - error = True - error_messages.append("Invalid email address '%s'. Cannot deliver your message!" % email['email']) - - if error: - data[MESSAGE_KEY] = "<br />\n".join(error_messages) - _remember_email(email, data) - else: - success, data[MESSAGE_KEY] = _send_email(email, config) - if success: - _forget_email(data) - else: - _remember_email(email, data) - - -def _remember_email(email, data): - """ - Stores form fields in the data dict so they can be used to - populate the form in the template. - """ - for key in email: - data["contact_%s" % key] = email[key] - - -def _forget_email(data): - """ - Resets/forgets any stored form field values. - """ - for key in _form_fields: - key = "contact_%s" % key - if key in data: - del data[key] - - -def _send_email(email, config): - try: - try: from email.Utils import formatdate - except ImportError: from rfc822 import formatdate - import smtplib - - smtp = smtplib.SMTP(config['contact_smtp_server']) - - email['to'] = config["contact_smtp_to"] - email['date'] = formatdate(localtime=True) - - msg = """\ -From: %(name)s <%(email)s> -To: %(to)s -Date: %(date)s -Subject: %(subject)s - -%(message)s - -""" % email - - smtp.sendmail( - from_addr=email['email'], - to_addrs=config['contact_smtp_to'], - msg=msg - ) - smtp.quit() - except: - if hasattr(tools, "log_exception"): - tools.log_exception() - return (False, "Error: Problem sending email.") - else: - return (True, "Thanks for feeding my mailbox ;-)") - - - - -#****************************** -# Callbacks -#****************************** - -def cb_start(args): - request = args['request'] - http = request.getHttp() - config = request.getConfiguration() - _update_config(config) - - if http['PATH_INFO'].startswith(TRIGGER): - data = request.getData() - data[INIT_KEY] = True - - -def cb_handle(args): - request = args['request'] - data = request.getData() - - if INIT_KEY in data: - http = request.getHttp() - if http['REQUEST_METHOD'].upper() == "POST": - _handle_post(request) - else: - _forget_email(data) - - ContactRenderer(request, request.getResponse()).render() - - return 1 - - -def cb_end(args): - # cleanup - request = args['request'] - data = request.getData() - if INIT_KEY in data: - del data[INIT_KEY] - if MESSAGE_KEY in data: - del data[MESSAGE_KEY] - |