diff --git a/README.md b/README.md index 1030680..9a2f669 100644 --- a/README.md +++ b/README.md @@ -18,41 +18,69 @@ Setup: { "type": "checkbox", "name": "my_check", - "default": "off" + "title": "Click to enable", + "default": "on" + }, + { + "type": "info", + "title": "Piece of text shown here." }, { "type": "number", "name": "my_number", - "default": "1.0" + "default": "1.0", + "title": "Only numbers allowed." }, { "type": "text", "name": "my_text", + "title": "Any text here", "default": "some text" }, { "type": "range", "name": "my_slider", + "title": "Slide away!", "default": "75", "min": "0", "max": "100" }, { "type": "select", + "title": "Select any from these", "name": "my_selection", "default": "select2", "options": [ "option1", - "select2" + "select2", + "select4", + "select5", + "select9" ] } ] } + ``` - Copy some images under data/images/ - Start the docker instance - Open the URL in http://localhost:$EXPOSE +## Label types + +Label entries require "type" and "name". All labels can include +a "title" field, which is added as a hover-on text, and "default" for +the default value. + +In some cases more fields required. + +- checkbox: If "default": "on", checkbox is selected. Otherwise it is unselected. +- text: Any string, if no default: "" +- number: Any number entry, if no default: "" +- range: Requires "min" and "max" values. if no default, default = min. +- select: Requires a list of "options". +- info: Not a selection. Add "title" field to show text instead. + ## With nginx: ``` diff --git a/code/labeler.py b/code/labeler.py index 1c55217..62d50d8 100644 --- a/code/labeler.py +++ b/code/labeler.py @@ -15,6 +15,7 @@ from flask import ( from revprox import ReverseProxied # configuration +VERSION = "2022.05.27" IMAGEDIR = "/data/images/" LABELDIR = "/data/labels/" CONFIG_FILE = "/data/config.json" @@ -33,6 +34,7 @@ app.wsgi_app = ReverseProxied(app.wsgi_app) @app.before_request def before_request_func(): + g.version = app.config["VERSION"] try: with open(app.config["CONFIG_FILE"], "rt") as fp: g.config = json.load(fp) @@ -43,7 +45,7 @@ def before_request_func(): logging.warning("config.json could not be read. using defaults.") g.labels = [ {"type": "checkbox", "name": "my_check", "default": "off"}, - {"type": "text", "name": "my_text", "default": "1.0"}, + {"type": "text", "name": "my_text", "default": "Some text"}, { "type": "range", "name": "my_slider", @@ -55,8 +57,14 @@ def before_request_func(): g.config = {"title": "Labeler", "labels": g.labels} g.users = ["user"] + if not "title" in g.config: + g.config["title"] = "Labeler" + for label in g.labels: - label["value"] = label["default"] + if label["type"] == "range": + label["value"] = label.get("default", label.get("min", "")) + else: + label["value"] = label.get("default", "") def natural_key(string_): @@ -152,12 +160,7 @@ def main(user=None): user_name = get_user() - return render_template( - "main.html", - current_user=user_name, - users=g.users, - title=g.config.get("title", "Labeler"), - ) + return render_template("main.html", current_user=user_name) @app.route("/image", methods=["GET", "POST"]) @@ -194,5 +197,4 @@ def show_image(id=None): labels=labels, id_minus=id_minus, id_plus=id_plus, - title=g.config.get("title", "Labeler"), ) \ No newline at end of file diff --git a/code/revprox.py b/code/revprox.py index 9649e61..3914560 100644 --- a/code/revprox.py +++ b/code/revprox.py @@ -1,7 +1,7 @@ class ReverseProxied(object): - '''Wrap the application in this middleware and configure the - front-end server to add these headers, to let you quietly bind - this to a URL other than / and to an HTTP scheme that is + """Wrap the application in this middleware and configure the + front-end server to add these headers, to let you quietly bind + this to a URL other than / and to an HTTP scheme that is different than what is used locally. In nginx: @@ -14,19 +14,20 @@ class ReverseProxied(object): } :param app: the WSGI application - ''' + """ + def __init__(self, app): self.app = app def __call__(self, environ, start_response): - script_name = environ.get('HTTP_X_SCRIPT_NAME', '') + script_name = environ.get("HTTP_X_SCRIPT_NAME", "") if script_name: - environ['SCRIPT_NAME'] = script_name - path_info = environ['PATH_INFO'] + environ["SCRIPT_NAME"] = script_name + path_info = environ["PATH_INFO"] if path_info.startswith(script_name): - environ['PATH_INFO'] = path_info[len(script_name):] + environ["PATH_INFO"] = path_info[len(script_name) :] - scheme = environ.get('HTTP_X_SCHEME', '') + scheme = environ.get("HTTP_X_SCHEME", "") if scheme: - environ['wsgi.url_scheme'] = scheme + environ["wsgi.url_scheme"] = scheme return self.app(environ, start_response) diff --git a/code/static/style.css b/code/static/style.css index e933d0a..50c7ac5 100644 --- a/code/static/style.css +++ b/code/static/style.css @@ -1,65 +1,125 @@ -body { font-family: sans-serif; background: #888; margin: 0px; - min-height: 100vh; width: 100vw; overflow-x: hidden; } -a, h1, h2 { color: #377ba8; } -h1, h2 { font-family: 'Georgia', serif; margin: 0; } -h1 { border-bottom: 2px solid #eee; } -h2 { font-size: 1.2em; } - -tr,td,tbody { margin: 0px; } - -.page { margin: 0em; - padding: 0em; background: #888; min-height: 100vh; width: 100vw;} -.entries { list-style: none; margin: 0; padding: 0; width:100%; min-height: 95vh; } - -.large { font-size: 3em; } -.right { text-align: right; } -.center { text-align: center; } - -#image { position: absolute; - left:0px; top:0px; - width: calc(100vw - 220px); /*height:95vh;*/ } -#img { max-width: calc(100vw - 220px); max-height:95vh; - width: auto; height: auto; - display: block; margin-left: auto; - margin-right: auto; } - -#img_title { overflow-x: hidden; - overflow-wrap: anywhere; +body { + font-family: sans-serif; + background: #888; + margin: 0px; + min-height: 100vh; + width: 100vw; + overflow-x: hidden; +} + +.page { + margin: 0em; + padding: 0em; + background: #888; + min-height: 100vh; + width: 100vw; +} + +.entries { + list-style: none; + margin: 0; + padding: 0; + width: 100%; + min-height: 95vh; +} + +.large { + font-size: 3em; +} + +.right { + text-align: right; +} + +.center { + text-align: center; +} + +#home { + position: absolute; + left: 0px; + bottom: 0px; +} + +#home a { + color: black; + font-weight: bold; + font-size: large; + background-color: #aaa; + border-radius: 5px; + padding: 2px; +} + +#image { + position: absolute; + left: 0px; + top: 0px; + width: calc(100vw - 220px); + /*height:95vh;*/ +} + +#img { + max-width: calc(100vw - 220px); + max-height: 95vh; + width: auto; + height: auto; + display: block; + margin-left: auto; + margin-right: auto; +} + +#img_title { + overflow-x: hidden; + overflow-wrap: anywhere; +} + +#topright { + position: absolute; + right: 0px; + top: 0px; + /*width: 20vw;*/ + height: 95vh; + font-size: large; } -#topright { position: absolute; - right:0px; top:0px; - /*width: 20vw;*/ - height:95vh; - font-size: large; } .inputcontainer { - z-index:1; - background-color: #aaa; - padding: 5px; - margin-bottom: 3px; - border-radius: 5px; - width: 210px; + z-index: 1; + background-color: #aaa; + padding: 5px; + margin-bottom: 3px; + border-radius: 5px; + width: 210px; } -input, select { - width: 180px; - font-size: large; - } - - -input[type="text"] { - +input, +select { + width: 180px; + font-size: large; } -input[type="submit"] { -} + +input[type="text"] {} + +input[type="submit"] {} + input[type="checkbox"] { - width: 3em; - height: 1.5em; + width: 3em; + height: 1.5em; +} + +label { + display: block; +} + +output { + display: block; + font-weight: bold; +} + +.info { + font-size: initial; } -label { display: block; } -output { display: block; font-weight: bold; } .button_next { width: 2em; @@ -67,12 +127,15 @@ output { display: block; font-weight: bold; } font-size: large; margin-top: 1em; } + .float_left { - float: left; + float: left; } + .float_right { - float:right; + float: right; } + .button_save { height: 3em; margin-top: 1em; @@ -80,6 +143,7 @@ output { display: block; font-weight: bold; } margin-right: 1em; clear: both; } + .button_continue { height: 4em; margin-top: 3em; diff --git a/code/templates/layout.html b/code/templates/layout.html index d237cc1..3a1cbec 100644 --- a/code/templates/layout.html +++ b/code/templates/layout.html @@ -1,14 +1,15 @@ - + + -{{ title }} - - - - + {{ g.config.title }} + + + + -
- - {% block body %}{% endblock %} -
+
+ {% block body %}{% endblock %} +
+ \ No newline at end of file diff --git a/code/templates/main.html b/code/templates/main.html index 124e107..57ded7a 100644 --- a/code/templates/main.html +++ b/code/templates/main.html @@ -1,13 +1,12 @@ {% extends "layout.html" %} {% block body %}
-

diff --git a/code/templates/show_image.html b/code/templates/show_image.html index 778a7dc..99ab707 100644 --- a/code/templates/show_image.html +++ b/code/templates/show_image.html @@ -11,29 +11,33 @@ {% for label in labels %}
+ {% if label.type == "info" %} + + {% else %}
{% if label.type == "checkbox" %} - + {% endif %} {% if label.type == "text" %} - + {% endif %} {% if label.type == "number" %} - + {% endif %} {% if label.type == "range" %} - + {{label.value}} {% endif %} {% if label.type == "select" %} - {% for opt in label.options %} {% endfor %} {% endif %}
+ {% endif %}
{% endfor %}
@@ -45,8 +49,8 @@
-
+
🏠