use tooltips for settings, to explain path usage in particular
This commit is contained in:
19
settings.py
19
settings.py
@@ -53,12 +53,12 @@ settings_schema = SettingsSchema(many=True)
|
|||||||
################################################################################
|
################################################################################
|
||||||
class SettingsForm(FlaskForm):
|
class SettingsForm(FlaskForm):
|
||||||
id = HiddenField()
|
id = HiddenField()
|
||||||
base_path = StringField('Base Path to use below (optional):', [validators.DataRequired()])
|
base_path = StringField('Base Path to use below:', [validators.DataRequired()])
|
||||||
import_path = StringField('Path(s) to import from:', [validators.DataRequired()])
|
import_path = StringField('Path(s) to import from:', [validators.DataRequired()])
|
||||||
storage_path = StringField('Path to store sorted images to:', [validators.DataRequired()])
|
storage_path = StringField('Path to store sorted images to:', [validators.DataRequired()])
|
||||||
recycle_bin_path = StringField('Path to temporarily store deleted images in:', [validators.DataRequired()])
|
recycle_bin_path = StringField('Path to temporarily store deleted images in:', [validators.DataRequired()])
|
||||||
default_refimg_model = SelectField( 'default_refimg_model', choices=[(c.id, c.name) for c in AIModel.query.order_by('id')] )
|
default_refimg_model = SelectField( 'Default model to use for reference images', choices=[(c.id, c.name) for c in AIModel.query.order_by('id')] )
|
||||||
default_scan_model = SelectField( 'default_scan_model', choices=[(c.id, c.name) for c in AIModel.query.order_by('id')] )
|
default_scan_model = SelectField( 'Default model to use for all scanned images', choices=[(c.id, c.name) for c in AIModel.query.order_by('id')] )
|
||||||
default_threshold = StringField('Face Distance threshold (below is a match):', [validators.DataRequired()])
|
default_threshold = StringField('Face Distance threshold (below is a match):', [validators.DataRequired()])
|
||||||
submit = SubmitField('Save' )
|
submit = SubmitField('Save' )
|
||||||
|
|
||||||
@@ -70,6 +70,15 @@ class SettingsForm(FlaskForm):
|
|||||||
def settings():
|
def settings():
|
||||||
form = SettingsForm(request.form)
|
form = SettingsForm(request.form)
|
||||||
page_title='Settings'
|
page_title='Settings'
|
||||||
|
HELP={}
|
||||||
|
HELP['base_path']="Optional: if the paths below are absolute, then this field is ignored. If they are relative, then this field is prepended"
|
||||||
|
HELP['import_path']="Path(s) to import files from. If starting with /, then used literally, otherwise base path is prepended"
|
||||||
|
HELP['storage_path']="Path(s) to store sorted files to. If starting with /, then used literally, otherwise base path is prepended"
|
||||||
|
HELP['recycle_bin_path']="Path where deleted files are moved to. If starting with /, then used literally, otherwise base path is prepended"
|
||||||
|
HELP['default_refimg_model']="Default face recognition model used for reference images - cnn is slower/more accurate, hog is faster/less accurate - we scan (small) refimg once, so cnn is okay"
|
||||||
|
HELP['default_scan_model']="Default face recognition model used for scanned images - cnn is slower/more accurate, hog is faster/less accurate - we scan (large) scanned images lots, so cnn NEEDS gpu/mem"
|
||||||
|
HELP['default_threshold']="The distance below which a face is considered a match. The default is usually 0.6, we are trying for about 0.55 with kids. YMMV"
|
||||||
|
|
||||||
if request.method == 'POST' and form.validate():
|
if request.method == 'POST' and form.validate():
|
||||||
try:
|
try:
|
||||||
# HACK, I don't really need an id here, but sqlalchemy get weird
|
# HACK, I don't really need an id here, but sqlalchemy get weird
|
||||||
@@ -90,10 +99,10 @@ def settings():
|
|||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
st.SetAlert( "danger" )
|
st.SetAlert( "danger" )
|
||||||
st.SetMessage( "<b>Failed to modify Setting:</b> {}".format(e.orig) )
|
st.SetMessage( "<b>Failed to modify Setting:</b> {}".format(e.orig) )
|
||||||
return render_template("settings.html", form=form, page_title=page_title)
|
return render_template("settings.html", form=form, page_title=page_title, HELP=HELP)
|
||||||
else:
|
else:
|
||||||
form = SettingsForm( obj=Settings.query.first() )
|
form = SettingsForm( obj=Settings.query.first() )
|
||||||
return render_template("settings.html", form=form, page_title = page_title)
|
return render_template("settings.html", form=form, page_title = page_title, HELP=HELP)
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# SettingsRBPath(): return modified array of paths (take each path in
|
# SettingsRBPath(): return modified array of paths (take each path in
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
<!-- code to get bootstrap to work -->
|
<!-- code to get bootstrap to work -->
|
||||||
<script src="{{ url_for( 'internal', filename='upstream/jquery-3.6.0.min.js')}}"></script>
|
<script src="{{ url_for( 'internal', filename='upstream/jquery-3.6.0.min.js')}}"></script>
|
||||||
<script src="{{ url_for( 'internal', filename='upstream/bootstrap-5.0.2-dist/js/bootstrap.min.js')}}"></script>
|
<script src="{{ url_for( 'internal', filename='upstream/bootstrap-5.0.2-dist/js/bootstrap.bundle.min.js')}}"></script>
|
||||||
<script src="{{ url_for( 'internal', filename='upstream/jquery.contextMenu.min.js')}}"></script>
|
<script src="{{ url_for( 'internal', filename='upstream/jquery.contextMenu.min.js')}}"></script>
|
||||||
<script src="{{ url_for( 'internal', filename='upstream/jquery.ui.position.min.js')}}"></script>
|
<script src="{{ url_for( 'internal', filename='upstream/jquery.ui.position.min.js')}}"></script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% extends "base.html" %} {% block main_content %}
|
{% extends "base.html" %} {% block main_content %}
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<h3 class="offset-2">{{page_title}}</h3>
|
<h3 class="offset-3">{{page_title}}</h3>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<form action="" method="POST">
|
<form action="" method="POST">
|
||||||
{% for field in form %}
|
{% for field in form %}
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
{{field}}
|
{{field}}
|
||||||
{% elif field.type != 'SubmitField' %}
|
{% elif field.type != 'SubmitField' %}
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
{{ field.label( class="input-group-text col-3 justify-content-end" ) }}
|
{{ field.label( class="input-group-text col-3 justify-content-end", title=HELP[field.name] ) }}
|
||||||
{% if field.type == 'SelectField' %}
|
{% if field.type == 'SelectField' %}
|
||||||
{{ field( class="form-select col-9" ) }}
|
{{ field( class="form-select col-9" ) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
@@ -24,3 +24,15 @@
|
|||||||
</div class="row">
|
</div class="row">
|
||||||
</div class="container">
|
</div class="container">
|
||||||
{% endblock main_content %}
|
{% endblock main_content %}
|
||||||
|
{% block script_content %}
|
||||||
|
<script>
|
||||||
|
$("label").each( function() {
|
||||||
|
$(this).attr('data-bs-toggle', "tooltip")
|
||||||
|
$(this).attr('data-bs-placement', "right")
|
||||||
|
} )
|
||||||
|
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
|
||||||
|
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||||
|
return new bootstrap.Tooltip(tooltipTriggerEl)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
{% endblock script_content %}
|
||||||
|
|||||||
Reference in New Issue
Block a user