roundabout,
created on Sunday, 15 September 2024, 11:43:08 (1726400588),
received on Sunday, 15 September 2024, 11:43:39 (1726400619)
Author identity: vlad <vlad.muntoiu@gmail.com>
bc45bba73420f48247383a503548aa5517f5bcf7
app.py
@@ -1,31 +1,21 @@
import json from datetime import datetimefrom email.policy import defaultfrom time import perf_counterimport os import mimetypesimport flask import ruamel.yaml as yaml import sqlalchemy.dialects.postgresql import config import markdown from datetime import datetime from os import pathfrom flask_sqlalchemy import SQLAlchemy from flask_bcrypt import Bcrypt from flask_httpauth import HTTPBasicAuthfrom markupsafe import escape, Markupfrom flask_migrate import Migrate, current from jinja2_fragments.flask import render_blockfrom sqlalchemy import falsefrom sqlalchemy.orm import backrefimport sqlalchemy.dialects.postgresqlfrom os import pathimport osfrom urllib.parse import urlencode import mimetypesimport ruamel.yaml as yamlfrom PIL import Image from sqlalchemy.orm.persistence import post_updatefrom sqlalchemy.sql.functions import current_user import configimport markdownapp = flask.Flask(__name__) bcrypt = Bcrypt(app)
@@ -567,6 +557,7 @@ def annotate_picture(id):
current_user = db.session.get(User, flask.session.get("username")) if current_user is None: flask.abort(401) if resource.author != current_user and not current_user.admin: flask.abort(403)
formats.md
@@ -118,7 +118,7 @@ key (this is to allow multiple rules of the same kind). Accepted rules are:
regions. * `below_region_count: count`: The image must have at most the given number of regions. * `copied_from: [image1, image2, ...]`: The image must be a copy of any of the* `copied_from: [image1, image2, ...]`: The image must be a copy of an image in theimages in the list (by ID). `ordering`, `offset` and `limit` can be specified as query parameters in the
static/efficient-ui
@@ -1 +1 @@
Subproject commit a98d70311f88ffc0d1551bc96a8a85c64f30fdf5Subproject commit 85d3e19a4ddf478cc9ca665b3695316dcd5efbff
static/picture-annotation.py
@@ -30,6 +30,16 @@ new_shape = None
selected_shape = None def make_shape_container(): shape = document.createElementNS("http://www.w3.org/2000/svg", "svg") shape.setAttribute("width", "100%") shape.setAttribute("height", "100%") shape.setAttribute("viewBox", f"0 0 {image.naturalWidth} {image.naturalHeight}") shape.classList.add("shape-container") return shape async def get_all_objects(): response = await pyfetch("/api/object-types") if response.ok:
@@ -102,12 +112,8 @@ def list_shapes():
def put_shapes(json_shapes): for shape in json_shapes: new_shape = document.createElementNS("http://www.w3.org/2000/svg", "svg")new_shape.setAttribute("width", "100%")new_shape.setAttribute("height", "100%")new_shape = make_shape_container()zone_rect = zone.getBoundingClientRect() new_shape.setAttribute("viewBox", f"0 0 {image.naturalWidth} {image.naturalHeight}")new_shape.classList.add("shape-container")if shape["type"] == "bbox": rectangle = document.createElementNS("http://www.w3.org/2000/svg", "rect")
@@ -406,12 +412,8 @@ def make_bbox(event):
rectangle = document.createElementNS("http://www.w3.org/2000/svg", "rect") new_shape = document.createElementNS("http://www.w3.org/2000/svg", "svg")new_shape.setAttribute("width", "100%")new_shape.setAttribute("height", "100%")new_shape = make_shape_container()zone_rect = zone.getBoundingClientRect() new_shape.setAttribute("viewBox", f"0 0 {image.naturalWidth} {image.naturalHeight}")new_shape.classList.add("shape-container")new_shape.appendChild(rectangle) zone.appendChild(new_shape)
@@ -537,12 +539,8 @@ def open_shape(event):
"remove the last point") if not polygon_points and not new_shape: new_shape = document.createElementNS("http://www.w3.org/2000/svg", "svg")new_shape.setAttribute("width", "100%")new_shape.setAttribute("height", "100%")new_shape = make_shape_container()zone_rect = zone.getBoundingClientRect() new_shape.setAttribute("viewBox", f"0 0 {image.naturalWidth} {image.naturalHeight}")new_shape.classList.add("shape-container")if not polygon_points and int(len(new_shape.children)) == 0: zone.addEventListener("click", make_polygon_proxy)
@@ -578,12 +576,8 @@ def open_shape(event):
point.classList.add("shape") point.setAttribute("data-object-type", "") new_shape = document.createElementNS("http://www.w3.org/2000/svg", "svg")new_shape.setAttribute("width", "100%")new_shape.setAttribute("height", "100%")new_shape = make_shape_container()zone_rect = zone.getBoundingClientRect() new_shape.setAttribute("viewBox", f"0 0 {image.naturalWidth} {image.naturalHeight}")new_shape.classList.add("shape-container")new_shape.appendChild(point) zone.appendChild(new_shape)