current fusion version

This commit is contained in:
lars 2008-06-26 14:09:04 +00:00
parent b2e04c1721
commit f3341b093a
10 changed files with 217 additions and 78 deletions

View file

@ -27,7 +27,7 @@ sqlobject.dburi="sqlite://%(current_dir_uri)s/devdata.sqlite"
# SERVER # SERVER
# Some server parameters that you may want to tweak # Some server parameters that you may want to tweak
# server.socket_port=8080 server.socket_port=80
# Enable the debug output at the end on pages. # Enable the debug output at the end on pages.
# log_debug_info_filter.on = False # log_debug_info_filter.on = False

View file

@ -7,7 +7,7 @@ from turbogears import controllers, expose, flash, redirect
# log = logging.getLogger("fotokiste.controllers") # log = logging.getLogger("fotokiste.controllers")
class DummyPicture(object): class SamplePicture(object):
title = "leer" title = "leer"
url = "nichts" url = "nichts"
@ -17,19 +17,23 @@ import tempfile
import cherrypy import cherrypy
import re import re
import datetime import datetime
import random
IMAGE_STORE = os.path.join(tempfile.gettempdir(), "fotokiste.jpg") IMAGE_GALLERY_PATH = os.path.join(os.getcwd(), 'fotokiste', 'static', 'gallery')
VIDEO_URL = "http://webcam.glasmensch.org/?action=stream" IMAGE_SUFFIX = ".jpg"
SNAPSHOT_URL = "http://webcam.glasmensch.org/?action=snapshot" IMAGE_STORE = os.path.join(tempfile.gettempdir(), "fotokiste" + IMAGE_SUFFIX)
GALLERY_NUM = 12
VIDEO_URL = "http://fotokiste:8081/?action=stream"
SNAPSHOT_URL = "http://fotokiste:8081/?action=snapshot"
ALLOWED_MAILADDRESS_CHARACTERS = "\w._%@-" ALLOWED_MAILADDRESS_CHARACTERS = "\w._%@-"
ALLOWED_MAILTEXT_CHARACTERS = "\w@_\-\.\s\n\#\(\)\[\]\{\}\|\>\<\,\+/\'\"\?\!\:=%\$^&\*" ALLOWED_MAILTEXT_CHARACTERS = "\w@_\-\.\s\n\#\(\)\[\]\{\}\|\>\<\,\+/\'\"\?\!\:=%\$^&\*"
MAIL_ADDRESS_REGEX = r"^[a-zA-Z0-9._%-]+@[a-zA-Z0-9._%-]+\.[a-zA-Z]{2,6}$" 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! # TODO: this path is relative - to be fixed!
MAIL_SIGNATURE_FILE = "mail_signature.txt" MAIL_SIGNATURE_FILE = os.path.join(os.getcwd(), "mail_signature.txt")
MAIL_FROM_ADDRESS = '"Fusion-Fotokiste" <fotokiste@glasmensch.org>' MAIL_FROM_ADDRESS = '"Fusion-Fotokiste" <fotokiste@glasmensch.org>'
MAIL_SUBJECT = "Ein überwachungskritisches Foto von der Fusion!" MAIL_SUBJECT = "Ein überwachungskritisches Foto von der Fusion!"
MAIL_ATTACHMENT_FILENAME = "fusion.jpeg" MAIL_ATTACHMENT_FILENAME = "fusion" + IMAGE_SUFFIX
SMTP_HOST = "192.168.1.31" SMTP_HOST = "localhost"
SMTP_PORT = "25" SMTP_PORT = "25"
MAIL_MAX_LENGTH = 5000 MAIL_MAX_LENGTH = 5000
ERRORS_MAX_LENGTH = 25 ERRORS_MAX_LENGTH = 25
@ -65,6 +69,33 @@ def check_mailaddress(address):
else: else:
return False 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): def send_mail(address, text):
import smtplib import smtplib
import StringIO import StringIO
@ -125,11 +156,12 @@ class Root(controllers.RootController):
def index(self, **kargs): def index(self, **kargs):
# TODO: this should generate a selection of random pictures # TODO: this should generate a selection of random pictures
pic_names = get_random_pictures()
gallery = [] gallery = []
for i in range(22): for i in range(len(pic_names)):
obj = DummyPicture() obj = SamplePicture()
obj.title = "test%d" % i obj.title = "pic%d" % (i+1)
obj.url = "URL: %d" % i obj.url = "%s" % pic_names[i]
gallery.append(obj) gallery.append(obj)
# remove old picture # remove old picture
@ -146,10 +178,13 @@ class Root(controllers.RootController):
@expose(template="fotokiste.templates.mailtext") @expose(template="fotokiste.templates.mailtext")
def mailtext(self, mailaddress="", mailtext="", already_stored="no", **kargs): def mailtext(self, mailaddress="", mailtext="", already_captured="no", already_stored="no", **kargs):
# store the picture if necessary # store the picture if necessary
if already_stored != "yes": if already_captured != "yes":
urllib.urlretrieve(SNAPSHOT_URL, IMAGE_STORE) urllib.urlretrieve(SNAPSHOT_URL, IMAGE_STORE)
already_captured = "no"
if already_stored != "yes":
already_stored = "no"
# filter input # filter input
mailaddress = filter_mailaddress(mailaddress) mailaddress = filter_mailaddress(mailaddress)
mailtext = filter_mailtext(mailtext) mailtext = filter_mailtext(mailtext)
@ -165,14 +200,17 @@ class Root(controllers.RootController):
@expose(template="fotokiste.templates.senden") @expose(template="fotokiste.templates.senden")
def senden(self, mailaddress="", mailtext="", senden=None): def senden(self, mailaddress="", mailtext="", already_stored="no", senden=None):
# filter input # filter input
mailaddress = filter_mailaddress(mailaddress) mailaddress = filter_mailaddress(mailaddress)
mailtext = filter_mailtext(mailtext) mailtext = filter_mailtext(mailtext)
if already_stored != "yes":
already_stored = "no"
return_dict = merged_dicts({ return_dict = merged_dicts({
"mailaddress": mailaddress, "mailaddress": mailaddress,
"mailtext": mailtext, "mailtext": mailtext,
"already_stored": already_stored,
}, DEFAULT_DICT) }, DEFAULT_DICT)
# check for a valid mail address and redirect if necessary # check for a valid mail address and redirect if necessary
if not check_mailaddress(mailaddress): if not check_mailaddress(mailaddress):
@ -183,6 +221,8 @@ class Root(controllers.RootController):
redirect("mailtext", return_dict) redirect("mailtext", return_dict)
else: else:
# send the mail # send the mail
if already_stored != "yes":
store_picture()
if send_mail(mailaddress, mailtext): if send_mail(mailaddress, mailtext):
return return_dict return return_dict
else: else:

