first pass of import logging, its not being used, data is in real tables, but faked. will probably have to switch to gunicorn and threading to allow import and serving pages when we use slower AI routines

This commit is contained in:
2021-01-14 00:15:54 +11:00
parent e9137c91fa
commit 3684f279e4
7 changed files with 145 additions and 2 deletions

15
TODO
View File

@@ -7,6 +7,21 @@
### UI ### UI
* use native file dialog box to set import_path in a "settings page" * use native file dialog box to set import_path in a "settings page"
* basic browse the import path * basic browse the import path
* some sort of log of import like:
State: finding files / found X files / AI for <cam>
Progress: overall # of passes
Progress: X of Y files
History:
<time> finding files
<time> found X files
<time> getting thumbnails for files
<time> X/10 of X
<time> 100% of all thumbs
<time> starting AI for <ref_img>
<time> X/10 of X done - AI for <ref_img>
etc...
### AI ### AI
* store reference images * store reference images

View File

@@ -20,6 +20,7 @@ import time
# Local Class imports # Local Class imports
################################################################################ ################################################################################
from settings import Settings from settings import Settings
from importlog import Importlog, Importlogline
class FileData(): class FileData():
def __init__(self): def __init__(self):

59
importlog.py Normal file
View File

@@ -0,0 +1,59 @@
from wtforms import SubmitField, StringField, FloatField, HiddenField, validators, Form
from flask_wtf import FlaskForm
from flask import request, render_template, redirect
from main import db, app, ma
from sqlalchemy import Sequence
from sqlalchemy.exc import SQLAlchemyError
from status import st, Status
from datetime import datetime, timedelta
import pytz
################################################################################
# Class describing Action in the database, and via sqlalchemy, connected to the DB as well
################################################################################
class Importlog(db.Model):
id = db.Column(db.Integer, db.Sequence('importlog_id_seq'), primary_key=True )
start_time = db.Column(db.DateTime(timezone=True))
last_update = db.Column(db.DateTime(timezone=True))
state = db.Column(db.String)
num_passes = db.Column(db.Integer)
current_pass = db.Column(db.Integer)
num_files = db.Column(db.Integer)
current_file_num = db.Column(db.Integer)
current_file = db.Column(db.String)
def __repr__(self):
return "<id: {}, start_time: {}, last_update: {}, state: {}, num_passes: {}, current_passes: {}, num_files: {}, current_file_num: {}, current_file: {}>".format(self.id, self.start_time, self.last_update, self.state, self.num_passes, self.current_pass, self.num_files, self.num_files, self.current_file_num, self.current_file)
class Importlogline(db.Model):
action_id = db.Column(db.Integer, db.ForeignKey('import.id'), primary_key=True )
log = db.Column(db.String)
################################################################################
# /imports -> show current settings
################################################################################
@app.route("/imports", methods=["GET"])
def imports():
page_title='Import actions'
imports = Importlog.query.all()
return render_template("imports.html", imports=imports, page_title=page_title, alert=st.GetAlert(), message=st.GetMessage() )
###############################################################################
# /import/<id> -> GET -> shows status/history of imports
################################################################################
@app.route("/import/<id>", methods=["GET"])
def importlog(id):
page_title='Show Import Details'
importlog = Importlog.query.get(id)
duration=(datetime.now(pytz.utc)-importlog.start_time)
duration= duration-timedelta(microseconds=duration.microseconds)
return render_template("importlog.html", imp=importlog, st=importlog.start_time.strftime("%d/%m/%Y %I:%M:%S %p"), duration=duration, page_title=page_title, alert=st.GetAlert(), message=st.GetMessage() )
###############################################################################
# This func creates a new filter in jinja2 to format the time from the db in a
# way that is more readable (converted to local tz too)
################################################################################
@app.template_filter('vicdate')
def _jinja2_filter_datetime(date, fmt=None):
return date.strftime("%d/%m/%Y %I:%M:%S %p")

View File

@@ -31,6 +31,7 @@ from settings import Settings
from files import Files from files import Files
from person import Person from person import Person
from refimg import Refimg from refimg import Refimg
from importlog import Importlog
from ai import * from ai import *
####################################### CLASSES / DB model ####################################### ####################################### CLASSES / DB model #######################################

View File

