#!/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, TextField, FileField, SelectField,\ validators, 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') # 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('//upload/', methods=['GET', 'POST']) @app.route('//upload/', 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('//files//') 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('//modules/') @app.route('//modules/') 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()] 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()