This commit is contained in:
darthsandmann
2016-10-16 21:53:15 +02:00
parent 0d10f8b9dc
commit c9f3117da1
412 changed files with 137942 additions and 0 deletions

View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="generator" content="pandoc">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title></title>
<style type="text/css">code{white-space: pre;}</style>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<h1 id="dokumentation-praktikum-2">Dokumentation: Praktikum 2</h1>
<h2 id="allgemeine-beschreibung-der-lösung">Allgemeine Beschreibung der Lösung</h2>
<p>Das Praktikum 2 ist in <em>Python</em> geschrieben und nutzt das Framework <em>CherryPy</em>, mit welchem eine Website zur Verwendung erzeugt wird.</p>
<p>Dieser Server läuft mit einer Datenbank, welche Informationen via des Python-Moduls <em>json</em> in Dateien abspeichern und auslesen kann.</p>
<p>Die Website wird durch ein Template erzeugt, welches durch die Template-Engine <em>mako</em> umgesetzt wird, wodurch Daten aus der Datenbank ausgeben werden können.</p>
<h2 id="beschreibung-der-komponenten">Beschreibung der Komponenten</h2>
<h3 id="zweck">Zweck</h3>
<p>Die Website stellt den Inhalt einer Absolventenfeier dar. Es besteht die Möglichkeit sich für diese anzumelden, mit der Option sich auch wieder abzumelden. Dieser Prozess wird durch ein Passwort geschützt, welches der Benutzer selber wählen kann. Die Daten die eingeben wurden, können jederzeit geändert werden, es muss jedoch das Passwort eingeben werden.</p>
<h3 id="aufbau">Aufbau</h3>
<p><strong>server.py</strong></p>
<p>Die <em>server.py</em> hat die Aufgabe die Website bereitzustellen und nutzt hierfür das <em>CherryPy-Framework</em>, sowie die folgenden Module.</p>
<p><strong>application.py</strong></p>
<p>Die <em>application.py</em> leitet Anfragen, die durch die Website, welche durch das <em>CherryPy-Framework</em> erzeugt wurde, an die anderen Module weiter.</p>
<p><strong>datenbank.py</strong></p>
<p>Die <em>datenbank.py</em> stellt den Speicher des Systems dar. Sie dient als Schnittstelle, um Daten abzuspeichern, verändern, oder zu löschen.</p>
<p><strong>anzeigen.py</strong></p>
<p>Die <em>anzeigen.py</em> generiert die Templates, welche benötigt werden, um die Informationen auf der Website anzuzeigen. Um dies zu ermöglichen wird die <em>mako-Engine</em> verwendet.</p>
<h3 id="zusammenwirken-der-komponenten">Zusammenwirken der Komponenten</h3>
<p>Durch die <em>server.py</em> werden die Anfragen durch das <em>CherryPy-Framework</em> erkannt und weitergeleitet an die <em>application.py</em> Die <em>application.py</em> verarbeitet die Anfragen und gibt Anweisungen an die <em>datenbank.py</em> und <em>anzeigen.py</em> was mit diesen geschehen soll. Im folgenden werden diese Anweisungen dann von der <em>datenbank.py</em> und <em>anzeigen.py</em> ausgeführt.</p>
<h2 id="datenablage">Datenablage</h2>
<p>Die Daten, die von der <em>datenbank.py</em> verarbeitet werden, liegen in dem Verzeichnis &quot;/data/&quot; und liegen im &quot;.json&quot; Format vor. Als Dateiname wird die jeweilige ID (abhängig von der Reihenfolge der Anmeldung) des Benutzers mit der Endung &quot;.json&quot; verwendet. In der &quot;letztes.json&quot; wird immer die zuletzt verwendete ID gespeichert, damit das System weiß, bis zu welcher ID Daten vorliegen.</p>
</body>
</html>

View File

