summaryrefslogtreecommitdiffstats
path: root/app/app.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/app.py')
-rw-r--r--app/app.py164
1 files changed, 164 insertions, 0 deletions
diff --git a/app/app.py b/app/app.py
new file mode 100644
index 0000000..474d0ee
--- /dev/null
+++ b/app/app.py
@@ -0,0 +1,164 @@
+#!/usr/bin/python2
+# -*- coding: utf-8 -*-
+
+import magic, os, sys
+
+from fit import Fit
+from flask import Flask, render_template, request, flash, redirect, url_for
+from flask.ext.wtf import Form
+from wtforms import TextField, FileField, SelectField, validators
+from wtforms.validators import ValidationError
+
+from werkzeug import secure_filename
+from datetime import date
+
+
+# set default encoding to utf-8, otherwise pygit2 can not handle umlauts
+reload(sys)
+sys.setdefaultencoding('utf-8')
+
+app = Flask(__name__)
+app.config.from_pyfile('settings.py')
+
+if not app.debug:
+ import logging
+ from logging.handlers import RotatingFileHandler
+ file_handler = RotatingFileHandler(app.config['LOG_FILE_PATH'])
+ file_handler.setLevel(logging.WARNING)
+ app.logger.addHandler(file_handler)
+
+# populate Module-List
+fit = {}
+for i, study in enumerate(app.config['STUDIES'].items()):
+ abbr = study[0]
+ fit[abbr] = Fit(os.path.join('static','studies',abbr + '.git'))
+
+ modules = app.config['STUDIES'][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.decode('ascii', errors='ignore')
+ app.config['STUDIES'][study[0]].append((slug, module))
+
+class UploadForm(Form):
+ """ Upload Form class for validation """
+ study = TextField('Studiengang')
+ exam = FileField('Klausur')
+ module = SelectField('Kurs')
+ module_new = TextField('Modulname', validators=[validators.Optional(),
+ validators.Length(min=5)])
+ year = SelectField(
+ 'Jahr',
+ validators=[validators.Required()],
+ choices = [ (str(x),x) for x in
+ xrange(date.today().year, app.config['FORM_START_YEAR']-1, -1)
+ ]
+ )
+
+ def validate_exam(form, field):
+ exts = app.config['ALLOWED_EXTENSIONS']
+ ext = map(field.data.filename.endswith, exts)
+
+ if not any(ext):
+ raise ValidationError(u'Ungültiger Dateityp')
+
+ if field.data.content_length > app.config['MAX_CONTENT_LENGTH']:
+ raise ValidationError(u'Zu große Datei')
+
+ def validate_module(form, field):
+ modules = dict(app.config['STUDIES'][form.study.data])
+ data = form.module.data
+ if data not in modules or data == '':
+ raise ValidationError(u'Bitte wähle ein Modul!')
+
+
+
+
+@app.route('/<study>/upload/', methods=['GET', 'POST'])
+@app.route('/<study>/upload/<module>', methods=['GET', 'POST'])
+def upload(study, module = None):
+ form = UploadForm()
+ form.study.data = study
+
+ form.module.choices = app.config['STUDIES'][study]
+ if 'new' not in dict(form.module.choices):
+ 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')
+ i = len(app.config['STUDIES'][study]) - 2
+ app.config['STUDIES'][study].insert(i, (slug,module))
+ else:
+ module = dict(app.config['STUDIES'][study])[form.module.data]
+
+ year = form.year.data
+ filename = secure_filename(form.exam.data.filename)
+ path = os.path.join(module,year,filename)
+
+ try:
+ oid = fit[study].add_file(form.exam.data.stream.getvalue(), path)
+ except:
+ oid = fit[study].add_file(form.exam.data.stream.read(), path)
+
+ flash("Datei %s gespeichert." % filename)
+
+ return redirect(url_for('study_index', study = study, module = module))
+
+ try: form.module.data = [k for (k,v) in form.module.choices if v == module][0]
+ except: pass
+
+ return render_template('upload.html',
+ study = study, form = form, module=module)
+
+
+
+@app.route('/<study>/files/<oid>/<filename>')
+def study_show(study, oid, filename):
+ 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('/<study>/modules/')
+@app.route('/<study>/modules/<module>')
+def study_index(study, module=None):
+ if module:
+ entries = sorted(fit[study].get_module(module), reverse=True)
+ return render_template('module_show.html',
+ study = study, module=module, entries=entries
+ )
+
+ modules = fit[study].get_modules()
+ return render_template('module_list.html', study = study, modules=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['STUDIES'].items()]
+ print(fit)
+
+ return render_template(
+ 'index.html',
+ studies = studies
+ )
+
+
+
+@app.route('/403')
+@app.errorhandler(403)
+def forbidden():
+ return render_template('403.html')
+
+
+
+if __name__ == "__main__":
+ app.run()