623
22.10
Lösungen
Abb. 22.15: Vom CGI-Skript dynamisch erzeugte HTML-Seite
22.10 Lösungen
Lösung 1
Nur die Klasse Chatraum und die HTTP-Schablone (die konzeptionell zu dieser Klasse
gehört) müssen erweitert werden; der Rest des Originalskripts und die statische HTML-
Seite bleiben, wie sie sind. Die geänderten Passagen im folgenden Skriptauszug sind fett
gedruckt.
Skript:
http_SCHABLONE = '''Content-Type: text/html
<html>
<head><title>Python-Chat</title></head>
<body><h1>Python-Chat</h1>
{} <hr>
<form action="http://localhost:8000/cgi-bin/chat1.py" method="POST">
<input type="hidden" name="name" value="{}">
Ich sage:&nbsp;
<input type="Text" name="beitrag" size="40" maxlength="40">
<input type="Submit" value="OK"><br><br>
<input type="Radio" name="typ" value="normal"
checked="checked"> normal &nbsp
<input type="Radio" name="typ" value="schreien">
schreiend &nbsp
<input type="Radio" name="typ" value="fluestern"> fl&uuml;sternd
</form></body></html>'''
class Chatraum:
Kapitel 22
CGI-Programmierung
624
Erläuterung:
#1: Zusätzlich wird der Inhalt der neuen Variablen typ also der Wert eines der Radiobut-
tons – ausgelesen.
#2: In dieser verschachtelten if-Anweisung wird in Abhängigkeit vom Inhalt von self.typ
der Text des Beitrags formatiert.
#3: Der String in der Variablen text enthält einen Platzhalter {}, die nun mithilfe der
String-Methode
format() durch den eingegebenen Text ersetzt werden (siehe dazu
Abschnitt 13.3.1).
#4: Der lange String mit dem HTML-Quelltext enthält zusätzlich die Definition dreier Radio-
buttons. Sie haben alle den gleichen Namen
typ, aber unterschiedliche Werte (normal,
schreien, fluestern). Neben jedem Radiobutton steht ein Wort (NORMAL, SCHREIEND oder
FLÜSTERND, gefolgt von einem »harten« Leerzeichen (&nbsp).
Lösung 2
Wenn Sie den Verzeichnisbaum python/httpserver auf Ihren Rechner kopiert haben,
können Sie so die Lösung testen: Starten Sie den http-Server
python/httpserver/
httpd.py
. Öffnen Sie im Webbrowser den URL http://localhost:8000/html/abstim-
mungstart.html
.
HTML-Quelltext für die statische HTML-Seite:
def __init__(self):
self.form = cgi.FieldStorage()
self.dialog = Dialog(
'chat/dialog.txt')
self.beitrag = self.form.getvalue('beitrag')
self.name = self.form.getvalue('name')
self.typ = self.form.getvalue('typ', 'normal') #1
if str(self.beitrag):
if self.typ == 'fluestern': #2
text = ' <font size="-1" color=#9F9F9F>{} </font>'
elif self.typ == 'schreien':
text = ' <font size="+2" color=#FF0000>{} </font>'
else:
text = ' {}'
text = text.format(self.beitrag) #3
self.dialog.aktualisiere(self.name, text)
def __str__(self):
return http_SCHABLONE.format(self.dialog,
self.name) #4
<html>
<head>
625
22.10
Lösungen
CGI-Skript:
<title>Abstimmung</title>
</head>
<body>
<h2> Willkommen zur Online-Abstimmung!</h2>
<h3> Sind Studiengeb&uuml;hren an Unis sinnvoll?</h3>
<form action="http://localhost:8000/cgi-bin/abstimmung.py"
method="GET">
<input type="Radio" name="item" value="Ja">&nbsp;ja<br>
<input type="Radio" name="item" value="Nein">&nbsp;nein<br><br>
<input type="Submit" value="abstimmen">
</form>
</body>
</html>
#!/Python35/python.exe
import cgi, os, pickle, http.cookies, cgitb
# Globale Konstanten:
SEITE = """{}
Content-Type: text/html;
<html>
<head><title>Online-Abstimmung</title></head>
<body><h1>Online-Abstimmung</h1>
<h3> {} </h3>
Hier ist das aktuelle Abstimmungsergebnis:<br>
Frage: {} <br><br> {}
</body>
</html>""" #1
PFAD = "abstimmung/zaehler.txt"
ITEMS = ["Ja", "Nein"]
FRAGE = "Sind Studiengeb&uuml;hren an Unis sinnvoll?"
cgitb.enable()
class Zaehler (object):
def __init__(self, datei,items):
self.datei = datei
try: # vorhandene Datei laden
f = open(datei,"rb") #2
Kapitel 22
CGI-Programmierung
626
self.stimmen = pickle.load(f)
f.close()
except: # neue Datei anlegen
self.stimmen = {}
for i in items:
self.stimmen[i] = 0
f = open(datei,"wb")
pickle.dump(self.stimmen, f)
f.close()
def votiere(self, item):
# item erhält eine Stimme
self.stimmen[item] += 1
f = open(self.datei, "wb")
pickle.dump(self.stimmen, f)
f.close()
def __str__(self):
# liefert HTML-Text mit Abstimmungsergebnis
ergebnis = ""
for i in self.stimmen.keys():
ergebnis += "<b>{}: </b>{} Stimmen<br>\n".format(
i,self.stimmen[i])
return ergebnis
class Abstimmung (object):
def __init__(self):
self.form = cgi.FieldStorage()
self.zaehler = Zaehler(PFAD, ITEMS)
if not self.__schon_mal_abgestimmt():
if "item" in self.form.keys():
item = self.form.getvalue('item')
self.zaehler.votiere(item)
self.meldung = "Vielen Dank f&uuml;r Ihr Voting!"
else:
self.meldung = "Sorry, Sie haben bereits abgestimmt ..."
def __schon_mal_abgestimmt(self):
# liefert True, falls schon mal abgestimmt wurde
#und sonst False
self.cookie = http.cookies.SimpleCookie()
try:
627
22.10
Lösungen
Erläuterung:
#1: Das ist die Schablone für das zurückgegebene HTTP-Paket. Sie enthält drei Platzhalter
{} für variable Teile. Der erste Platzhalter steht für das Cookie, das der Server an den Client
nach der ersten Abstimmung übergibt. Es befindet sich im Kopf des Pakets also vor der ers-
ten Leerzeile.
#2: Um pickle verwenden zu können, müssen Dateien im binären Modus geöffnet werden.
self.cookie.load(os.environ['HTTP_COOKIE'])
return bool(self.cookie['abstimmung'])
except:
self.cookie['abstimmung'] = True
return False
def __str__(self):
return SEITE.format(self.cookie, self.meldung,
FRAGE, self.zaehler)
print(Abstimmung())

Get Python 3 - Lernen und professionell anwenden now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.