@ -0,0 +1,64 @@
#Dokumentation: Praktikum 2#
##Allgemeine Beschreibung der Lösung
Das Praktikum 2 ist in *Python* geschrieben und nutzt das Framework *CherryPy*, mit welchem eine Website zur
Verwendung erzeugt wird.
Dieser Server läuft mit einer Datenbank, welche Informationen via des Python-Moduls *json* in Dateien abspeichern
und auslesen kann.
Die Website wird durch ein Template erzeugt, welches durch die Template-Engine *mako* umgesetzt wird, wodurch
Daten aus der Datenbank ausgeben werden können.
##Beschreibung der Komponenten
###Zweck
Die Website stellt den Inhalt einer Absolventenfeier dar. Es besteht die Möglichkeit sich für diese anzumelden,
mit der Option sich auch wieder abzumelden. Dieser Prozess wird durch ein Passwort geschützt, welches der Benutzer
selber wählen kann. Die Daten die eingeben wurden, können jederzeit geändert werden, es muss jedoch das Passwort
eingeben werden.
###Aufbau
**server.py**
Die *server.py* hat die Aufgabe die Website bereitzustellen und nutzt hierfür das *CherryPy-Framework*, sowie die folgenden Module.
**application.py**
Die *application.py* leitet Anfragen, die durch die Website, welche durch das *CherryPy-Framework* erzeugt wurde,
an die anderen Module weiter.
**datenbank.py**
Die *datenbank.py* stellt den Speicher des Systems dar. Sie dient als Schnittstelle, um Daten abzuspeichern, verändern, oder zu löschen.
**anzeigen.py**
Die *anzeigen.py* generiert die Templates, welche benötigt werden, um die Informationen auf der Website anzuzeigen.
Um dies zu ermöglichen wird die *mako-Engine* verwendet.
###Zusammenwirken der Komponenten
Durch die *server.py* werden die Anfragen durch das *CherryPy-Framework* erkannt und weitergeleitet an die *application.py*
Die *application.py* verarbeitet die Anfragen und gibt Anweisungen an die *datenbank.py* und *anzeigen.py* was mit diesen geschehen soll.
Im folgenden werden diese Anweisungen dann von der *datenbank.py* und *anzeigen.py* ausgeführt.
##Datenablage
Die Daten, die von der *datenbank.py* verarbeitet werden, liegen in dem Verzeichnis "/data/" und liegen im ".json" Format vor.
Als Dateiname wird die jeweilige ID (abhängig von der Reihenfolge der Anmeldung) des Benutzers mit der Endung ".json" verwendet.
In der "letztes.json" wird immer die zuletzt verwendete ID gespeichert, damit das System weiß, bis zu welcher ID Daten vorliegen.

BIN
Sammlung/P2/P2.zip Normal file

Binary file not shown.

View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,31 @@
# coding: utf-8
import os.path
from mako.template import Template
from mako.lookup import TemplateLookup
class anzeigen_az(object):
def __init__(self):
self.path_s = 'template'
self.lookup_o = TemplateLookup(directories=['/'])
def erzeugen_az(self, template_praktikum, inhalt_person):
template_praktikum = Template(filename=os.path.join(self.path_s, template_praktikum), output_encoding='utf-8', lookup=self.lookup_o)
return template_praktikum.render(inhalt_alle = inhalt_person)
def erzeugen_anzeigen_az(self, inhalt_person):
return self.erzeugen_az('anzeigen.html', inhalt_person)
def erzeugen_bearbeiten_az(self, id, inhalt_person):
inhalt_person['id'] = id
return self.erzeugen_az('bearbeiten.html', inhalt_person)
def passwort_az(self, id, inhalt_person):
inhalt_person['id'] = id
return self.erzeugen_az('passwort.html', inhalt_person)
def passwort_loeschen_az(self, id, inhalt_person):
inhalt_person['id'] = id
return self.erzeugen_az('passwort_loeschen.html', inhalt_person)
#EOF

View File

