summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNico Geyso <nico.geyso@fu-berlin.de>2014-12-07 18:09:58 +0100
committerNico Geyso <nico.geyso@fu-berlin.de>2014-12-07 18:09:58 +0100
commit4ea12c4b97fc7775ab5ae3cb4607f715b880aede (patch)
treebdb798ffd244bee68b62d70da068ca795da766e6
parentab487c574b6ac405a869528516bed55473e93c5f (diff)
downloadklausuren-4ea12c4b97fc7775ab5ae3cb4607f715b880aede.tar.gz
klausuren-4ea12c4b97fc7775ab5ae3cb4607f715b880aede.tar.bz2
klausuren-4ea12c4b97fc7775ab5ae3cb4607f715b880aede.zip
Remove dependency of pygit2 instead use directory listings
-rw-r--r--.gitignore7
-rw-r--r--app/__init__.py78
-rw-r--r--app/app.py164
-rw-r--r--app/backend.py34
-rw-r--r--app/exts.py4
-rw-r--r--app/fit.py136
-rw-r--r--app/forms.py41
-rw-r--r--app/main.py81
-rw-r--r--app/static/images/bioinformatik.pngbin4976 -> 0 bytes
-rw-r--r--app/static/images/informatik.pngbin562 -> 0 bytes
-rw-r--r--app/static/images/mathematik.pngbin882 -> 0 bytes
-rw-r--r--app/static/style_v3.css16
-rw-r--r--app/templates/index.html2
-rw-r--r--app/templates/layout.html25
-rw-r--r--app/templates/module_list.html2
-rw-r--r--app/templates/module_show.html10
-rw-r--r--app/templates/upload.html2
-rw-r--r--config.cfg.dist61
-rw-r--r--manage.py14
-rw-r--r--requirements.txt2
-rw-r--r--scripts/__init__.py0
-rw-r--r--settings.py.sample16
22 files changed, 336 insertions, 359 deletions
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('/<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()
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('/<study>/upload/', methods=['GET', 'POST'])
+@main.route('/<study>/upload/<module>', 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('/<study>/files/<module>/<year>/<filename>')
+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('/<study>/modules/')
+@main.route('/<study>/modules/<module>')
+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
--- a/app/static/images/bioinformatik.png
+++ /dev/null
Binary files differ
diff --git a/app/static/images/informatik.png b/app/static/images/informatik.png
deleted file mode 100644
index 8c31df8..0000000
--- a/app/static/images/informatik.png
+++ /dev/null
Binary files differ
diff --git a/app/static/images/mathematik.png b/app/static/images/mathematik.png
deleted file mode 100644
index 1dd6baf..0000000
--- a/app/static/images/mathematik.png
+++ /dev/null
Binary files 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 @@
<ul id="studies">
{% for name,img_path in studies|sort %}
<li>
- <a href="{{url_for('study_index', study=name)}}">
+ <a href="{{url_for('main.study_index', study=name)}}">
<img src="{{url_for('static',filename=img_path)}}" alt="{{name}}" />
{{name.capitalize()}}
</a>
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 @@
</head>
<body>
<div id="header">
- <h1><a href="/">Archiv</a><small> @ spline</small></h1>
- {% if study %}
- <p>
- <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 %}
+ <h1><a href="/">Klausurenarchiv</a><small> @ spline</small></h1>
</div>
<div id="content">
@@ -26,15 +17,15 @@
<div id="sub-header">
{% if study %}
<p>
- {% if not request.base_url.endswith(url_for('upload', study=study, module = module))%}
- {% if not request.base_url.endswith(url_for('forbidden')) %}
- <a href="{{url_for('upload', study=study, module=module)}}">neue Klausur hochladen</a>
+ {% if not request.base_url.endswith(url_for('.upload', study=study, module = module))%}
+ {% if not request.base_url.endswith(url_for('errorhandler')) %}
+ <a href="{{url_for('main.upload', study=study, module=module)}}">neue Klausur hochladen</a>
{% endif %}
{% else %}
- <a href="{{url_for('study_index', study=study, module=module)}}">zurück</a>
+ <a href="{{url_for('main.study_index', study=study, module=module)}}">zurück</a>
{% endif %}
</p>
- <h2><a href="{{url_for('study_index', study=study)}}">{{study.capitalize()}}</a></h2>
+ <h2><a href="{{url_for('main.study_index', study=study)}}">{{study.capitalize()}}</a></h2>
{% endif %}
<ul class="flashes">
@@ -51,11 +42,7 @@
</div>
<footer>
- <a href="https://github.com/libgit2/libgit2">libgit2</a>
- |
<a href="https://gitlab.spline.inf.fu-berlin.de/cholin/klausuren">source</a>
- |
- <a href="https://github.com/libgit2/pygit2">pygit2</a>
</footer>
</body>
</html>
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 @@
<ul>
{% for module in modules %}
<li>
- <a href="{{url_for('study_index', study = study, module=module)}}">{{module}}</a>
+ <a href="{{url_for('main.study_index', study = study, module=module)}}">{{module}}</a>
</li>
{% else %}
<li>Keine Klausuren bisher hochgeladen!</li>
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) %}
<ul id="module-list">
-{% for year,files in module %}
+{% for year,files in entries %}
<li>
{{year}}
<ul>
- {% for name,oid in files %}
+ {% for name in files %}
<li>
- <a href="{{url_for('study_show', study = study, oid=oid, filename=name)}}">
+ <a href="{{url_for('.study_show', study = study, module=module, year=year, filename=name)}}">
{{name|truncate(40,True)}}
</a>
</li>
@@ -24,7 +24,7 @@
<div id="module-index">
<h3>{{module}}</h3>
- {{ render_module_list(entries)}}
+ {{ render_module_list(module, entries)}}
</div>
{% 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 @@
<div id="upload">
<form method="POST" enctype="multipart/form-data"
- action="{{url_for('upload', study=study, module=module)}}">
+ 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
--- /dev/null
+++ b/scripts/__init__.py
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'),
- ]
-}