Es ist auch nicht so wirklich schlau den gleichen Namen im gleichen Namensraum für völlig unterschiedliche Dinge zu verwenden.
Auf Modulebene gehört nur Code der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
`cgitb` sollte als allererstes importiert werden und sofort danach die `enable()`-Funktion aufgerufen werden. Sonst bekommt man keinen Traceback für Code der davor steht im Browser zu sehen.
Namen sollte man nicht kryptisch abkürzen. Wenn man `connection` meint, sollte man nicht `conn` schreiben. Und einbuchtabige Namen wie `c` für `cursor` gehen gar nicht wenn der Gütigkeitsbereich sich über mehr als einen Ausdruck erstreckt. Das Ding heisst `cursor`.
Die Datenbankverbindung sollte man auch sauber wieder schliessen. Bei `sqlite3` ist die Verbindung netterweise ein Kontextmanager und kann deshalb mit ``with`` verwendet werden.
Den Datenbankdateinamen würde man als Konstante definieren, damit ihn einfacher am Anfang des Programms ändern kann. Die Vorlage für die Antwort auch.
Die Klammern im SQL sind überflüssig und ich würde keine Umlaute in Namen verwenden.
Die ``while``-Schleife ist so überhaupt kein idiomatisches Python. Umständlicher kann man das ja kaum ausdrücken. Man kann in Python mit einer ``for``-Schleife *direkt* über die Elemente von Sequenzwerten iterieren, ohne den Umweg über einen Index. Der dann auch noch manuell hochgezählt wird und das damit auch noch vor die Schleife und ans Schleifenende verteilt wird.
Selbst die Liste braucht man nicht, weil man über `sqlite3.Cursor`-Objekte nach dem Ausführen einer Anfrage direkt iterieren kann. Sonst würde das ``list(c)`` auch gar nicht funktionieren, das nutzt diesen Umstand ja auch.
Zeichenketten durch wiederholtes addieren von neuen Teilen aufzubauen ist ineffizient. Idiomatisches Python sammelt die Teile in einer Liste und fügt die hinterher mit der `join()`-Methode von Zeichenketten zusammen.
Dass es ``format()`` gibt weisst Du ja bereits, warum stückelst Du dann das HTML so unübersichtlich mit ``+`` zusammen?
Wenn man Werte in HTML einbaut, muss man darauf achten das die nichts enthalten was in HTML eine Bedeutung hat, sonst macht man sich im besten Fall einfach nur die Seite kaputt und hat im schlechtesten Fall wieder eine Sicherheitslücke.
Man kann das mit `html.escape()` absichern. Dann muss man immer aufpassen was man schon escaped hat, damit man a) nichts vergisst, aber b) auch nichts doppelt escaped. Da ist es besser wenn man so etwas wie das `markupsafe`-Modul verwendet oder gleich eine Template-Engine wie Jinja2.
Zwischenstand (ungetestet):
Code: Alles auswählen
#!/usr/bin/env python3
import cgitb
cgitb.enable()
import cgi
import html
import sqlite3
DB_FILENAME = "/var/www/html/datenbanken/mxstream_musik.db"
SONG_LINE_TEMPLATE = (
'{title}'
' <audio controls><source src="{path}" type="audio/mpeg"></audio><br/>'
)
TEMPLATE = """Content-type: text/html; charset=utf-8
<!DOCTYPE html>
<html>
<head><title>Ergebnisse</title></head>
<body>
<p>Suche nach {}</p>
<p>{}</p>
</body>
</html>"""
def main():
search_term = cgi.FieldStorage().getvalue("search")
with sqlite3.connect() as connection:
cursor = connection.cursor()
cursor.execute(
"SELECT titel, pfad"
" FROM musik"
" WHERE titel=? OR album=? OR kuenstler=?",
search_term,
search_term,
search_term,
)
song_lines = "".join(
SONG_LINE_TEMPLATE.format(
title=html.escape(title), path=html.escape(path)
)
for title, path in cursor
)
print(TEMPLATE.format(html.escape(search_term), song_lines))
if __name__ == "__main__":
main()