@ -0,0 +1,100 @@
# coding: utf-8
# id ->
# id_s -> einlesen aus datei
import cherrypy
from app import datenbank
from app import anzeigen
class programm(object):
def __init__(self):
self.datenbank_py = datenbank.datenbank_db()
self.anzeigen_py = anzeigen.anzeigen_az()
def index(self):
return self.erzeugen_anzeigen_app()
index.exposed = True
def hinzufuegen_app(self):
return self.erzeugen_bearbeiten_app()
hinzufuegen_app.exposed = True
def passwort_app(self, id):
return self.erzeugen_passwort_app(id)
passwort_app.exposed = True
def passwort_loeschen_app(self, id):
return self.erzeugen_passwort_loeschen_app(id)
passwort_loeschen_app.exposed = True
def bearbeiten_app(self, id_s, pw):
inhalt_alle = self.datenbank_py.lesen_json_db(id_s)
if pw == inhalt_alle['Passwort']:
return self.erzeugen_bearbeiten_app(id_s)
elif pw == "" or pw != inhalt_alle['Passwort']:
return self.erzeugen_anzeigen_app()
bearbeiten_app.exposed = True
# ** damit die übergebene Variable beliebig groß sein kannst, ansonsten würde py nur "Vorname" kennen
def speichern_app(self, **inhalt_person):
id_s = inhalt_person["id_s"]
inhalt_alle = {
'Vorname': inhalt_person["Vorname_s"],
'Nachname': inhalt_person["Nachname_s"],
'Gaeste': inhalt_person["Gaeste_s"],
'Studiengang': inhalt_person["Studiengang_s"],
'Betreuer': inhalt_person["Betreuer_s"],
'Passwort': inhalt_person["Passwort_s"],
'Matrikelnummer': inhalt_person["Matrikelnummer_s"]
}
if id_s != "None":
self.datenbank_py.update_json_db(id_s, inhalt_alle)
else:
id_s = self.datenbank_py.erzeugen_json_db(inhalt_alle)
return self.anzeigen_py.erzeugen_bearbeiten_az(id_s, inhalt_alle)
speichern_app.exposed = True
def loeschen_app(self, id_s, pw):
inhalt_alle = self.datenbank_py.lesen_json_db(id_s)
if pw == inhalt_alle['Passwort']:
self.datenbank_py.loesche_json_db(id_s)
return self.erzeugen_anzeigen_app()
elif pw =="" or pw!= inhalt_alle['Passwort']:
return self.erzeugen_anzeigen_app()
loeschen_app.exposed = True
def fehler_app(self, *arguments, **kwargs):
msg_s = "Fehler: " + \
str(arguments) + \
' ' + \
str(kwargs)
raise cherrypy.HTTPError(404, msg_s)
fehler_app.exposed = True
def erzeugen_anzeigen_app(self):
inhalt_alle = self.datenbank_py.lesen_json_db()
return self.anzeigen_py.erzeugen_anzeigen_az(inhalt_alle)
def erzeugen_bearbeiten_app(self, id = None):
if id != None:
inhalt_alle = self.datenbank_py.lesen_json_db(id)
else:
inhalt_alle = self.datenbank_py.inhalt_db()
return self.anzeigen_py.erzeugen_bearbeiten_az(id, inhalt_alle)
def erzeugen_passwort_app(self, id):
inhalt_alle = self.datenbank_py.lesen_json_db(id)
return self.anzeigen_py.passwort_az(id, inhalt_alle)
def erzeugen_passwort_loeschen_app(self, id):
inhalt_alle = self.datenbank_py.lesen_json_db(id)
return self.anzeigen_py.passwort_loeschen_az(id, inhalt_alle)
#EOF

View File