View file

@ -5,7 +5,17 @@ body {
text-align: center; text-align: center;
font: 1em Arial, Helvetica, sans-serif; font: 1em Arial, Helvetica, sans-serif;
} }
input.button {
margin: 5px 20px 5px 20px;
text-align: center;
font-size: large;
}
label {
font-size: large;
}
#header { #header {
/** background: url(../static/images/header.jpg) top left no-repeat; /** background: url(../static/images/header.jpg) top left no-repeat;
position: relative; position: relative;
@ -56,13 +66,8 @@ body {
* fails to show up sometimes * fails to show up sometimes
*/ */
#mail_pic img { #mail_pic img {
width: 320px; width: 350px;
height: 240px; height: 260px;
}
#live_pic img {
width: 320px;
height: 240px;
} }
/* Styles for the text area */ /* Styles for the text area */
@ -70,7 +75,7 @@ body {
position: relative; position: relative;
margin: 15px auto 15px auto; margin: 15px auto 15px auto;
padding: 0; padding: 0;
width: 90%; width: 95%;
text-align: left; text-align: left;
line-height: 1.25em; line-height: 1.25em;
} }
@ -110,12 +115,16 @@ h2 {
padding: 20px; padding: 20px;
} }
#vkb { #vkb {
margin: 0 auto 0 15%; margin: 0 auto 0 15%;
} }
img.gallery {
width: 100px;
height: 60px;
}
/* Style for the footer */ /* Style for the footer */
#footer { #footer {
padding: 2px; padding: 2px;

View file

