seit einiger Zeit versuche ich mich jetzt mit Python. Leider hilft das Buch nicht wirklich da ich immer wieder auf Schwierigkeiten stoße. In der Hoffnung die Probleme mit dem localhost zu umgehen habe ich jetzt, auf einem anderen Rechner, einen Server laufen (Ubuntu Server 20.04 mit Apache2). Aber auch hier laufen die Skripte aus dem Buch, bzw Download nicht. (Dem Server habe ich gleich nach Installation ein Update verpasst, die Browser auf meinem Rechner sind alle aktuell.)
Durch ausgiebige Suche konnte ich schon die *.py-Dateien soweit anpassen, das die ursprünglichen Fehler nicht mehr auftreten. Diese waren:
- redaktion.py: End of script output before headers: redaktion.py
- abstimmung4.py:Response header name '<!--' contains invalid characters, aborting request, referer: http://homeserv.fritz.box/python/abstimmung/abstimmung.html
Abstimmung, Pfade:
- /var/www/html/python/abstimmung/abstimmung4.html
- /usr/lib/cgi-bin/abstimmung4.py
Bei Firefox und Chromium: Set-Cookie: abstimmung=True
und bei Google Chrome Set-Cookie: abstimmung=True Set-Cookie: nc_sameSiteCookielax=true Set-Cookie: nc_sameSiteCookiestrict=true Set-Cookie: oc_sessionPassphrase=Rv6311eBYAjX9MJLTrkTY2x8jS3AQ0nAOxOWj4YemB3gqcdi2fJvzqh8XqW54fdae4nwwRF9Fg9liPRecvDWZGEQ6vw2%2B6NjcviHbc2HwXHtiQM6FVtdBRXqa%2FiVIVkD Set-Cookie: ocnoslie8ssv=a4aa54bac8019b45da7dc520731edb8a
Die abstimmung4.py:
Code: Alles auswählen
#!/usr/bin/python3
import cgi, cgitb, os, pickle, http.cookies
cgitb.enable()
print("Content-type: text/html\n")
SEITE = '''{}
<html>
<head>
<title>Online-Abstimmung</title>
</head>
<body>
<h1>Online-Abstimmung</h1>
<form action="http://homeserv.fritz.box/cgi-bin/abstimmung4.py">
<h3>{}</h3>
Hier ist das aktuelle Abstimmungsergebnis:<br>
Frage: {}
<br><br> {} </br>
</form>
</body>
</html>
'''
PFAD = 'zaehler4.txt'
ITEMS = ["Ja","Nein","Enthaltung"]
FRAGE = "Sind Studiengebühren an Unis sinnvoll?"
class Zaehler(object):
def __init__(self, datei, items):
self.datei = datei
try:
f = open(PFAD, 'rb') # im Buch: datei
self.stimmen = pickle.load(f)
f.close()
except:
self.stimmen={}
for i in items:
self.stimmen[i]=0
f=open(PFAD, 'wb') # im Buch: datei
pickle.dump(self.stimmen, f)
f.close()
def votiere(self,item):
self.stimmen[item] += 1
f=open(PFAD, 'wb') # im Buch: self.datei
pickle.dump(self.stimmen, f)
f.close()
def __str__(self):
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ür Ihr Voting!"
else:
self.meldung = "Sorry, Sie haben bereits abgestimmt ..."
def __schon_mal_abgestimmt(self):
self.cookie = http.cookies.SimpleCookie()
try:
self.cookie.load(os.environ['HTTP_COOKIE'])
return bool(self.cookie['abstimmung']) # im Buch fehlt am anfang ein Leerzeichen
except:
self.cookie['abstimmung'] = True
return False
def __str__(self):
return SEITE.format(self.cookie, self.meldung, FRAGE, self.zaehler)
print(Abstimmung())
- /var/www/html/python/redaktion/login_redaktion.html
- /usr/lib/cgi-bin/redaktion.py
Die redaktion.py
Code: Alles auswählen
#!/usr/bin/python3
import sqlite3, cgi, hashlib, time, logging
logging.basicConfig(filename="tmp/logging.txt",
format="%(funcName)s: %(message)s",
level=logging.DEBUG,
filemode="w") #2
print("Content-type: text/html\n")
# Schablone für HTML-Seite
# Platzhalter {}: Name, Passwort, Text, Fehler im Beitrag,
# Fehler im Passwort
SEITE1 = """
<html>
<head>
<title>Python-Redaktionssystem</title>
<meta http-equiv="Content-Type" content="charset=utf-8" />
</head>
<body bgcolor=#C0C0C0>
<h2>Python-Redaktionssystem</h2>
<form method="POST" >
<input type="hidden" name="name" value="{}">
<input type="hidden" name="passwort" value="{}">
<b>Titel: </b>
<input type="Text" name="titel"
size="50" maxlength="80"><br><br>
<textarea name="text" cols="50" rows="8" >{}
</textarea><br>
<h4>Haltbarkeit</h4>
<input type="Radio" name="haltbar" value="14"
checked="checked">
2 Wochen <br>
<input type="Radio" name="haltbar" value="30">
1 Monat <br>
<input type="Radio" name="haltbar" value="90">
3 Monate <br>
<input type="Radio" name="haltbar" value="180">
6 Monate <br>
<h4> Passwortverwaltung</h4>
<input type="Checkbox" name="neuespass" value="1">
Passwort ändern<br>
<input type="Password" name="neupass1" > Neues Passwort<br>
<input type="Password" name="neupass2" > Passwort wiederholen<br>
<input type="Submit" value="Absenden">
</form>
<i>{}<br>{}<br></i>
</body></html>"""
# HTML-Seite mit Fehlermeldung bei falschem Login
SEITE2 = """
<html>
<head><title>Rython-Redaktionssystem</title>
<meta http-equiv="Content-Type" content="charset=utf-8" />
</head>
<body bgcolor=#C0C0C0>
<h2> Python-Redaktionssystem</h2>
<form method="POST">
Name: <input type="Text" name="name" >
Passwort: <input type="Password"
name="passwort"><br><br>
<input type="Submit" value="Login">
</form>
<b> Login gescheitert! Überprüfen Sie Name und
Passwort.<b>
</body></html>"""
# Schablone für Webseite (Publikation)
# Platzhalter {}: Zeit und Beiträge
WEBSEITE = """<html>
<head><title>Python-News</title></head>
<body>
<h1>Python-News</h1>
Letzte Änderung: {}
{}
</body></html>"""
# Schablone für Beitrag
# Platzhalter {}: Titel, Autor und Text
BEITRAG = """<h3>{}</h3>
<h4>von {}</h4>
<p>{}</p>"""
HTML = {ord("ä"): "ä", ord("ö"): "ö",
ord("ü"): "ü", ord("Ä"): "Ä",
ord("Ö"): "Ö", ord("Ü"): "Ü",
ord("ß"): "ß"} #2
class Person(object): #3
def __init__(self, form, db):
self.name = form.getvalue("name")
self.pw = form.getvalue("passwort")
self.db = db
def id_ok(self): #4
logging.debug("Name: {}, Passwort:{}".format(
self.name,self.pw))
try:
logging.debug(self.db)
verbindung = sqlite3.connect(self.db)
c = verbindung.cursor()
c.execute("""SELECT *
FROM person
WHERE name = ?;""", (self.name,))
logging.debug("Mit Datenbank verbunden.")
fingerprint_db = list(c)[0][1] #5
pw_bytes = self.pw.encode("utf-8") #6
fingerprint_pw = hashlib.md5(pw_bytes).digest()
c.close()
verbindung.close()
return fingerprint_db == fingerprint_pw #7
except:
return False
def aktualisiere_pw(self, form): #8
neupw1 = form.getvalue("neupass1", "")
neupw2 = form.getvalue("neupass2", "")
if neupw1 == neupw2:
self.pw = neupw1
verbindung = sqlite3.connect(self.db)
c = verbindung.cursor()
c.execute("""UPDATE person
SET fingerprint = ?
WHERE name = ?;
""",
(hashlib.md5(self.pw.encode("utf-8")).digest(),
self.name))
verbindung.commit()
c.close()
verbindung.close()
return "Passwort geändert."
else:
return "Fehler! Passwörter nicht gleich!"
class Beitrag(object): #9
def __init__(self, form, autor, db):
self.text = self.titel = ""
self.db = db
self.autor = autor
if "titel" in form.keys():
self.text = form.getvalue("text")
self.titel = form.getvalue("titel")
sekunden = float(form.getvalue("haltbar")) *24*3600
self.verfallsdatum = sekunden + time.time()
logging.debug("Verfallsdatum:" + str(self.verfallsdatum))
def publiziere(self):
if self.titel: #10
logging.debug("Titel: " + self.titel)
logging.debug("Text: " + self.text)
verbindung = sqlite3.connect(self.db)
c = verbindung.cursor()
c.execute("""SELECT *
FROM beitrag
WHERE titel = ?;""",
(self.titel,))
if not list(c): #11
c.execute("""INSERT INTO beitrag
VALUES(?, ?, ?, ?);""",
(self.titel, self.text,
self.verfallsdatum,
self.autor.name))
logging.debug("Gespeichert: " + self.titel)
verbindung.commit()
self.text = ""
self.titel = ""
meldung = "Beitrag wurde gespeichert."
else:
meldung = "Titel existiert bereits."
c.close()
verbindung.close()
else: meldung = ""
return meldung
def aktualisiere_news(self, news_pfad):
# HTML-Datei mit Journal aktualisieren
verbindung = sqlite3.connect(self.db)
c = verbindung.cursor()
beiträge = list(
c.execute("""select * FROM beitrag;"""))
pubtext =""
for (titel, text, verfallsdatum,
autor) in beiträge: #12
if float(verfallsdatum) > time.time():
pubtext += BEITRAG.format(
titel.translate(HTML),
autor.translate(HTML),
text.translate(HTML))
else: #13
c.execute("""DELETE FROM beitrag
WHERE titel = ?;""", (titel,))
logging.debug("Veröffentlichter Text:"+pubtext)
verbindung.commit()
c.close()
verbindung.close()
# Speichern
f = open(news_pfad, "w")
f.write(WEBSEITE.format(time.asctime(), pubtext))
f.close()
# Konstanten
DB = "redaktion.db"
NEWS_PFAD = "html/news.html"
# WSGI Applikationsfunktion
def application(environ, start_response):
status = '200 OK'
form = cgi.FieldStorage(
fp=environ['wsgi.input'],
environ=environ,
keep_blank_values=True)
redakteur = Person(form, DB) #14
beitrag = Beitrag(form, redakteur, DB)
beitragfehler = "" #15
pwfehler = ""
if redakteur.id_ok(): #16
beitragfehler = beitrag.publiziere()
beitrag.aktualisiere_news(NEWS_PFAD)
if "neuespass" in form.keys():
pwfehler = redakteur.aktualisiere_pw(form)
content_string = SEITE1.format(redakteur.name,
redakteur.pw,
beitrag.text,
beitragfehler,
pwfehler)
content = content_string.encode('utf-8')
else:
content = SEITE2.encode('utf-8')
response_headers = [('Content-type', 'text/html'),
('Content-Length', str(len(content)))]
start_response(status, response_headers)
return [content]
print(Beitrag)
Kann mir jemand da weiterhelfen?