@ -0,0 +1,76 @@
# coding: utf-8
import os
import os.path
import codecs
import json
class datenbank_db(object):
def __init__(self):
self.inhalt_alle = {}
self.lesen_inhalt_db()
def erzeugen_json_db(self, inhalt_person):
id = self.naechste_db()
datei = codecs.open(os.path.join('data', id+'.json'), 'w', 'utf-8')
datei.write(json.dumps(inhalt_person, indent=3, ensure_ascii=True))
datei.close()
self.inhalt_alle[id] = inhalt_person
return id
def lesen_json_db(self, id = None):
inhalt_alle = None
if id == None:
inhalt_alle = self.inhalt_alle
else:
if id in self.inhalt_alle:
inhalt_alle = self.inhalt_alle[id]
return inhalt_alle
def update_json_db(self, id, inhalt_person):
status_b = False
if id in self.inhalt_alle:
datei = codecs.open(os.path.join('data', id+'.json'), 'w', 'utf-8')
datei.write(json.dumps(inhalt_person, indent=3, ensure_ascii=True))
datei.close
self.inhalt_alle[id] = inhalt_person
status_b = True
return status_b
def loesche_json_db(self, id):
status_b = False
if id in self.inhalt_alle:
os.remove(os.path.join('data', id+'.json'))
del self.inhalt_alle[id]
status_b = True
return status_b
def inhalt_db(self):
return {
'Vorname': '',
'Nachname': '',
'Gaeste': '',
'Studiengang': '',
'Betreuer': '',
'Passwort': '',
'Matrikelnummer': ''
}
def lesen_inhalt_db(self):
ordner = os.listdir('data')
for dateiname in ordner:
if dateiname.endswith('.json') and dateiname != 'letztes.json':
datei = codecs.open(os.path.join('data', dateiname), 'rU', 'utf-8')
dateiinhalt = datei.read()
id = dateiname[:-4]
self.inhalt_alle[id] = json.loads(dateiinhalt)
def naechste_db(self):
datei = open(os.path.join('data', 'letztes.json'), 'r+')
letztes = datei.read()
letztes = str(int(letztes)+1)
datei.seek(0)
datei.write(letztes)
datei.close()
return letztes
# EOF

9
Sammlung/P2/data/1.json Normal file
View File

@ -0,0 +1,9 @@
{
"Betreuer": "Person X",
"Passwort": "12345",
"Vorname": "Person",
"Studiengang": "Informatik",
"Gaeste": "3",
"Matrikelnummer": "12345",
"Nachname": "A"
}

View File

@ -0,0 +1 @@
1

40
Sammlung/P2/server.py Normal file
View File

@ -0,0 +1,40 @@
#coding: utf-8
import os
import cherrypy
from app import application
#--------------------------------------
def main():
#--------------------------------------
# Get current directory
try:
current_dir = os.path.dirname(os.path.abspath(__file__))
except:
current_dir = os.path.dirname(os.path.abspath(sys.executable))
# disable autoreload and timeout_monitor
cherrypy.engine.autoreload.unsubscribe()
cherrypy.engine.timeout_monitor.unsubscribe()
# Static content config
static_config = {
'/': {
'tools.staticdir.root': current_dir,
'tools.staticdir.on': True,
'tools.staticdir.dir': '',
}
}
# Mount static content handler
root_o = cherrypy.tree.mount(application.programm(), '/', static_config)
# suppress traceback-info
cherrypy.config.update({'request.show_tracebacks': True})
cherrypy.config.update({'server.socket_port' : 8080})
# Start server
cherrypy.engine.start()
cherrypy.engine.block()
#--------------------------------------
if __name__ == '__main__':
#--------------------------------------
main()
# EOF

View File