@@ -7,7 +7,7 @@ from sqlalchemy.exc import SQLAlchemyError
from status import st, Status from status import st, Status
################################################################################ ################################################################################
# Class describing Author in the database, and via sqlalchemy, connected to the DB as well # Class describing Settings in the database, and via sqlalchemy, connected to the DB as well
################################################################################ ################################################################################
class Settings(db.Model): class Settings(db.Model):
id = db.Column(db.Integer, db.Sequence('settings_id_seq'), primary_key=True ) id = db.Column(db.Integer, db.Sequence('settings_id_seq'), primary_key=True )
@@ -18,7 +18,7 @@ class Settings(db.Model):
return "<id: {}, import_path: {}, last_import_date: {}>".format(self.id, self.import_path, self.last_import_date) return "<id: {}, import_path: {}, last_import_date: {}>".format(self.id, self.import_path, self.last_import_date)
################################################################################ ################################################################################
# Helper class that inherits a .dump() method to turn class Author into json / useful in jinja2 # Helper class that inherits a .dump() method to turn class Settings into json / useful in jinja2
################################################################################ ################################################################################
class SettingsSchema(ma.SQLAlchemyAutoSchema): class SettingsSchema(ma.SQLAlchemyAutoSchema):
class Meta: class Meta:

45
templates/importlog.html Normal file
View File

@@ -0,0 +1,45 @@
{% extends "base.html" %}
{% block main_content %}
<div class="container">
<h3>{{page_title}}</h3>
<div class="row col-lg-12">
<label class="form-control-plaintext col-lg-2">Start Time:</label>
<label class="form-control-plaintext col-lg-10">{{imp.start_time|vicdate}}</label>
</div>
<div class="row col-lg-12">
<label class="form-control-plaintext col-lg-2">Duration:</label>
<label class="form-control-plaintext col-lg-10">{{duration}}</label>
</div>
<div class="row col-lg-12">
<label class="form-control-plaintext col-lg-2">Last Update:</label>
<label class="form-control-plaintext col-lg-10">{{imp.last_update|vicdate}}</label>
</div>
<div class="row col-lg-12">
<label class="form-control-plaintext col-lg-2">Current state:</label>
<label class="form-control-plaintext col-lg-10">{{imp.state}}</label>
</div>
<div class="row col-lg-12">
<label class="form-control-plaintext col-lg-2">Current File:</label>
<label class="form-control-plaintext col-lg-10">{{imp.current_file}}</label>
</div>
<div class="row col-lg-12">
{% set prog=(imp.current_pass/imp.num_passes*100)|round|int %}
<label class="form-control-plaintext col-lg-2">Passes:</label>
<div class="col-lg-10 px-0">
<div class="progress" style="height:80%">
<div class="progress-bar" role="progressbar" style="width: {{prog}}%;" aria-valuenow="{{prog}}" aria-valuemin="0" aria-valuemax="100">{{imp.current_pass}} of {{imp.num_passes}} - {{prog}}%</div>
</div>
</div>
</div>
<div class="row col-lg-12">
{% set prog=(imp.current_file_num/imp.num_files*100)|round|int %}
<label class="form-control-plaintext col-lg-2">Files in pass:</label>
<div class="col-lg-10 px-0">
<div class="progress" style="height:80%">
<div class="progress-bar bg-info" role="progressbar" style="width: {{prog}}%;" aria-valuenow="{{prog}}" aria-valuemin="0" aria-valuemax="100">{{imp.current_file_num}} of {{imp.num_files}} - {{prog}}%</div>
</div>
</div>
</div>
</div class="containter">
{% endblock main_content %}

22
templates/imports.html Normal file
View File

@@ -0,0 +1,22 @@
{% extends "base.html" %}
{% block main_content %}
<h3>{{page_title}}</h3>
<table id="import_tbl" class="table table-striped table-sm" data-toolbar="#toolbar" data-search="true">
<thead>
<tr class="thead-light"><th>Import Id</th><th>Import Started</th><th>Passes</th></tr>
</thead>
<tbody>
{% for imp in imports %}
<tr><td><a href="{{url_for('importlog', id=imp.id )}}">{{imp.id}}</td><td>{{imp.start_time}}</td>
<td>
<div class="progress">
{% set prog=(imp.current_pass/imp.num_passes*100)|round|int %}
<div class="progress-bar" role="progressbar" style="width: {{prog}}%;" aria-valuenow="{{prog}}" aria-valuemin="0" aria-valuemax="100">{{imp.current_pass}} of {{imp.num_passes}}</div>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock main_content %}