diff options
author | Nico von Geyso <Nico.Geyso@FU-Berlin.de> | 2012-08-13 17:37:18 +0200 |
---|---|---|
committer | Nico von Geyso <Nico.Geyso@FU-Berlin.de> | 2012-08-13 17:51:54 +0200 |
commit | ed9f2a99351349fa8d12868fe5dd27de6e70e8ad (patch) | |
tree | cdb4ca72134a5a16b6699f2ab929c26aeeaeabd6 | |
parent | cc675a681431369a5230ed7a8394d4dee10a3c61 (diff) | |
download | klausuren-ed9f2a99351349fa8d12868fe5dd27de6e70e8ad.tar.gz klausuren-ed9f2a99351349fa8d12868fe5dd27de6e70e8ad.tar.bz2 klausuren-ed9f2a99351349fa8d12868fe5dd27de6e70e8ad.zip |
several studies like Informatik, Bioinformatik and Mathemathik are now possible
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | app.py | 119 | ||||
-rw-r--r-- | fit.py | 3 | ||||
-rw-r--r-- | munin.py | 15 | ||||
-rw-r--r-- | static/images/bioinformatik.png | bin | 0 -> 4976 bytes | |||
-rw-r--r-- | static/images/informatik.png | bin | 0 -> 562 bytes | |||
-rw-r--r-- | static/images/mathematik.png | bin | 0 -> 882 bytes | |||
-rw-r--r-- | static/style.css | 43 | ||||
-rw-r--r-- | templates/index.html | 20 | ||||
-rw-r--r-- | templates/layout.html | 16 | ||||
-rw-r--r-- | templates/module_list.html | 4 | ||||
-rw-r--r-- | templates/module_show.html | 6 | ||||
-rw-r--r-- | templates/upload.html | 5 |
13 files changed, 152 insertions, 83 deletions
@@ -1,3 +1,5 @@ *.pyc -static/fit.git +static/studies/*.git +static/studies/*.zip +static/studies/*.tar.gz settings.py @@ -1,62 +1,50 @@ #!/usr/bin/python2 # -*- coding: utf-8 -*- + import magic, os from fit import Fit -from flask import Flask, render_template, request, flash, redirect, \ - url_for,jsonify +from flask import Flask, render_template, request, flash, redirect, url_for from flask.ext.wtf import Form, TextField, FileField, SelectField,\ validators, ValidationError from werkzeug import secure_filename from datetime import date -fit = Fit('static/fit.git') - app = Flask(__name__) -app.config.from_object('settings') - -ALLOWED_EXTENSIONS = ['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'zip', 'gs', 'gz' ] - -FORM_MODULE_LIST= [ - ('alp1', u'ALP1 - Funktionale Programmierung'), - ('alp2', u'ALP2 - Objektorientierte Programmierung'), - ('alp3', u'ALP3 - Datenstrukturen'), - ('alp4', u'ALP4 - Nichtsequentielle Programmierung'), - ('alp5', u'ALP5 - Netzprogrammierung'), - ('ti1', u'TI1 - Grundlagen der Technischen Informatik'), - ('ti2', u'TI2 - Rechnerarchitektur'), - ('ti3', u'TI3 - Betriebs- und Kommunikationssysteme'), - ('mafi1', u'MafI1 - Logik und Diskrete Mathematik'), - ('mafi2', u'MafI2 - Analysis'), - ('mafi3', u'MafI3 - Lineare Algebra'), - ('gti', u'Grundlagen der Theoretischen Informatik'), - ('dbs', u'Datenbanksysteme'), - ('swt', u'Softwaretechnik'), - ('aws', u'Anwendungssysteme'), - ('', u'---'), - ('new', u'neues Modul hinzufügen') -] - -TERM_START_YEAR = 1999 -YEARS = [(str(x),x) for x in xrange(date.today().year, TERM_START_YEAR, -1)] - - +app.config.from_pyfile('settings.py') + +# populate Module-List +fit = {} +for i, study in enumerate(app.config['MODULES'].items()): + abbr = study[0] + fit[abbr] = Fit(os.path.join('static','studies',abbr + '.git')) + + modules = app.config['MODULES'][study[0]] + # extend module list with git values + for module in fit[abbr].get_modules(): + # check if module is already listed + if all(map(lambda (k,v): v != module, modules)): + slug = module.encode('ascii', errors='ignore') + app.config['MODULES'][study[0]].append((slug, module)) class UploadForm(Form): """ Upload Form class for validation """ + study = TextField('Studiengang') exam = FileField('Klausur') - module = SelectField('Kurs', choices = FORM_MODULE_LIST) + module = SelectField('Kurs') module_new = TextField('Modulname', validators=[validators.Optional(), validators.Length(min=5)]) year = SelectField( 'Jahr', validators=[validators.Required()], - choices = YEARS + choices = [(str(x),x) for x in xrange(date.today().year, app.config['FORM_START_YEAR'], -1)] ) def validate_exam(form, field): - ext = map(lambda x: field.data.filename.endswith(x), ALLOWED_EXTENSIONS) + exts = app.config['ALLOWED_EXTENSIONS'] + ext = map(lambda x: field.data.filename.endswith(x), exts) + if not any(ext): raise ValidationError(u'Ungültiger Dateityp') @@ -64,8 +52,10 @@ class UploadForm(Form): raise ValidationError(u'Zu große Datei') def validate_module(form, field): - modules = dict(FORM_MODULE_LIST) + modules = dict(app.config['MODULES'][form.study.data]) data = form.module.data + print(data) + print(modules) if data not in modules or data == '': raise ValidationError(u'Bitte wähle ein Modul!') @@ -73,56 +63,71 @@ class UploadForm(Form): -@app.route('/upload', methods=['GET', 'POST']) -def upload(): +@app.route('/<study>/upload', methods=['GET', 'POST']) +def upload(study): form = UploadForm() + form.study.data = study + + form.module.choices = app.config['MODULES'][study] + if 'new' not in dict(form.module.choices): + if len(form.module.choices) > 0: + form.module.choices.append(('', u'---')) + form.module.choices.append(('new', u'neues Modul hinzufügen')) + if form.validate_on_submit(): if form.module.data == 'new': module = form.module_new.data slug = module.encode('ascii', errors='ignore') - FORM_MODULE_LIST.append((slug,module)) + app.config['MODULES'][study].append((slug,module)) else: - module = dict(FORM_MODULE_LIST)[form.module.data] + module = dict(app.config['MODULES'][study])[form.module.data] year = form.year.data filename = secure_filename(form.exam.data.filename) path = os.path.join(module,year,filename).encode('ascii', errors='ignore') try: - oid = fit.add_file(form.exam.data.stream.getvalue(), path) + oid = fit[study].add_file(form.exam.data.stream.getvalue(), path) except: - oid = fit.add_file(form.exam.data.stream.read(), path) + oid = fit[study].add_file(form.exam.data.stream.read(), path) flash("Datei %s gespeichert." % filename) - return redirect(url_for('index', module = module)) + return redirect(url_for('study_index', study = study, module = module)) - return render_template('upload.html', form = form) + return render_template('upload.html', study = study, form = form) -@app.route('/files/<oid>') -def show(oid): - data = fit.get_file(oid) +@app.route('/<study>/files/<oid>') +def study_show(study, oid): + data = fit[study].get_file(oid) mime = magic.Magic(mime=True) header = { 'Content-Type' : mime.from_buffer(data[:1024]) } return data, 200, header -@app.route('/') -@app.route('/modules') -@app.route('/modules/<module>') -def index(module=None): +@app.route('/<study>/modules') +@app.route('/<study>/modules/<module>') +def study_index(study, module=None): if module: return render_template( - 'module_show.html', module=module, entries=fit.get_module(module) + 'module_show.html', study = study, module=module, entries=fit[study].get_module(module) ) - return render_template('module_list.html', modules=fit.get_modules()) + return render_template('module_list.html', study = study, modules=fit[study].get_modules()) +@app.route('/') +def index(): + get_img_path = lambda x: os.path.join('images', x +'.png') + studies = [(name,get_img_path(name)) for name,m in app.config['MODULES'].items()] + return render_template( + 'index.html', + studies = studies + ) @app.route('/403') @app.errorhandler(403) @@ -132,12 +137,4 @@ def forbidden(): if __name__ == "__main__": - modules = dict(FORM_MODULE_LIST) - # extend module list with git values - for module in fit.get_modules(): - # check if module is already listed - if all(map(lambda (k,v): v != module, modules.items())): - slug = module.encode('ascii', errors='ignore') - FORM_MODULE_LIST.insert(len(FORM_MODULE_LIST) - 2, (slug, module)) - app.run() @@ -98,7 +98,8 @@ class Fit: parents ) - with open('static/fit.git/info/refs', 'w') as f: + info_refs_path = os.path.join(self.repo.path, 'info', 'refs') + with open(info_refs_path, 'w') as f: f.write('%s\trefs/heads/master\n' % b2a_hex(commit).decode('ascii')) return b2a_hex(blob_oid).decode('ascii') @@ -1,5 +1,5 @@ import sys -from fit import Fit +from app import fit def select_entries(module_list): @@ -7,12 +7,15 @@ def select_entries(module_list): if __name__ == "__main__": - fit = Fit('static/fit.git') - entries = map(lambda x: select_entries(fit.get_module(x)), fit.get_modules()) + entries = {} + for name, instance in fit.items(): + entries[name] = map(lambda x: select_entries(instance.get_module(x)), instance.get_modules()) if len(sys.argv) > 1 and sys.argv[1] == 'config': - print 'graph_title Fit' + print 'graph_title Klausuren' print 'graph_vlabel Amount' - print 'exams.label Klausuren' + for label in fit.keys(): + print '%s.label %s' % (label, label.capitalize()) else: - print 'exams.value',sum(map(lambda x: len(x), entries)) + for label, value in entries.items(): + print '%s.value %s' %(label, sum(map(lambda x: len(x), value))) diff --git a/static/images/bioinformatik.png b/static/images/bioinformatik.png Binary files differnew file mode 100644 index 0000000..0c7e740 --- /dev/null +++ b/static/images/bioinformatik.png diff --git a/static/images/informatik.png b/static/images/informatik.png Binary files differnew file mode 100644 index 0000000..8c31df8 --- /dev/null +++ b/static/images/informatik.png diff --git a/static/images/mathematik.png b/static/images/mathematik.png Binary files differnew file mode 100644 index 0000000..1dd6baf --- /dev/null +++ b/static/images/mathematik.png diff --git a/static/style.css b/static/style.css index a46689e..35063ad 100644 --- a/static/style.css +++ b/static/style.css @@ -20,9 +20,9 @@ body { #header { background-color: #fff; - clear: both; - height: 80px; margin: 0px auto 10px auto; + float: left; + width: 100%; } footer { @@ -51,17 +51,20 @@ footer a, footer a:visited { } #header h1 { + display: inline-block; float: left; width: 50%; margin: 0px; } #header p { + display: inline-block; font-family: monospace; text-align: right; line-height: 180%; - height: 80px; padding: 5px; margin: 0; + float: right; + width: 30%; } #header h1 small { @@ -139,3 +142,37 @@ select { border: 1px solid #ccc; } +#studies { + margin: auto; + text-align: center; + padding: 40px 0px 60px 0px; +} + +#studies ul { + display: inline-block; +} + +#studies li { + float: left; + list-style-type: none; + text-align: center; + width: 200px; +} + +#studies li a { + margin: 0px 20px; + padding: 10px; + border: 1px solid #ccc; + display: block; +} + +#studies li a:hover { + background-color: #ccc; + border: 1px solid #000; +} + +#studies li img{ + display: block; + margin: 0px auto; +} + diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..14b7fde --- /dev/null +++ b/templates/index.html @@ -0,0 +1,20 @@ +{% extends "layout.html" %} +{% block body %} + <h2>Studiengänge</h2> + + <div id="studies"> + <ul id="studies"> + {% for name,img_path in studies|sort %} + <li> + <a href="{{url_for('study_index', study=name)}}"> + <img src="{{url_for('static',filename=img_path)}}" alt="{{name}}" /> + {{name.capitalize()}} + </a> + </li> + {% else %} + <li>Keine Studiengänge konfiguriert!</li> + {% endfor %} + </ul> + </div> + +{% endblock %} diff --git a/templates/layout.html b/templates/layout.html index 19d0e6f..28eaa80 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -9,24 +9,32 @@ <body> <div id="header"> <h1><a href="/">Archiv</a><small> @ spline</small></h1> + {% if study %} <p> - <b>Tip</b>: Du kannst alle Klausuren mittels Git herunterladen.<br /> - <i>git clone {{url_for('static', filename='fit.git', _external=True)}}</i> + <b>Tip</b>: Du kannst alle Klausuren auch als + {% set path = 'studies/' + study %} + <a href="{{url_for('static', filename=path + '.zip')}}">ZIP</a>- oder + <a href="{{url_for('static', filename=path + '.tar.gz')}}">TAR-GZ</a>-Archiv, sowie via + <a href="{{url_for('static', filename=path + '.git')}}">git</a> herunterladen </p> + {% endif %} </div> <div id="content"> <div id="sub-header"> + {% if study %} <p> - {% if not request.base_url.endswith(url_for('upload')) %} + {% if not request.base_url.endswith(url_for('upload', study=study)) %} {% if not request.base_url.endswith(url_for('forbidden')) %} - <a href="{{url_for('upload')}}">neue Klausur hochladen</a> + <a href="{{url_for('upload', study=study)}}">neue Klausur hochladen</a> {% endif %} {% else %} <a href="{{url_for('index')}}">zurück</a> {% endif %} </p> + <h2>{{study.capitalize()}}</h2> + {% endif %} <ul class="flashes"> {% with messages = get_flashed_messages() %} diff --git a/templates/module_list.html b/templates/module_list.html index 493a66f..2b36f30 100644 --- a/templates/module_list.html +++ b/templates/module_list.html @@ -1,11 +1,11 @@ {% extends "layout.html" %} {% block body %} - <h2>Klausuren</h2> + <h3>Klausuren</h3> <ul> {% for module in modules %} <li> - <a href="{{url_for('index', module=module)}}">{{module}}</a> + <a href="{{url_for('study_index', study = study, module=module)}}">{{module}}</a> </li> {% else %} <li>Keine Klausuren bisher hochgeladen!</li> diff --git a/templates/module_show.html b/templates/module_show.html index 5029859..8b2dda1 100644 --- a/templates/module_show.html +++ b/templates/module_show.html @@ -1,9 +1,9 @@ {% extends "layout.html" %} {% block body %} - <h2>{{module}}</h2> + <h3>{{module}}</h3> <p> - <a href="{{url_for('index')}}">zurück zur Übersicht</a> + <a href="{{url_for('study_index', study=study)}}">zurück zur Übersicht</a> </p> <ul> @@ -13,7 +13,7 @@ <ul> {% for name,oid in files %} <li> - <a href="{{url_for('show', oid=oid)}}">{{name}}</a> + <a href="{{url_for('study_show', study = study, oid=oid)}}">{{name}}</a> </li> {% endfor %} </ul> diff --git a/templates/upload.html b/templates/upload.html index 2032323..dec17c8 100644 --- a/templates/upload.html +++ b/templates/upload.html @@ -1,6 +1,6 @@ {% extends "layout.html" %} {% block body %} - <h2>neue Klausur hochladen</h2> + <h3>neue Klausur hochladen</h3> {% macro render_fields(field, extra_field) %} <p> @@ -40,7 +40,8 @@ }); }); </script> - <form method="POST" enctype="multipart/form-data" action="/upload"> + <form method="POST" enctype="multipart/form-data" + action="{{url_for('upload', study=study)}}"> {{ form.csrf_token }} {{ render_field(form.exam) }} |