@ -0,0 +1,60 @@
<!DOCTYPE html>
<html>
<head>
<title>
Absolventenfeier Main
</title>
<meta charset="UTF-8" />
<style type="text/css">
@import url("/template/template.css");
</style>
</head>
<body>
<h1 id="idSiteHeader" class="clSiteHeader">
Absolventenfeier
</h1>
<div id="idContent" class="clContent">
<h2 id="idContentHeader" class="clContentHeader">
Übersicht
</h2>
<div id="idContentArea" class="clContentArea">
<table id="idList">
<tr>
<th>Vorname</th>
<th>Nachname</th>
<th>Anzahl der Begleitpersonen</th>
<th>Studiengang</th>
<th>Betreuer</th>
<th>Matrikelnr</th>
<th>&nbsp;</th></tr>
% for var in inhalt_alle:
<tr>
<td>${inhalt_alle[var]['Vorname']}</td>
<td>${inhalt_alle[var]['Nachname']}</td>
<td>${inhalt_alle[var]['Gaeste']}</td>
<td>${inhalt_alle[var]['Studiengang']}</td>
<td>${inhalt_alle[var]['Betreuer']}</td>
<td>${inhalt_alle[var]['Matrikelnummer']}</td>
<td>
<a href="/passwort_app/${var}">Bearbeiten</a>
<a href="/passwort_loeschen_app/${var}">Löschen </a>
</td>
</tr>
% endfor
</table>
</div>
<div id="idButtonArea" class="clButtonArea">
<a href="/hinzufuegen_app" class="clButton">Neuer Teilnehmer</a>
<a href="./Dokumentation.html" class="clButton">Dokumentation</a>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html>
<head>
<title>
Registrierung
</title>
<meta charset="UTF-8" />
<style type="text/css">
@import url("/template/template.css");
</style>
</head>
<body>
<h1 id="idSiteHeader" class="clSiteHeader">
Ihre Daten
</h1>
<form id="idForm" class="clContent" action="/speichern_app" method="POST">
<h2 id="idContentHeader" class="clContentHeader">
Das Formular ausfüllen/korrigieren und auf "speichern" klicken:
</h2>
<div id="idContentArea" class="clContentArea">
<input type="hidden" value="${inhalt_alle['id']}" id="id_s" name="id_s" />
<div class="clFormRow">
<label for="vorname_s">Vorname</label>
<input type="text" value="${inhalt_alle['Vorname']}" id="Vorname_s" name="Vorname_s" />
</div>
<div class="clFormRow">
<label for="nachname_s">Nachname</label>
<input type="text" value="${inhalt_alle['Nachname']}" id="Nachname_s" name="Nachname_s" />
</div>
<div class="clFormRow">
<label for="gast_s">Anzahl der Begleitpersonen</label>
<input type="text" value="${inhalt_alle['Gaeste']}" id="Gaeste_s" name="Gaeste_s" />
</div>
<div class="clFormRow">
<label for="studiengang_s">Studiengang</label>
<input type="text" value="${inhalt_alle['Studiengang']}" id="Studiengang_s" name="Studiengang_s" />
</div>
<div class="clFormRow">
<label for="betreuer_s">Betreuer</label>
<input type="text" value="${inhalt_alle['Betreuer']}" id="Betreuer_s" name="Betreuer_s" />
</div>
<div class="clFormRow">
<label for="kennwort_s">Kennwort</label>
<input type="text" value="${inhalt_alle['Passwort']}" id="Passwort_s" name="Passwort_s" />
</div>
<div class="clFormRow">
<label for="matnr_s">Matrikelnummer</label>
<input type="text" value="${inhalt_alle['Matrikelnummer']}" id="Matrikelnummer_s" name="Matrikelnummer_s" />
</div>
</div>
<div id="idButtonArea" class="clButtonArea">
<a href="/index" title="Zurück zur Startseite">Zurück</a>
<input type="submit" value="Speichern" />
</div>
</form>
</body>
</html>

