# -*- coding: utf-8 -*- import turbogears as tg from turbogears import controllers, expose, flash, redirect # from fotokiosk import model # import logging # log = logging.getLogger("fotokiosk.controllers") class SamplePicture(object): title = "leer" url = "nichts" import os import urllib import tempfile import cherrypy import re import datetime import random IMAGE_GALLERY_PATH = os.path.join(os.getcwd(), 'fotokiosk', 'static', 'gallery') IMAGE_SUFFIX = ".jpg" IMAGE_STORE = os.path.join(tempfile.gettempdir(), "fotokiosk" + IMAGE_SUFFIX) GALLERY_NUM = 12 VIDEO_URL = "http://fotokiosk:8080/?action=stream" SNAPSHOT_URL = "http://fotokiosk:8080/?action=snapshot" ALLOWED_MAILADDRESS_CHARACTERS = "\w._%@-" ALLOWED_MAILTEXT_CHARACTERS = "\w@_\-\.\s\n\#\(\)\[\]\{\}\|\>\<\,\+/\'\"\?\!\:=%\$^&\*" MAIL_ADDRESS_REGEX = r"^[a-zA-Z0-9._%-]+@[a-zA-Z0-9._%-]+\.[a-zA-Z]{2,6}$" # TODO: this path is relative - to be fixed! MAIL_SIGNATURE_FILE = os.path.join(os.getcwd(), "mail_signature.txt") MAIL_FROM_ADDRESS = '"Fotokiosk" ' MAIL_SUBJECT = "Ein Foto fuer Kinderrechte!" MAIL_ATTACHMENT_FILENAME = "kinderrechte" + IMAGE_SUFFIX SMTP_HOST = "localhost" SMTP_PORT = "25" MAIL_MAX_LENGTH = 5000 ERRORS_MAX_LENGTH = 25 errors = [] DEFAULT_DICT = { "video_url": VIDEO_URL } def debug(message): log_msg = "%s: %s" % (datetime.datetime.now().isoformat(), message) errors.append(log_msg) # remove old messages, if necessary while len(errors) > ERRORS_MAX_LENGTH: del errors[0] print log_msg 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(MAIL_ADDRESS_REGEX, address): return True else: return False def store_picture(): if not os.path.isdir(IMAGE_GALLERY_PATH): os.mkdir(IMAGE_GALLERY_PATH) import shutil timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") filename = os.path.join(IMAGE_GALLERY_PATH, "%s%s" % (timestamp, IMAGE_SUFFIX)) shutil.copy(IMAGE_STORE, filename) def get_random_pictures(): default = [""] * GALLERY_NUM try: result = [] all_files = [fname for fname in os.listdir(IMAGE_GALLERY_PATH) if os.path.isfile(os.path.join(IMAGE_GALLERY_PATH, fname)) and fname.endswith(IMAGE_SUFFIX)] if not all_files: return default all_files.sort() print all_files # the last five pictures result.extend(all_files[-5:]) while len(result) < GALLERY_NUM: result.append(all_files[random.randint(0, len(all_files)-1)]) return result except OSError: return default def send_mail(address, text): import smtplib import StringIO import email.Generator import email.MIMEMultipart import email.MIMEText import email.MIMEImage import rfc822 # 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)) return False try: picture = file(IMAGE_STORE).read() except IOError, msg: debug("failed to open the image file (%s): %s" % \ (IMAGE_STORE, msg)) return False # prepare the message #mail_flat = StringIO.StringIO() #mail_gen = email.Generator.Generator(mail_flat) #mail_gen.flatten(body) mail = email.MIMEMultipart.MIMEMultipart() mail_text = email.MIMEText.MIMEText((unicode(text) + unicode(signature, 'latin-1')).encode('utf-8'), _charset='utf-8') mail_pict = email.MIMEImage.MIMEImage(picture, "jpeg") mail_pict.add_header("Content-Disposition", 'attachment; filename="%s"' % MAIL_ATTACHMENT_FILENAME) mail.add_header("Subject", MAIL_SUBJECT) mail.add_header("To", address) mail.add_header("From", MAIL_FROM_ADDRESS) mail.add_header("Date", rfc822.formatdate()) mail.add_header("Content-Disposition", "inline") mail.attach(mail_text) mail.attach(mail_pict) writer = StringIO.StringIO() email.Generator.Generator(writer).flatten(mail) # send the mail try: con = smtplib.SMTP(SMTP_HOST, SMTP_PORT) con.sendmail(MAIL_FROM_ADDRESS, address, writer.getvalue()) con.quit() except (smtplib.SMTPHeloError, smtplib.SMTPRecipientsRefused, smtplib.SMTPSenderRefused, smtplib.SMTPDataError), msg: debug("an error occoured while sending the mail: %s" % msg) return False return True class Root(controllers.RootController): @expose(template="fotokiosk.templates.start") def index(self, **kargs): # TODO: this should generate a selection of random pictures pic_names = get_random_pictures() gallery = [] for i in range(len(pic_names)): obj = SamplePicture() obj.title = "pic%d" % (i+1) obj.url = "%s" % pic_names[i] gallery.append(obj) # remove old picture if os.path.isfile(IMAGE_STORE): os.unlink(IMAGE_STORE) return merged_dicts({ "gallery": gallery }, DEFAULT_DICT) @expose(template="fotokiosk.templates.ausloeser") def ausloeser(self, **kargs): flash("Das Bild wird in 3 Sekunden aufgenommen!") return merged_dicts({}, DEFAULT_DICT) @expose(template="fotokiosk.templates.mailtext") def mailtext(self, mailaddress="", mailtext="", already_captured="no", already_stored="no", **kargs): # store the picture if necessary if already_captured != "yes": try: urllib.urlretrieve(SNAPSHOT_URL, IMAGE_STORE) except: #os.system("reboot") flash("Achtung: dein Foto enthaelt moeglicherweise menschenverachtende Inhalte. Bitte wende dich fuer einen umfassenden Persoenlichkeitstest an der Bar. Danke fuer deine Kooperation!") redirect("index", DEFAULT_DICT) already_captured = "no" if already_stored != "yes": already_stored = "no" # filter input mailaddress = filter_mailaddress(mailaddress) mailtext = filter_mailtext(mailtext) #if not check_mailaddress(mailaddress): # turbogears.flash( return merged_dicts({ "mailaddress": mailaddress, "mailtext": mailtext, "already_stored": already_stored, }, DEFAULT_DICT) @expose(template="fotokiosk.templates.senden") def senden(self, mailaddress="", mailtext="", already_stored="no", senden=None): # filter input mailaddress = filter_mailaddress(mailaddress) mailtext = filter_mailtext(mailtext) if already_stored != "yes": already_stored = "no" return_dict = merged_dicts({ "mailaddress": mailaddress, "mailtext": mailtext, "already_stored": already_stored, }, 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: # send the mail if already_stored != "yes": store_picture() if send_mail(mailaddress, mailtext): return return_dict else: flash("Fehler beim Senden der Mail! Ist die Adresse korrekt?") redirect("mailtext", 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 ""