Implement index list setting field

This commit is contained in:
Tim Van Baak 2020-04-29 23:23:46 -07:00
parent 48047a4b6a
commit 8446adcc83
2 changed files with 50 additions and 2 deletions

View File

@ -63,6 +63,9 @@
{{ number_setting(form.turnMax) }} {{ number_setting(form.turnMax) }}
{{ form.articleIndexList.label }}:<br> {{ form.articleIndexList.label }}:<br>
{{ form.articleIndexList(class_="fullwidth", rows=10) }} {{ form.articleIndexList(class_="fullwidth", rows=10) }}
{% for error in form.articleIndexList.errors %}
<span style="color: #ff0000">{{ error }}</span><br>
{% endfor %}
{{ number_setting(form.articleIndexCapacity) }} {{ number_setting(form.articleIndexCapacity) }}
</p> </p>

View File

@ -1,3 +1,4 @@
import re
from typing import cast from typing import cast
from flask import current_app from flask import current_app
@ -8,7 +9,8 @@ from wtforms import (
BooleanField, BooleanField,
TextAreaField, TextAreaField,
IntegerField, IntegerField,
SelectField) SelectField,
ValidationError)
from wtforms.validators import DataRequired, Optional from wtforms.validators import DataRequired, Optional
from wtforms.widgets.html5 import NumberInput from wtforms.widgets.html5 import NumberInput
@ -17,6 +19,12 @@ from amanuensis.models import ModelFactory, UserModel
from amanuensis.server.forms import User from amanuensis.server.forms import User
index_regex = re.compile(
r'(char|prefix|etc)' # index type
r'(\[(-?\d+)\])?' # index pri
r':(.+)') # index pattern
class SettingTranslator(): class SettingTranslator():
""" """
Base class for the translation layer between internal config data Base class for the translation layer between internal config data
@ -46,6 +54,32 @@ class UsernameTranslator(SettingTranslator):
return user.uid return user.uid
class IndexListTranslator(SettingTranslator):
"""
Converts internal index representations into the index
specification format used in the editable list.
"""
def load(self, cfg_value):
index_list = []
for index in cfg_value:
if index.pri == 0:
index_list.append('{type}:{pattern}'.format(**index))
else:
index_list.append('{type}[{pri}]:{pattern}'.format(**index))
return '\n'.join(index_list)
def save(self, field_data):
index_list = []
for index in field_data.split('\n'):
match = index_regex.fullmatch(index)
itype, _, pri, pattern = match.groups()
index_list.append(dict(
type=itype,
pri=pri or 0,
pattern=pattern.strip()))
return index_list
class Setting(): class Setting():
""" """
Represents a relation between a node in a lexicon config and a Represents a relation between a node in a lexicon config and a
@ -84,6 +118,14 @@ class Setting():
cfg[self.cfg_path[-1]] = self.translator.save(data) cfg[self.cfg_path[-1]] = self.translator.save(data)
def IndexList(form, field):
if not field.data:
raise ValidationError('You must specify an index list.')
for index in field.data.split('\n'):
if not index_regex.fullmatch(index):
raise ValidationError(f'Bad index: "{index}"')
class Settings(): class Settings():
@staticmethod @staticmethod
def settings(): def settings():
@ -166,7 +208,10 @@ class Settings():
'Block turn publish if any articles are awaiting editor review')) 'Block turn publish if any articles are awaiting editor review'))
s_articleIndexList = Setting('article.index.list', s_articleIndexList = Setting('article.index.list',
TextAreaField('Index specifications')) TextAreaField(
'Index specifications',
validators=[IndexList]),
translator=IndexListTranslator())
s_articleIndexCapacity = Setting('article.index.capacity', s_articleIndexCapacity = Setting('article.index.capacity',
IntegerField( IntegerField(