@ -0,0 +1,38 @@
/* Copyright (C) 2007 Richard Atterer, richard©atterer.net
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License, version 2. See the file
COPYING for details. */
var imageNr = 0; // Serial number of current image
var finished = new Array(); // References to img objects which have finished downloading
var paused = false;
function createImageLayer() {
var img = new Image();
img.style.position = "absolute";
img.style.zIndex = -1;
img.style.width = "400px";
img.style.height = "320px";
img.onload = imageOnload;
img.onclick = imageOnclick;
img.src = "http://fotokiste:8081/?action=snapshot&n=" + (++imageNr);
var webcam = document.getElementById("live_pic");
webcam.insertBefore(img, webcam.firstChild);
}
// Two layers are always present (except at the very beginning), to avoid flicker
function imageOnload() {
this.style.zIndex = imageNr; // Image finished, bring to front!
while (1 < finished.length) {
var del = finished.shift(); // Delete old image(s) from document
del.parentNode.removeChild(del);
}
finished.push(this);
if (!paused) createImageLayer();
}
function imageOnclick() { // Clicking on the image will pause the stream
paused = !paused;
if (!paused) createImageLayer();
}

View file

@ -96,7 +96,7 @@
</tr> </tr>
<tr> <tr>
<td colspan="2" class="buttons"> <td colspan="2" class="buttons">
<input type="submit" name="login" value="Login"/> <input class="button" type="submit" name="login" value="Login"/>
</td> </td>
</tr> </tr>
</table> </table>

View file

@ -11,31 +11,37 @@
<body> <body>
<table> <table>
<tr><td> <tr>
<td>
<form action="${tg.url('/')}" method="post">
<input class="button" type="submit" name="senden" value="Zur&uuml;ck" />
</form>
</td><td>
<div id="mail_pic"><img src="../static/images/fotokiste-default.png" <div id="mail_pic"><img src="../static/images/fotokiste-default.png"
py:attrs="src=tg.url('/get_current_shot')"/></div> py:attrs="src=tg.url('/get_current_shot')"/></div>
<form action="${tg.url('/ausloeser')}" method="post">
<input type="submit" name="senden" value="Zur&uuml;ck" />
</form>
</td> </td>
<td> <td>
<div id="mail_info"> <div id="mail_info">
<form action="${tg.url('/senden')}" method="post"> <form action="${tg.url('/senden')}" method="post">
<label for="mailaddress">An:</label> <table><tr><td>
<label for="mailaddress">An:</label><br/>
<input type="textfield" id="mailaddress" <input type="textfield" id="mailaddress"
name="mailaddress" value="${mailaddress}" size="30" name="mailaddress" value="${mailaddress}" size="40"
onfocus="VirtualKeyboard.attachInput(this)" /> onfocus="VirtualKeyboard.attachInput(this)" />
<br/> <br/>
<label for="mailtext">Text:</label> <br/>
<label for="mailtext">Text:</label><br/>
<textarea name="mailtext" id="mailtext" <textarea name="mailtext" id="mailtext"
rows="10" cols="40" wrap="physical" rows="5" cols="40" wrap="physical"
onfocus="VirtualKeyboard.attachInput(this)" onfocus="VirtualKeyboard.attachInput(this)"
>${mailtext}</textarea> >${mailtext}</textarea>
<br/> </td><td>
<input type="submit" name="senden" value="senden" /> <input class="button" type="submit" name="senden" value="Senden!" />
</form> </td></tr></table>
</form>
</div> </div>
</td></tr> </td>
</tr>
</table> </table>
<div id="vkb"></div> <div id="vkb"></div>
<script type="text/javascript"> <script type="text/javascript">

View file

