multiple user support
This commit is contained in:
39
README.md
39
README.md
@@ -9,19 +9,44 @@ Setup:
|
|||||||
- Write a data/config.json:
|
- Write a data/config.json:
|
||||||
|
|
||||||
```
|
```
|
||||||
{ "title": "My Labeler",
|
{
|
||||||
"labels": [
|
"title": "My Labeler",
|
||||||
|
"users": [
|
||||||
|
"user1",
|
||||||
|
"name2"
|
||||||
|
],
|
||||||
|
"labels": [
|
||||||
{
|
{
|
||||||
"type": "checkbox", "name": "my_check", "value": "off"},
|
"type": "checkbox",
|
||||||
{"type": "text", "name": "my_text", "value": "1.0"},
|
"name": "my_check",
|
||||||
|
"default": "off"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "number",
|
||||||
|
"name": "my_number",
|
||||||
|
"default": "1.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "text",
|
||||||
|
"name": "my_text",
|
||||||
|
"default": "some text"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "range",
|
"type": "range",
|
||||||
"name": "my_slider",
|
"name": "my_slider",
|
||||||
"value": "75",
|
"default": "75",
|
||||||
"min": "0",
|
"min": "0",
|
||||||
"max": "100",
|
"max": "100"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "select",
|
||||||
|
"name": "my_selection",
|
||||||
|
"default": "select2",
|
||||||
|
"options": [
|
||||||
|
"option1",
|
||||||
|
"select2"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import time
|
|
||||||
import datetime
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
@@ -13,7 +11,6 @@ from flask import (
|
|||||||
url_for,
|
url_for,
|
||||||
abort,
|
abort,
|
||||||
render_template,
|
render_template,
|
||||||
flash,
|
|
||||||
)
|
)
|
||||||
from revprox import ReverseProxied
|
from revprox import ReverseProxied
|
||||||
|
|
||||||
@@ -40,6 +37,7 @@ def before_request_func():
|
|||||||
with open(app.config["CONFIG_FILE"], "rt") as fp:
|
with open(app.config["CONFIG_FILE"], "rt") as fp:
|
||||||
g.config = json.load(fp)
|
g.config = json.load(fp)
|
||||||
g.labels = g.config["labels"]
|
g.labels = g.config["labels"]
|
||||||
|
g.users = g.config["users"]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.warning(e)
|
logging.warning(e)
|
||||||
logging.warning("config.json could not be read. using defaults.")
|
logging.warning("config.json could not be read. using defaults.")
|
||||||
@@ -55,9 +53,11 @@ def before_request_func():
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
g.config = {"title": "Labeler", "labels": g.labels}
|
g.config = {"title": "Labeler", "labels": g.labels}
|
||||||
|
g.users = ["user"]
|
||||||
|
|
||||||
for label in g.labels:
|
for label in g.labels:
|
||||||
label['value'] = label['default']
|
label["value"] = label["default"]
|
||||||
|
|
||||||
|
|
||||||
def natural_key(string_):
|
def natural_key(string_):
|
||||||
"""See http://www.codinghorror.com/blog/archives/001018.html"""
|
"""See http://www.codinghorror.com/blog/archives/001018.html"""
|
||||||
@@ -66,7 +66,7 @@ def natural_key(string_):
|
|||||||
|
|
||||||
def get_metadata_path(image_path):
|
def get_metadata_path(image_path):
|
||||||
base, ext = os.path.splitext(os.path.basename(image_path))
|
base, ext = os.path.splitext(os.path.basename(image_path))
|
||||||
jsonpath = os.path.join(app.config["LABELDIR"], base + ".json")
|
jsonpath = os.path.join(app.config["LABELDIR"], get_user(), base + ".json")
|
||||||
return jsonpath
|
return jsonpath
|
||||||
|
|
||||||
|
|
||||||
@@ -126,9 +126,45 @@ def set_metadata(values, imagepath):
|
|||||||
return json.dump(values, fp, indent=2, sort_keys=True)
|
return json.dump(values, fp, indent=2, sort_keys=True)
|
||||||
|
|
||||||
|
|
||||||
|
def set_user(user_name):
|
||||||
|
if user_name not in g.users:
|
||||||
|
raise ValueError("No such user {}".format(user_name))
|
||||||
|
session["user"] = user_name
|
||||||
|
try:
|
||||||
|
os.makedirs(os.path.join(app.config["LABELDIR"], user_name))
|
||||||
|
except FileExistsError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def get_user():
|
||||||
|
|
||||||
|
return session.get("user", None)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/", methods=["GET", "POST"])
|
@app.route("/", methods=["GET", "POST"])
|
||||||
|
@app.route("/user:<int:user>", methods=["GET", "POST"])
|
||||||
|
def main(user=None):
|
||||||
|
|
||||||
|
if request.method == "POST":
|
||||||
|
user_name = request.form["user_name"]
|
||||||
|
set_user(user_name)
|
||||||
|
return redirect(url_for("show_image"))
|
||||||
|
|
||||||
|
user_name = get_user()
|
||||||
|
|
||||||
|
return render_template(
|
||||||
|
"main.html",
|
||||||
|
current_user=user_name,
|
||||||
|
users=g.users,
|
||||||
|
title=g.config.get("title", "Labeler"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/image", methods=["GET", "POST"])
|
||||||
@app.route("/image:<int:id>", methods=["GET", "POST"])
|
@app.route("/image:<int:id>", methods=["GET", "POST"])
|
||||||
def show_image(id=None):
|
def show_image(id=None):
|
||||||
|
if get_user() is None:
|
||||||
|
return redirect(url_for("main"))
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
# parse form
|
# parse form
|
||||||
|
|||||||
19
code/templates/main.html
Normal file
19
code/templates/main.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{% extends "layout.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<div class="entries">
|
||||||
|
|
||||||
|
<div class="center inputcontainer">
|
||||||
|
<form action="{{ url_for('main') }}" method=post class=add-entry>
|
||||||
|
<label>Choose user:</label>
|
||||||
|
<select name="user_name">
|
||||||
|
{% for user in users %}
|
||||||
|
<option value="{{user}}" {% if user == current_user %}SELECTED{% endif %}>{{user}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<br>
|
||||||
|
<input type=submit value="Choose" name=save class="button_save">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user