current fusion version
This commit is contained in:
parent
b2e04c1721
commit
f3341b093a
10 changed files with 217 additions and 78 deletions
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -6,6 +6,16 @@ body {
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -115,6 +120,10 @@ h2 {
|
||||||
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 {
|
||||||
|
|
38
fotokiste/fotokiste/static/javascript/mjp-streamer.js
Normal file
38
fotokiste/fotokiste/static/javascript/mjp-streamer.js
Normal 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();
|
||||||
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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ü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ü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">
|
||||||
|
|
|
@ -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önnen wegen der Creative Commons Lizenz beliebig weiter verwendet werden.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -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önnen im Sinne einer Creative Commons Lizenz (BY-SA) beliebig weiter verwendet werden.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -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>
|
||||||
|
@ -26,23 +31,56 @@
|
||||||
<!-- 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önnen im Sinne einer Creative Commons Lizenz (BY-SA) beliebig weiter verwendet werden.
|
||||||
</div>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue