diff --git a/fotokiste/fotokiste/controllers.py b/fotokiste/fotokiste/controllers.py index 4286bb2..56cb7fc 100644 --- a/fotokiste/fotokiste/controllers.py +++ b/fotokiste/fotokiste/controllers.py @@ -1,5 +1,7 @@ +# -*- coding: utf-8 -*- + import turbogears as tg -from turbogears import controllers, expose, flash +from turbogears import controllers, expose, flash, redirect # from fotokiste import model # import logging # log = logging.getLogger("fotokiste.controllers") @@ -10,8 +12,90 @@ class DummyPicture(object): url = "nichts" import os +import urllib +import tempfile +import cherrypy +import re +import datetime + +IMAGE_STORE = os.path.join(tempfile.gettempdir(), "fotokiste.jpg") +VIDEO_URL = "http://localhost:8081/?action=stream" +SNAPSHOT_URL = "http://localhost:8081/?action=snapshot" +ALLOWED_MAILADDRESS_CHARACTERS = "\w._%@-" +ALLOWED_MAILTEXT_CHARACTERS = "\w@_\-\.\s\n\#\(\)\[\]\{\}\|\>\<\,\+/\'\"\?\!\:=%\$^&\*" +MAIL_SIGNATURE_FILE = "mail_signature.txt" +MAIL_FROM_ADDRESS = "fotokiste@glasmensch.org" +MAIL_SUBJECT = "Ein Foto von der Fusion!" +SMTP_HOST = "localhost" +SMTP_PORT = "25" +MAIL_MAX_LENGTH = 5000 + + +DEFAULT_DICT = { "video_url": VIDEO_URL } + +def debug(message): + print "%s: %s" % (datetime.datetime.now().isoformat(), message) + +def merged_dicts(dict_a, dict_b): + return dict(dict_a.items() + dict_b.items()) + +def filter_mailaddress(address): + return re.sub("[^%s]" % ALLOWED_MAILADDRESS_CHARACTERS, "", address) + +def filter_mailtext(text): + filtered = re.sub("[^%s]" % ALLOWED_MAILTEXT_CHARACTERS, "", text) + if len(filtered) > MAIL_MAX_LENGTH: + return filtered[:MAIL_MAX_LENGTH-1] + else: + return filtered + +def check_mailaddress(address): + if re.match("^[a-zA-Z0-9._%-]+@[a-zA-Z0-9._%-]+\.[a-zA-Z]{2,6}$", address): + return True + else: + return False + +def send_mail(address, text): + import smtplib + import MimeWriter + import StringIO + import base64 + # read the additional mail parts (signature and picture) + try: + signature = file(MAIL_SIGNATURE_FILE).read() + except IOError, msg: + debug("failed to open the signature file (%s): %s" % \ + (MAIL_SIGNATURE_FILE, msg)) + try: + picture = StringIO.StringIO(file(IMAGE_STORE).read()) + except IOError, msg: + debug("failed to open the image file (%s): %s" % \ + (IMAGE_STORE, msg)) + + # prepare the message + message = StringIO.StringIO() + writer = MimeWriter.MimeWriter(message) + writer.addheader("Subject", MAIL_SUBJECT) + # the picture should be shown inline by the mail clients + writer.addheader("Content-Disposition", "inline") + writer.startmultipartbody('mixed') + # start off with a text/plain part + part = writer.nextpart() + body = part.startbody('text/plain') + body.write(text + signature) + # now add an attachment + part = writer.nextpart() + # the 'Content-Disposition' is necessary for displaying the image inline + part.addheader('Content-Disposition', 'attachment; filename="fusion.jpeg"') + part.addheader('Content-Transfer-Encoding', 'base64') + body = part.startbody('image/jpeg') + base64.encode(picture, body) + # finish off + writer.lastpart() + + con = smtplib.SMTP(SMTP_HOST, SMTP_PORT) + con.sendmail(address, MAIL_FROM_ADDRESS, message.getvalue()) -IMAGE_STORE = os.tempnam() class Root(controllers.RootController): @@ -31,40 +115,59 @@ class Root(controllers.RootController): if os.path.isfile(IMAGE_STORE): os.unlink(IMAGE_STORE) - return { "gallery": gallery } + return merged_dicts({ "gallery": gallery }, DEFAULT_DICT) @expose(template="fotokiste.templates.ausloeser") def ausloeser(self, **kargs): flash("Das Bild wird in 5 Sekunden aufgenommen!") - return {} + return merged_dicts({}, DEFAULT_DICT) @expose(template="fotokiste.templates.mailtext") - def mailtext(self, mailtext=None, already_stored="no", **kargs): - # mailtext filtern + def mailtext(self, mailaddress="", mailtext="", already_stored="no", **kargs): + # store the picture if necessary + if already_stored != "yes": + urllib.urlretrieve(SNAPSHOT_URL, IMAGE_STORE) + # filter input + mailaddress = filter_mailaddress(mailaddress) + mailtext = filter_mailtext(mailtext) - # "already_stored" filtern - if already_stored != "no": - already_stored = "yes" - return { - "mailtext": mailtext, - "already_stored": already_stored, - } + #if not check_mailaddress(mailaddress): + # turbogears.flash( - @expose(template="fotokiste.templates.senden") - def senden(self, mailaddress=None, mailtext=None, already_stored=False, **kargs): - # Bild speichern, falls "already_stored" falsch ist - # Mail versenden - - # mailaddress filtern - # mailtext filtern - - # das Bild wurde gerade gespeichert - already_stored = "yes" - - return { + return merged_dicts({ "mailaddress": mailaddress, "mailtext": mailtext, "already_stored": already_stored, - } + }, DEFAULT_DICT) + + @expose(template="fotokiste.templates.senden") + def senden(self, mailaddress="", mailtext="", senden=None): + # filter input + mailaddress = filter_mailaddress(mailaddress) + mailtext = filter_mailtext(mailtext) + + return_dict = merged_dicts({ + "mailaddress": mailaddress, + "mailtext": mailtext, + }, DEFAULT_DICT) + # check for a valid mail address and redirect if necessary + if not check_mailaddress(mailaddress): + if not mailaddress: + flash("Gib bitte eine Ziel-Mailadresse an!") + else: + flash("Die Mailadresse scheint nicht ungueltig zu sein.") + redirect("mailtext", return_dict) + else: + # Mail versenden + send_mail(mailaddress, mailtext) + return return_dict + + @expose() + def get_current_shot(self): + if os.path.exists(IMAGE_STORE): + return cherrypy.lib.cptools.serveFile(IMAGE_STORE, + "image/jpeg") + else: + return "" diff --git a/fotokiste/fotokiste/static/css/1024optimized.css b/fotokiste/fotokiste/static/css/1024optimized.css index 2d0c771..bbbc515 100644 --- a/fotokiste/fotokiste/static/css/1024optimized.css +++ b/fotokiste/fotokiste/static/css/1024optimized.css @@ -53,6 +53,19 @@ body { text-decoration: none; } +/* dimensions are necessary - otherwise the picture/video + * fails to show up sometimes + */ +#mail_pic img { + width: 320px; + height: 240px; +} + +#live_pic img { + width: 320px; + height: 240px; +} + /* Styles for the text area */ #main_content { position: relative; diff --git a/fotokiste/fotokiste/templates/ausloeser.kid b/fotokiste/fotokiste/templates/ausloeser.kid index d1f1dd8..cf6fb91 100644 --- a/fotokiste/fotokiste/templates/ausloeser.kid +++ b/fotokiste/fotokiste/templates/ausloeser.kid @@ -9,11 +9,7 @@
-