diff options
| author | Gertjan van den Burg <gertjanvandenburg@gmail.com> | 2019-03-18 18:30:21 +0000 |
|---|---|---|
| committer | Gertjan van den Burg <gertjanvandenburg@gmail.com> | 2019-03-18 18:30:21 +0000 |
| commit | bff5795ed10c923f0e26781ed53ff04fd2284923 (patch) | |
| tree | 487bb1d33fafbfe052e6f6eb44459c9b8af5afea | |
| parent | Add command line interface for admin tasks (diff) | |
| download | AnnotateChange-bff5795ed10c923f0e26781ed53ff04fd2284923.tar.gz AnnotateChange-bff5795ed10c923f0e26781ed53ff04fd2284923.zip | |
Start work on admin panel
| -rw-r--r-- | annotate_change_v2.py | 3 | ||||
| -rw-r--r-- | app/__init__.py | 8 | ||||
| -rw-r--r-- | app/admin/__init__.py | 7 | ||||
| -rw-r--r-- | app/admin/decorators.py | 21 | ||||
| -rw-r--r-- | app/admin/forms.py | 12 | ||||
| -rw-r--r-- | app/admin/routes.py | 42 | ||||
| -rw-r--r-- | app/templates/admin/assign.html | 34 | ||||
| -rw-r--r-- | app/templates/base.html | 3 |
8 files changed, 128 insertions, 2 deletions
diff --git a/annotate_change_v2.py b/annotate_change_v2.py index 65959cb..0aa4765 100644 --- a/annotate_change_v2.py +++ b/annotate_change_v2.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- -from app import create_app, db +from app import create_app, db, cli app = create_app() +cli.register(app) diff --git a/app/__init__.py b/app/__init__.py index 9908dd8..7bad100 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -14,7 +14,7 @@ from flask_mail import Mail from flask_migrate import Migrate from flask_sqlalchemy import SQLAlchemy -from .config import Config +from config import Config db = SQLAlchemy() migrate = Migrate() @@ -28,12 +28,14 @@ def create_app(config_class=Config): app = Flask(__name__) app.config.from_object(config_class) + # Initialize all extensions db.init_app(app) migrate.init_app(app, db) login.init_app(app) mail.init_app(app) bootstrap.init_app(app) + # Register all the blueprints from app.errors import bp as errors_bp app.register_blueprint(errors_bp) @@ -46,6 +48,10 @@ def create_app(config_class=Config): app.register_blueprint(main_bp) + from app.admin import bp as admin_bp + + app.register_blueprint(admin_bp) + if not app.debug: if app.config["MAIL_SERVER"]: auth = None diff --git a/app/admin/__init__.py b/app/admin/__init__.py new file mode 100644 index 0000000..737dcc6 --- /dev/null +++ b/app/admin/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- + +from flask import Blueprint + +bp = Blueprint("admin", __name__, url_prefix="/admin") + +from app.admin import routes diff --git a/app/admin/decorators.py b/app/admin/decorators.py new file mode 100644 index 0000000..f42b582 --- /dev/null +++ b/app/admin/decorators.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +from functools import wraps + +from flask import current_app, request +from flask_login import current_user +from flask_login.config import EXEMPT_METHODS + + +def admin_required(func): + @wraps(func) + def decorated_view(*args, **kwargs): + if request.method in EXEMPT_METHODS: + return func(*args, **kwargs) + elif current_app.config.get("LOGIN_DISABLED"): + return func(*args, **kwargs) + elif not current_user.is_admin: + return current_app.login_manager.unauthorized() + return func(*args, **kwargs) + + return decorated_view diff --git a/app/admin/forms.py b/app/admin/forms.py new file mode 100644 index 0000000..b33b1c6 --- /dev/null +++ b/app/admin/forms.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +from flask_wtf import FlaskForm + +from wtforms import StringField, PasswordField, BooleanField, SubmitField +from wtforms.validators import DataRequired, ValidationError, Email, EqualTo + + +class AdminAssignTaskForm(FlaskForm): + username = StringField("Username", validators=[DataRequired()]) + dataset = StringField("Dataset", validators=[DataRequired()]) + submit = SubmitField("Assign") diff --git a/app/admin/routes.py b/app/admin/routes.py new file mode 100644 index 0000000..1150f72 --- /dev/null +++ b/app/admin/routes.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +from flask import render_template, flash, redirect, url_for +from flask_login import login_required + +from app import db +from app.admin import bp +from app.admin.decorators import admin_required +from app.admin.forms import AdminAssignTaskForm +from app.models import User, Dataset, Task + + +@bp.route("/assign", methods=("GET", "POST")) +@login_required +@admin_required +def assign(): + form = AdminAssignTaskForm() + if form.validate_on_submit(): + user = User.query.filter_by(username=form.username.data).first() + if user is None: + flash("User does not exist.") + return redirect(url_for("admin.assign")) + dataset = Dataset.query.filter_by(name=form.dataset.data).first() + if dataset is None: + flash("Dataset does not exist.") + return redirect(url_for("admin.assign")) + + task = Task.query.filter_by( + annotator_id=user.id, dataset_id=dataset.id + ) + if not task is None: + flash("Task assignment already exists.") + return redirect(url_for("admin.assign")) + + task = Task(annotator_id=user.id, dataset_id=dataset.id) + db.session.add(task) + db.session.commit() + flash("Task registered successfully.") + tasks = Task.query.all() + return render_template( + "admin/assign.html", title="Assign Task", form=form, tasks=tasks + ) diff --git a/app/templates/admin/assign.html b/app/templates/admin/assign.html new file mode 100644 index 0000000..44c6bf7 --- /dev/null +++ b/app/templates/admin/assign.html @@ -0,0 +1,34 @@ +{% extends "base.html" %} +{% import 'bootstrap/wtf.html' as wtf %} + +{% block app_content %} +<h1>Assign Task</h1> +<div class="row"> + <div class="col-md-4"> + {{ wtf.quick_form(form) }} + </div> +</div> +<article class="overview"> + <table> + <tr> + <th>User ID</th> + <th>Username</th> + <th>Dataset ID</th> + <th>Dataset Name</th> + <th>Status</th> + <th>Completed On</th> + </tr> + {% for task in tasks %} + <tr> + <td>{{ task.user_id }}</td> + <td>{{ task.username }}</td> + <td>{{ task.dataset_id }}</td> + <td>{{ task.dataset_name }}</td> + <td>{{ task.done }}</td> + <td>{{ task.completed_on }}</td> + </tr> + {% endfor %} + </tr> + </table> +</article> +{% endblock %} diff --git a/app/templates/base.html b/app/templates/base.html index 8e51695..7713eef 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -24,6 +24,9 @@ {% if current_user.is_anonymous %} <li><a href="{{ url_for('auth.login') }}">Login</a></li> {% else %} + {% if current_user.is_admin %} + <li><a href="/admin" style="color: red;">Admin Panel</a></li> + {% endif %} <li><a href="{{ url_for('auth.logout') }}">Logout</a></li> {% endif %} </ul> |