@ -17,6 +17,7 @@
</style> </style>
<link rel="stylesheet" type="text/css" media="screen" href="../static/css/1024optimized.css" <link rel="stylesheet" type="text/css" media="screen" href="../static/css/1024optimized.css"
py:attrs="href=tg.url('/static/css/1024optimized.css')"/> py:attrs="href=tg.url('/static/css/1024optimized.css')"/>
<title>Bild versenden</title>
</head> </head>
<body py:match="item.tag=='{http://www.w3.org/1999/xhtml}body'" py:attrs="item.items()"> <body py:match="item.tag=='{http://www.w3.org/1999/xhtml}body'" py:attrs="item.items()">
@ -38,12 +39,14 @@
<div id="main_content"> <div id="main_content">
<!--
<div id="nav"> <div id="nav">
<ul> <ul>
<li><a href="#">Privacy Shades</a></li> <li><a href="#">Privacy Shades</a></li>
<li><a href="#">Start</a></li> <li><a href="/">Start</a></li>
</ul> </ul>
</div> </div>
-->
<div id="status_block" class="flash" <div id="status_block" class="flash"
py:if="value_of('tg_flash', None)" py:content="tg_flash"></div> py:if="value_of('tg_flash', None)" py:content="tg_flash"></div>
<div py:replace="[item.text]+item[:]"> <div py:replace="[item.text]+item[:]">
@ -56,13 +59,6 @@
</div> </div>
</div> </div>
<div id="footer">
<p>
<img src="${tg.url('/static/images/logo.png')}" alt="Sense.Lab e.V." /> <br/>
Die Fotokiste ist ein Sense.Lab Projekt und ein Modul der Glasmensch Ausstellung.<br/>
Alle Inhalte k&ouml;nnen wegen der Creative Commons Lizenz beliebig weiter verwendet werden.
</p>
</div>
</body> </body>
</html> </html>

View file

@ -8,19 +8,31 @@
<body> <body>
<table>
<tr><td>
<div id="mail_pic"><img src="../static/images/fotokiste-default.png" <div id="mail_pic"><img src="../static/images/fotokiste-default.png"
py:attrs="src=tg.url('/get_current_shot')"/></div> py:attrs="src=tg.url('/get_current_shot')"/></div>
</td><td>
<div id="mail_info"> <div id="mail_info">
<form action="${tg.url('/mailtext')}" method="post"> <form action="${tg.url('/mailtext')}" method="post">
<input type="hidden" name="mailtext" value="${mailtext}" /> <input type="hidden" name="mailtext" value="${mailtext}" />
<input type="hidden" name="already_stored" value="yes" /> <input type="hidden" name="already_stored" value="yes" />
<input type="submit" name="send" value="Erneut versenden" /> <input type="hidden" name="already_captured" value="yes" />
<input class="button" type="submit" name="send" value="Erneut versenden" />
</form> </form>
<form action="${tg.url('/')}" method="post"> <form action="${tg.url('/')}" method="post">
<input type="submit" name="send" value="Fertig" /> <input class="button" type="submit" name="send" value="Fertig!" />
</form> </form>
</div> </div>
</td></tr>
</table>
<div id="footer">
<p>
<img src="${tg.url('/static/images/logo.png')}" alt="Sense.Lab e.V." /> <br/>
Die Fotokiste ist ein sense.lab-Projekt und ein Modul der Glasmensch-Ausstellung.<br/>
Alle Inhalte k&ouml;nnen im Sinne einer Creative Commons Lizenz (BY-SA) beliebig weiter verwendet werden.
</p>
</div>
</body> </body>
</html> </html>

View file