View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<title>
Registrierung
</title>
<meta charset="UTF-8" />
<style type="text/css">
@import url("/template/template.css");
</style>
</head>
<body>
<h1 id="idSiteHeader" class="clSiteHeader">
Passwort
</h1>
<form id="idForm" class="clContent" action="/bearbeiten_app" method="POST">
<h2 id="idContentHeader" class="clContentHeader">
Sie müssen zuerst ihr Passwort eingeben:
</h2>
<div id="idContentArea" class="clContentArea">
<input type="hidden" value="${inhalt_alle['id']}" id="id_s" name="id_s" />
<div class="clFormRow">
<label for="pw">Passwort</label>
<input type="text" value="" id="pw" name="pw" />
</div>
</div>
<div id="idButtonArea" class="clButtonArea">
<a href="/index" title="Zurück zur Startseite">Zurück</a>
<input type="submit" value="Bestätigen" />
</div>
</form>
</body>
</html>

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<title>
Registrierung
</title>
<meta charset="UTF-8" />
<style type="text/css">
@import url("/template/template.css");
</style>
</head>
<body>
<h1 id="idSiteHeader" class="clSiteHeader">
Passwortabfrage
</h1>
<form id="idForm" class="clContent" action="/loeschen_app" method="POST">
<h2 id="idContentHeader" class="clContentHeader">
Sie löschen mit diesem Schritt Ihre Daten aus der Datenbank!
</h2>
<div id="idContentArea" class="clContentArea">
<input type="hidden" value="${inhalt_alle['id']}" id="id_s" name="id_s" />
<div class="clFormRow">
<label for="pw">Passwort</label>
<input type="text" value="" id="pw" name="pw" />
</div>
</div>
<div id="idButtonArea" class="clButtonArea">
<a href="/index" title="Zurück zur Startseite">Zurück</a>
<input type="submit" value="Löschen" />
</div>
</form>
</body>
</html>

View File

@ -0,0 +1,148 @@
/* template.css */
/* allgemeine Vorgaben */
body {
font-family: "Open Sans", sans-serif;
font-size: 12pt;
padding: 0;
margin: 0;
}
/* Basislayout */
.clSiteHeader {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 100px;
line-height: 100px;
margin: 0;
padding: 5px;
font-size: 40pt;
text-align: center;
text-shadow:black 3px 2px;
font-family: cursive, fantasy;
color: #920B19;
background-color: #B6B6B7;
}
.clContent {
position: absolute;
top: 110px; /* height, padding, border, margin von idSiteHeader beachten */
left: 0;
right: 0;
bottom: 0;
margin: 0;
padding: 5px;
}
/* Elemente im Content-Bereich */
.clContentHeader {
position: absolute;
top: 20px;
left: 0;
right: 0;
height: 30px;
line-height: 30px;
margin: 0;
padding: 5px;
font-size: 18pt;
text-align: center;
}
.clContentArea {
position: absolute;
top: 80px; /* height, padding, border, margin von idContentHeader beachten */
left: 0;
right: 0;
bottom: 40px; /* height, padding, border, margin von idButtonArea beachten */
margin: 10px 0;
margin-left: 10px;
padding: 5px;
}
.clButtonArea {
position: absolute;
left: 0;
right: 0;
/*float: left; width: 10px:*/
bottom: 0;
height: 80px;
line-height: 80px;
margin: 0;
padding: 5px;
text-align: center;
background-color: #B6B6B7;
}
/* Links und Submit-Schalter im Buttonbereich gestalten */
.clButtonArea a, input[type="submit"] {
margin: 0 5px;
padding: 3px 6px;
font-size: 14pt;
text-decoration: none;
border: 2px solid;
color: black;
background-color: buttonface;
}
/* unterschiedliche Kennzeichnungen je nach Bedienung vermeiden */
.clButtonArea a:hover, a:visited, a:active {
color: black;
}
/* Gestaltung von Tabellen */
#idList {
table-layout: fixed;
width: auto;
border: 2px solid;
border-collapse: collapse;
margin:auto;
}
#idList th {
text-align: center;
padding-left: 5px;
background-color: #FFFFFF;
}
#idList th, #idList td {
padding: 3px;
border: 2px solid;
}
/* Gestaltung von Formularen */
/* das Formular nochmals zusätzlich gestalten */
#idForm .clContentArea {
width: 500px;
margin: auto;
}
.clFormRow {
position: relative; /* damit das Element in jedem Fall "positioniert" ist und damit als Bezugspunkt geeignet ist */
height: 30px;
margin-bottom: 10px;
}
.clFormRow label {
position: absolute;
top: 0;
left: 0;
width: 240px;
text-align: center;
}
.clFormRow input {
position: absolute;
top: 0;
left: 250px;
width: 250px;
}
/* EOF */