roundabout,
created on Friday, 6 September 2024, 14:54:24 (1725634464),
received on Friday, 6 September 2024, 19:35:57 (1725651357)
Author identity: vlad <vlad.muntoiu@gmail.com>
9a4e6304001c95126108bb7c3c47814d49e3d3b3
app.py
@@ -1,6 +1,7 @@
import json from datetime import datetime from email.policy import default from time import perf_counterimport flask from flask_sqlalchemy import SQLAlchemy
@@ -12,6 +13,7 @@ from jinja2_fragments.flask import render_block
from sqlalchemy.orm import backref import sqlalchemy.dialects.postgresql from os import path from urllib.parse import urlencodeimport mimetypes import ruamel.yaml as yaml
@@ -49,6 +51,22 @@ def set_filter(value):
return set(value) @app.template_global() def modify_query(**new_values): args = flask.request.args.copy() # for key, value in new_values.items(): # args[key] = value args |= new_values return f"{flask.request.path}?{urlencode(args)}" @app.context_processor def default_variables(): return { "current_user": db.session.get(User, flask.session.get("username")), } with app.app_context(): class User(db.Model): username = db.Column(db.String(32), unique=True, nullable=False, primary_key=True)
@@ -315,6 +333,23 @@ def profile(username):
return flask.render_template("profile.html", user=user) @app.route("/object/<id>") def has_object(id): object_ = db.session.get(PictureObject, id) if object_ is None: flask.abort(404) query = db.session.query(PictureResource).join(PictureRegion).filter(PictureRegion.object_id == id) page = int(flask.request.args.get("page", 1)) per_page = int(flask.request.args.get("per_page", 16)) resources = query.paginate(page=page, per_page=per_page) return flask.render_template("object.html", object=object_, resources=resources, page_number=page, per_page=per_page, num_pages=resources.pages) @app.route("/upload") def upload(): if "username" not in flask.session:
static/style.css
@@ -278,3 +278,31 @@ small {
/* BIG :D */ font-size: 1em; } #pagination { display: flex; gap: 1em; justify-content: center; align-items: center; font-size: 1.5em; font-weight: 600; flex: 1 0 auto; } #pagination > a { text-decoration: none; color: var(--color-accent-1); } #pagination-options > form { align-items: center; display: flex; gap: 1em; } #pagination-options { justify-content: center; align-items: center; gap: 1em; width: 100%; }
templates/object.html
@@ -0,0 +1,18 @@
{% extends "default.html" %} {% block title %}Object {{ object.id }} | gigadata{% endblock %} {% block content %} <x-frame style="--width: 768px"> <h1>{{ object.id }}</h1> <p>{{ object.description }}</p> <h2>Pictures with this object</h2> <ul> {% for resource in resources %} <li> <a href="/picture/{{ resource.id }}">{{ resource.title }}</a> </li> {% endfor %} </ul> {% include "pagination.html" %} </x-frame> {% endblock %}
templates/pagination.html
@@ -0,0 +1,35 @@
<x-hbox id="pagination-options"> <x-hbox id="pagination"> {% if prev_page %} <a href="{{ modify_query(per_page=page_length, page=1) }}"> « </a> <a href="{{ modify_query(per_page=page_length, page=prev_page) }}"> ‹ </a> {% endif %} <span>{{ page_number }}/{{ num_pages }}</span> {% if next_page %} <a href="{{ modify_query(per_page=page_length, page=next_page) }}"> › </a> <a href="{{ modify_query(per_page=page_length, page=num_pages) }}"> » </a> {% endif %} </x-hbox> <form> <div> {% for key, value in request.args.items() %} {% if key not in ["page", "per_page"] %} <input type="hidden" name="{{ key }}" value="{{ value }}"> {% endif %} {% endfor %} </div> <label> Items per page: <input type="number" name="per_page" value="{{ page_length }}" min="1" max="256" style="font: var(--mono-font);"> </label> <button type="submit">Load</button> </form> </x-hbox>
templates/picture.html
@@ -1,5 +1,5 @@
{% extends "default.html" %} {% block title %}Picture | gigadata{% endblock %}{% block title %}Picture {{ resource.title }} | gigadata{% endblock %}{% macro shape_label(x, y, text) %} {% if text %} <foreignObject height="100%" width="100%" x="{{ x * size[0] }}" y="{{ y * size[1] }}">
@@ -87,6 +87,8 @@
<span>{{ resource.regions | length }}</span> <span>Number of labelled regions</span> <span>{{ resource.regions | selectattr("object_id") | list | length }}</span> <span>Date uploaded</span> <span>{{ resource.timestamp }}</span></div> Contains objects: {{ contains | join(", ") }} <x-hbox style="justify-content: space-between">