@ -4,19 +4,24 @@
<head> <head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/> <meta content="text/html; charset=utf-8" http-equiv="Content-Type" py:replace="''"/>
<title>Willkommen in der Fotokiste!</title> <title>Willkommen in der Fotokiste!</title>
<script type="text/javascript" src="../static/javascript/mjp-streamer.js"
py:attrs="src=tg.url('/static/javascript/mjp-streamer.js')" />
<title>Bild versenden</title>
</head> </head>
<body> <body onload="createImageLayer();">
<table> <table>
<tr> <tr>
<td> <td>
<div id="live_pic"><img src="../static/images/fotokiste-default.png" <div id="live_pic"><noscript><img width="400" height="320"
py:attrs="src=video_url"/></div> src="../static/images/fotokiste-default.jpg"
py:attrs="src=video_url"/></noscript></div>
<div id="default_pic"><img width="400" height="320"
src="../static/images/fotokiste-default.jpg" /></div>
</td> </td>
<td valign="center"> <td valign="center">
<!-- TODO: einfach nur ein weiterfuehrendes Icon - kein Formular --> <form action="${tg.url('/mailtext')}" method="post">
<form action="${tg.url('/ausloeser')}" method="post"> <input class="button" type="submit" value="Bild senden" />
<input type="submit" value="Bild senden" />
</form> </form>
</td> </td>
</tr> </tr>
@ -25,24 +30,57 @@
<div id="gallery"> <div id="gallery">
<!-- see http://www.kid-templating.org/trac/wiki/GenerateTableFromListRecipe --> <!-- see http://www.kid-templating.org/trac/wiki/GenerateTableFromListRecipe -->
<?python i= iter(gallery); rows= map(None, i, i, i, i, i, i, i, i, i, i, i) ?> <?python i= iter(gallery); rows= map(None, i, i, i, i, i, i, i, i, i, i, i) ?>
<table> <table>
<tr py:for="row in rows"> <tr>
<td py:for="picture in row"> <td><img class="gallery" src="../static/images/platzhalter.jpg"
<img py:if="picture" py:strip="False" alt="${gallery[0].title}"
title="${picture.title}" width="50" height="64" py:attrs="src=tg.url('static/gallery/') + gallery[0].url" /></td>
src="../static/images/platzhalter.jpg" <td><img class="gallery" src="../static/images/platzhalter.jpg"
py:attrs="src=tg.url('/static/images/platzhalter.jpg')" alt="${gallery[1].title}"
TODO="${picture.url}" /> py:attrs="src=tg.url('static/gallery/') + gallery[1].url" /></td>
</td> <td><img class="gallery" src="../static/images/platzhalter.jpg"
</tr> alt="${gallery[2].title}"
py:attrs="src=tg.url('static/gallery/') + gallery[2].url" /></td>
<td><img class="gallery" src="../static/images/platzhalter.jpg"
alt="${gallery[3].title}"
py:attrs="src=tg.url('static/gallery/') + gallery[3].url" /></td>
<td><img class="gallery" src="../static/images/platzhalter.jpg"
alt="${gallery[4].title}"
py:attrs="src=tg.url('static/gallery/') + gallery[4].url" /></td>
<td><img class="gallery" src="../static/images/platzhalter.jpg"
alt="${gallery[5].title}"
py:attrs="src=tg.url('static/gallery/') + gallery[5].url" /></td>
<td><img class="gallery" src="../static/images/platzhalter.jpg"
alt="${gallery[6].title}"
py:attrs="src=tg.url('static/gallery/') + gallery[6].url" /></td>
<td><img class="gallery" src="../static/images/platzhalter.jpg"
alt="${gallery[7].title}"
py:attrs="src=tg.url('static/gallery/') + gallery[7].url" /></td>
</tr>
<tr>
<td><img class="gallery" src="../static/images/platzhalter.jpg"
alt="${gallery[8].title}"
py:attrs="src=tg.url('static/gallery/') + gallery[8].url" /></td>
<td><img class="gallery" src="../static/images/platzhalter.jpg"
alt="${gallery[9].title}"
py:attrs="src=tg.url('static/gallery/') + gallery[9].url" /></td>
<td colspan="4">
<img src="${tg.url('/static/images/logo.png')}" alt="Sense.Lab e.V." /></td>
<td><img class="gallery" src="../static/images/platzhalter.jpg"
alt="${gallery[10].title}"
py:attrs="src=tg.url('static/gallery/') + gallery[10].url" /></td>
<td><img class="gallery" src="../static/images/platzhalter.jpg"
alt="${gallery[11].title}"
py:attrs="src=tg.url('static/gallery/') + gallery[11].url" /></td>
</tr>
</table> </table>
</div> </div>
<div> <div id="footer">
<div class="notice">Falls du Fragen zur FotoKiste hast, dann schau mal auf die <p>
<a href="http://glasmensch.org/fotokiste.html">Webseite</a> oder schreib eine Mail Die Fotokiste ist ein sense.lab-Projekt und ein Modul der Glasmensch-Ausstellung.<br/>
an <a href="mailto:fotokiste@glasmensch.org">fotokiste@glasmensch.org</a>. Alle Inhalte k&ouml;nnen im Sinne einer Creative Commons Lizenz (BY-SA) beliebig weiter verwendet werden.
</div> </p>
</div> </div>
</body> </body>
</html> </html>

View file

@ -1,4 +1,4 @@
#!/usr/bin/python #!/usr/bin/env python2.4
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Start script for the fotokiste TurboGears project. """Start script for the fotokiste TurboGears project.