From 4ea12c4b97fc7775ab5ae3cb4607f715b880aede Mon Sep 17 00:00:00 2001 From: Nico Geyso Date: Sun, 7 Dec 2014 18:09:58 +0100 Subject: Remove dependency of pygit2 instead use directory listings --- .gitignore | 7 +- app/__init__.py | 78 +++++++++++++++++ app/app.py | 164 ------------------------------------ app/backend.py | 34 ++++++++ app/exts.py | 4 + app/fit.py | 136 ------------------------------ app/forms.py | 41 +++++++++ app/main.py | 81 ++++++++++++++++++ app/static/images/bioinformatik.png | Bin 4976 -> 0 bytes app/static/images/informatik.png | Bin 562 -> 0 bytes app/static/images/mathematik.png | Bin 882 -> 0 bytes app/static/style_v3.css | 16 +--- app/templates/index.html | 2 +- app/templates/layout.html | 25 ++---- app/templates/module_list.html | 2 +- app/templates/module_show.html | 10 +-- app/templates/upload.html | 2 +- config.cfg.dist | 61 ++++++++++++++ manage.py | 14 +++ requirements.txt | 2 +- scripts/__init__.py | 0 settings.py.sample | 16 ---- 22 files changed, 336 insertions(+), 359 deletions(-) delete mode 100644 app/app.py create mode 100644 app/backend.py create mode 100644 app/exts.py delete mode 100644 app/fit.py create mode 100644 app/forms.py create mode 100644 app/main.py delete mode 100644 app/static/images/bioinformatik.png delete mode 100644 app/static/images/informatik.png delete mode 100644 app/static/images/mathematik.png create mode 100644 config.cfg.dist create mode 100644 manage.py create mode 100644 scripts/__init__.py delete mode 100644 settings.py.sample diff --git a/.gitignore b/.gitignore index 312b13e..31240db 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,9 @@ *.pyc -static/studies/*.git -static/studies/*.zip -static/studies/*.tar.gz +app/static/studies +app/static/studies +app/static/studies settings.py +config.cfg env log app.log diff --git a/app/__init__.py b/app/__init__.py index e69de29..6c6b08c 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- + +from flask import Flask, render_template, g +from .main import main +from .backend import Storage +import sys +reload(sys) +sys.setdefaultencoding('utf-8') + +def create_app(config=None): + """Creates the Flask app.""" + app = Flask(__name__) + + configure_app(app) + configure_error_handlers(app) + init_app(app) + + for blueprint in [main]: + app.register_blueprint(blueprint) + + return app + + +def configure_app(app): + app.config.from_pyfile('../config.cfg') + + # http://flask.pocoo.org/docs/0.10/errorhandling/ + if not app.debug: + import logging + from logging.handlers import RotatingFileHandler + file_handler = RotatingFileHandler(app.config['LOG_FILE_PATH']) + file_handler.setLevel(logging.WARNING) + file_handler.setFormatter(logging.Formatter( + '%(asctime)s %(levelname)s: %(message)s' + '[in %(pathname)s:%(lineno)d]')) + app.logger.addHandler(file_handler) + + +def init_app(app): + import os + @app.before_request + def init(): + g.studies = {} + for i, study in enumerate(app.config['STUDIES'].items()): + abbr = study[0] + g.studies[abbr] = Storage(os.path.join('app', 'static','studies', abbr)) + + modules = app.config['STUDIES'][study[0]] + # extend module list with git values + for module in g.studies[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)) + + +## 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)) + +def configure_error_handlers(app): + @app.route('/forbidden') + @app.errorhandler(400) + @app.errorhandler(403) + @app.errorhandler(404) + def errorhandler(e): + return render_template('error.html', error=e), e.code + diff --git a/app/app.py b/app/app.py deleted file mode 100644 index 474d0ee..0000000 --- a/app/app.py +++ /dev/null @@ -1,164 +0,0 @@ -#!/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('//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()] - 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() diff --git a/app/backend.py b/app/backend.py new file mode 100644 index 0000000..25a5506 --- /dev/null +++ b/app/backend.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +import os +import magic + +class Storage: + def __init__(self, root_path): + self.root = root_path + + def _join(self, *arg): + return os.path.join(self.root, *arg) + + def get_file(self, module, year, name): + with open(self._join(module, year, name), 'r') as f: + data = f.read() + mime = magic.Magic(mime=True) + mime_type = mime.from_buffer(data[:1024]) + return mime_type, data + + def get_modules(self): + return [o for o in os.listdir(self.root) if os.path.isdir(self._join(o))] + + def get_module(self, module): + for root, dirs, files in os.walk(self._join(module)): + if len(dirs) == 0: + splitted = root.split(os.path.sep) + if len(splitted) > 1: + year = splitted[-1] + module = splitted[-2] + if year.isdigit(): + yield((year, files))#, os.path.join(root,f)) + + def add_file(self, data, path): + pass diff --git a/app/exts.py b/app/exts.py new file mode 100644 index 0000000..7d42edc --- /dev/null +++ b/app/exts.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + +from flask.ext.sqlalchemy import SQLAlchemy +db = SQLAlchemy() diff --git a/app/fit.py b/app/fit.py deleted file mode 100644 index 6fbc13f..0000000 --- a/app/fit.py +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/python2 -# -*- coding: utf-8 -*- - -import os, time -import collections - -from pygit2 import init_repository, Signature, GIT_FILEMODE_TREE, GIT_FILEMODE_BLOB -from binascii import b2a_hex - - -class Fit: - def __init__(self, path): - self.repo = init_repository(path, True) - - - def get_file(self, oid): - """ Returns the actual data of a git object """ - return self.repo[oid].data - - - def get_modules(self): - """ returns a list of all modules """ - return [x[0] for x in self._list()] - - - def get_module(self, module): - """ gets all entries for a module grouped by years """ - years = self._list(module) - return [(year[0], self._list(os.path.join(module, year[0]))) for year in years] - - def add_file(self, data, path): - """ Inserts the given file in the git tree and commits the changes """ - try: - commit = self.repo.head.get_object() - parents = commit.parents - root = commit.tree.id - - except: - parents = [] - root = None - - - blob_oid = self.repo.create_blob(data) - tree = self._insert_node(blob_oid, path, root) - author = committer = Signature('Fit', 'Fit@fit.de', int(time.time()), 120) - - commit = self.repo.create_commit( - 'HEAD', - author, - committer, - 'added %s' % path, - tree, - [p.id for p in parents] - ) - - # save the actual head sha for dump git http protocol - # similiar to `git update-server-info` - 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(str(commit)).decode('ascii')) - - return b2a_hex(str(blob_oid)).decode('ascii') - - - def _insert_node(self, node_oid, path, root_oid): - """ Inserts a new Node in a Git Tree graph """ - if root_oid: - root = self.repo.TreeBuilder(root_oid) - current_node = self.repo[root_oid] - else: - root = self.repo.TreeBuilder() - current_node = self.repo[root.write()] - - # entire path - dir_path = path.split(os.sep)[:-1] - - # search for existing nodes in path - existing_builders = [(os.sep, root)] - for dir_entry in dir_path: - try: - new_oid = current_node[dir_entry].oid - current_node = self.repo[new_oid] - - existing_builders.append(( - dir_entry, self.repo.TreeBuilder(current_node) - )) - except KeyError: - break - - # directories to create - new_path = dir_path[len(existing_builders)-1:] - - # inserts blob object - filename = os.path.basename(path) - - if len(new_path) > 0: - builder = self.repo.TreeBuilder() - pre = filename - else: - last_dir = existing_builders.pop() - builder = last_dir[1] - pre = last_dir[0] - - builder.insert(filename, node_oid, GIT_FILEMODE_BLOB) - current_tree_oid = builder.write() - - # create new nodes bottom-up for our node - if len(new_path) > 0: - pre = new_path.pop(0) - for entry in reversed(new_path): - builder = self.repo.TreeBuilder() - builder.insert(entry, current_tree_oid, GIT_FILEMODE_TREE) - current_tree_oid = builder.write() - - # connect existing nodes with created nodes - for name, builder in reversed(existing_builders): - builder.insert(pre, current_tree_oid, GIT_FILEMODE_TREE) - current_tree_oid = builder.write() - pre = name - - return current_tree_oid - - - def _list(self, path=None): - """ Lists all entries for a given path """ - try: - tree = self.repo.head.get_object().tree - - if path: - for p in path.split('/'): - tree = self.repo[tree[p].id] - - return [(x.name, x.hex) for x in tree] - - except: - return [] diff --git a/app/forms.py b/app/forms.py new file mode 100644 index 0000000..e562df2 --- /dev/null +++ b/app/forms.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- + +from datetime import date +from flask import current_app +from flask.ext.wtf import Form +from wtforms import TextField, FileField, SelectField, validators +from wtforms.validators import ValidationError + +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, current_app.config['FORM_START_YEAR']-1, -1) + xrange(date.today().year, 2000, -1) + ] + ) + + def validate_exam(form, field): + exts = current_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 > current_app.config['MAX_CONTENT_LENGTH']: + raise ValidationError(u'Zu große Datei') + + def validate_module(form, field): + modules = dict(current_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!') + + diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..cdc8d0b --- /dev/null +++ b/app/main.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- + +import os, sys +from flask import Blueprint, render_template, request, flash, redirect,\ + url_for, current_app, g +from werkzeug import secure_filename +from .forms import UploadForm + +main = Blueprint('main', __name__) + +@main.route('//upload/', methods=['GET', 'POST']) +@main.route('//upload/', methods=['GET', 'POST']) +def upload(study, module = None): + form = UploadForm() + form.study.data = study + + form.module.choices = current_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(current_app.config['STUDIES'][study]) - 2 + current_app.config['STUDIES'][study].insert(i, (slug,module)) + else: + module = dict(current_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 = g.studies[study].add_file(form.exam.data.stream.getvalue(), path) + except: + oid = g.studies[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) + + + +@main.route('//files///') +def study_show(study, module, year, filename): + mime_type, data = g.studies[study].get_file(module,year,filename) + header = { 'Content-Type' : mime_type } + return data, 200, header + + +@main.route('//modules/') +@main.route('//modules/') +def study_index(study, module=None): + if module: + entries = sorted(g.studies[study].get_module(module), reverse=True) + return render_template('module_show.html', + study = study, module=module, entries=entries + ) + + modules = g.studies[study].get_modules() + return render_template('module_list.html', study = study, modules=modules) + + +@main.route('/') +def index(): + get_img_path = lambda x: os.path.join('studies', x, 'logo.png') + studies = [(name,get_img_path(name)) for name,m in current_app.config['STUDIES'].items()] + + return render_template( + 'index.html', + studies = studies + ) diff --git a/app/static/images/bioinformatik.png b/app/static/images/bioinformatik.png deleted file mode 100644 index 0c7e740..0000000 Binary files a/app/static/images/bioinformatik.png and /dev/null differ diff --git a/app/static/images/informatik.png b/app/static/images/informatik.png deleted file mode 100644 index 8c31df8..0000000 Binary files a/app/static/images/informatik.png and /dev/null differ diff --git a/app/static/images/mathematik.png b/app/static/images/mathematik.png deleted file mode 100644 index 1dd6baf..0000000 Binary files a/app/static/images/mathematik.png and /dev/null differ diff --git a/app/static/style_v3.css b/app/static/style_v3.css index 3b9bee3..6907658 100644 --- a/app/static/style_v3.css +++ b/app/static/style_v3.css @@ -25,6 +25,8 @@ body { width: 100%; } + + footer { clear: both; margin: 0px auto; @@ -53,20 +55,10 @@ footer a, footer a:visited { #header h1 { display: inline-block; - float: left; - width: 50%; + width: 100%; + text-align: center; margin: 0px; } -#header p { - display: inline-block; - font-family: monospace; - text-align: right; - line-height: 180%; - padding: 5px; - margin: 0; - float: right; - width: 30%; -} #header h1 small { color: #777; diff --git a/app/templates/index.html b/app/templates/index.html index 14b7fde..9d090c3 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -6,7 +6,7 @@
    {% for name,img_path in studies|sort %}
  • - + {{name}} {{name.capitalize()}} diff --git a/app/templates/layout.html b/app/templates/layout.html index 4de48c8..06901e9 100644 --- a/app/templates/layout.html +++ b/app/templates/layout.html @@ -9,16 +9,7 @@
    @@ -26,15 +17,15 @@
    {% if study %}

    - {% if not request.base_url.endswith(url_for('upload', study=study, module = module))%} - {% if not request.base_url.endswith(url_for('forbidden')) %} - neue Klausur hochladen + {% if not request.base_url.endswith(url_for('.upload', study=study, module = module))%} + {% if not request.base_url.endswith(url_for('errorhandler')) %} + neue Klausur hochladen {% endif %} {% else %} - zurück + zurück {% endif %}

    -

    {{study.capitalize()}}

    +

    {{study.capitalize()}}

    {% endif %}
      @@ -51,11 +42,7 @@
    diff --git a/app/templates/module_list.html b/app/templates/module_list.html index 2b36f30..9e1409c 100644 --- a/app/templates/module_list.html +++ b/app/templates/module_list.html @@ -5,7 +5,7 @@
      {% for module in modules %}
    • - {{module}} + {{module}}
    • {% else %}
    • Keine Klausuren bisher hochgeladen!
    • diff --git a/app/templates/module_show.html b/app/templates/module_show.html index cbaec74..e31da24 100644 --- a/app/templates/module_show.html +++ b/app/templates/module_show.html @@ -1,12 +1,12 @@ -{% macro render_module_list(module) %} +{% macro render_module_list(module, entries) %}
        -{% for year,files in module %} +{% for year,files in entries %}
      • {{year}}
          - {% for name,oid in files %} + {% for name in files %}
        • - + {{name|truncate(40,True)}}
        • @@ -24,7 +24,7 @@

          {{module}}

          - {{ render_module_list(entries)}} + {{ render_module_list(module, entries)}}
          {% endblock %} diff --git a/app/templates/upload.html b/app/templates/upload.html index 8683be0..67c47ea 100644 --- a/app/templates/upload.html +++ b/app/templates/upload.html @@ -26,7 +26,7 @@
          + action="{{url_for('main.upload', study=study, module=module)}}"> {{ form.csrf_token }} {{ render_field(form.exam) }} diff --git a/config.cfg.dist b/config.cfg.dist new file mode 100644 index 0000000..ce3ac18 --- /dev/null +++ b/config.cfg.dist @@ -0,0 +1,61 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +SECRET_KEY = 'secret_key_to_fill_in' +MAX_CONTENT_LENGTH = 10 * 1024 * 1024 +DEBUG = False +LOG_FILE_PATH = 'app.log' + +FORM_START_YEAR = 2000 +ALLOWED_EXTENSIONS = ['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'zip', 'gs', +'gz', 'html' ] + +STUDIES = { + 'informatik' : [ + ('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') ], + 'bioinformatik' : [ + ('info_a', u'Informatik A'), + ('info_b', u'Informatik B'), + ('alp', u'Algorithmen und Datenstrukturen'), + ('albio', u'Algorithmische Bioinformatik'), + ('lina', u'Mathematik I (Lineare Algebra)'), + ('ana', u'Mathematik II (Analysis)'), + ('coma1', u'Computerorientierte Mathematik 1'), + ('coma2', u'Computerorientierte Mathematik 2'), + ('bio_stat1', u'Statistik für Biowissenschaften 1'), + ('bio_stat2', u'Statistik für Biowissenschaften 2'), + ('allg_chemie', u'Allgemeine Chemie'), + ('molbio1', u'Molekularbiologie und Biochemie 1'), + ('molbio2', u'Molekularbiologie und Biochemie 2'), + ('molbio3', u'Molekularbiologie und Biochemie 3'), + ('genetik', u'Genetik'), + ('physio1', u'Physiologie 1'), + ('physio2', u'Physiologie 2'), + ('dbs', u'Datenbanksysteme') + ], + 'mathematik' : [ + ('ana1', u'Analysis 1'), + ('ana2', u'Analysis 2'), + ('ana3', u'Analysis 3'), + ('coma1', u'Computerorientierte Mathematik 1'), + ('coma2', u'Computerorientierte Mathematik 2'), + ('lina1', u'Lineare Algebra 1'), + ('lina2', u'Lineare Algebra 2'), + ('stochastik1', u'Stochastik 1'), + ('numerik1', u'Numerik 1') + ] +} diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..452423a --- /dev/null +++ b/manage.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- + +from flask.ext.script import Manager +from app import create_app + +# create app +app = create_app() +manager = Manager(app) + +# import scripts +from scripts import * + +if __name__ == '__main__': + manager.run() diff --git a/requirements.txt b/requirements.txt index 5a514e1..c634f9b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ Flask Flask-WTF +flask-script Jinja2 WTForms Werkzeug -pygit2 python-magic wsgiref diff --git a/scripts/__init__.py b/scripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/settings.py.sample b/settings.py.sample deleted file mode 100644 index 7d1f208..0000000 --- a/settings.py.sample +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -SECRET_KEY = 'secret_key_to_fill_in' -MAX_CONTENT_LENGTH = 10 * 1024 * 1024 -DEBUG = False -LOG_FILE_PATH = 'app.log' - -FORM_START_YEAR = 2000 -ALLOWED_EXTENSIONS = ['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'zip', 'gs', 'gz' ] - -STUDIES = { - 'informatik' : [ - ('alp1', u'ALP1 - Funktionale Programmierung'), - ] -} -- cgit v1.2.3-1-g7c22