feat: add "has output file templates" config option for master view
this is a bit hacky, a quick copy/paste job from the equivalent feature for input file templates. i assume this will get cleaned up when moved to wuttaweb..
This commit is contained in:
parent
07871188aa
commit
1def26a35b
|
@ -143,6 +143,68 @@
|
||||||
</div>
|
</div>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
|
<%def name="output_file_template_field(key)">
|
||||||
|
<% tmpl = output_file_templates[key] %>
|
||||||
|
<b-field grouped>
|
||||||
|
|
||||||
|
<b-field label="${tmpl['label']}">
|
||||||
|
<b-select name="${tmpl['setting_mode']}"
|
||||||
|
v-model="outputFileTemplateSettings['${tmpl['setting_mode']}']"
|
||||||
|
@input="settingsNeedSaved = true">
|
||||||
|
<option value="default">use default</option>
|
||||||
|
<option value="hosted">use uploaded file</option>
|
||||||
|
</b-select>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
<b-field label="File"
|
||||||
|
v-show="outputFileTemplateSettings['${tmpl['setting_mode']}'] == 'hosted'"
|
||||||
|
:message="outputFileTemplateSettings['${tmpl['setting_file']}'] ? 'This file lives on disk at: ${output_file_option_dirs[tmpl['key']]}' : null">
|
||||||
|
<b-select name="${tmpl['setting_file']}"
|
||||||
|
v-model="outputFileTemplateSettings['${tmpl['setting_file']}']"
|
||||||
|
@input="settingsNeedSaved = true">
|
||||||
|
<option :value="null">-new-</option>
|
||||||
|
<option v-for="option in outputFileTemplateFileOptions['${tmpl['key']}']"
|
||||||
|
:key="option"
|
||||||
|
:value="option">
|
||||||
|
{{ option }}
|
||||||
|
</option>
|
||||||
|
</b-select>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
<b-field label="Upload"
|
||||||
|
v-show="outputFileTemplateSettings['${tmpl['setting_mode']}'] == 'hosted' && !outputFileTemplateSettings['${tmpl['setting_file']}']">
|
||||||
|
|
||||||
|
<b-field class="file is-primary"
|
||||||
|
:class="{'has-name': !!outputFileTemplateSettings['${tmpl['setting_file']}']}">
|
||||||
|
<b-upload name="${tmpl['setting_file']}.upload"
|
||||||
|
v-model="outputFileTemplateUploads['${tmpl['key']}']"
|
||||||
|
class="file-label"
|
||||||
|
@input="settingsNeedSaved = true">
|
||||||
|
<span class="file-cta">
|
||||||
|
<b-icon class="file-icon" pack="fas" icon="upload"></b-icon>
|
||||||
|
<span class="file-label">Click to upload</span>
|
||||||
|
</span>
|
||||||
|
</b-upload>
|
||||||
|
<span v-if="outputFileTemplateUploads['${tmpl['key']}']"
|
||||||
|
class="file-name">
|
||||||
|
{{ outputFileTemplateUploads['${tmpl['key']}'].name }}
|
||||||
|
</span>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
</b-field>
|
||||||
|
</%def>
|
||||||
|
|
||||||
|
<%def name="output_file_templates_section()">
|
||||||
|
<h3 class="block is-size-3">Output File Templates</h3>
|
||||||
|
<div class="block" style="padding-left: 2rem;">
|
||||||
|
% for key in output_file_templates:
|
||||||
|
${self.output_file_template_field(key)}
|
||||||
|
% endfor
|
||||||
|
</div>
|
||||||
|
</%def>
|
||||||
|
|
||||||
<%def name="form_content()"></%def>
|
<%def name="form_content()"></%def>
|
||||||
|
|
||||||
<%def name="page_content()">
|
<%def name="page_content()">
|
||||||
|
@ -229,6 +291,7 @@
|
||||||
ThisPageData.settingsNeedSaved = false
|
ThisPageData.settingsNeedSaved = false
|
||||||
ThisPageData.undoChanges = false
|
ThisPageData.undoChanges = false
|
||||||
ThisPageData.savingSettings = false
|
ThisPageData.savingSettings = false
|
||||||
|
ThisPageData.validators = []
|
||||||
|
|
||||||
ThisPage.methods.purgeSettingsInit = function() {
|
ThisPage.methods.purgeSettingsInit = function() {
|
||||||
this.purgeSettingsShowDialog = true
|
this.purgeSettingsShowDialog = true
|
||||||
|
@ -260,7 +323,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
ThisPage.methods.saveSettings = function() {
|
ThisPage.methods.saveSettings = function() {
|
||||||
let msg = this.validateSettings()
|
let msg
|
||||||
|
|
||||||
|
// nb. this is the future
|
||||||
|
for (let validator of this.validators) {
|
||||||
|
msg = validator.call(this)
|
||||||
|
if (msg) {
|
||||||
|
alert(msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// nb. legacy method
|
||||||
|
msg = this.validateSettings()
|
||||||
if (msg) {
|
if (msg) {
|
||||||
alert(msg)
|
alert(msg)
|
||||||
return
|
return
|
||||||
|
@ -291,5 +366,35 @@
|
||||||
window.addEventListener('beforeunload', this.beforeWindowUnload)
|
window.addEventListener('beforeunload', this.beforeWindowUnload)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
##############################
|
||||||
|
## output file templates
|
||||||
|
##############################
|
||||||
|
|
||||||
|
% if output_file_template_settings is not Undefined:
|
||||||
|
|
||||||
|
ThisPageData.outputFileTemplateSettings = ${json.dumps(output_file_template_settings)|n}
|
||||||
|
ThisPageData.outputFileTemplateFileOptions = ${json.dumps(output_file_options)|n}
|
||||||
|
ThisPageData.outputFileTemplateUploads = {
|
||||||
|
% for key in output_file_templates:
|
||||||
|
'${key}': null,
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisPage.methods.validateOutputFileTemplateSettings = function() {
|
||||||
|
% for tmpl in output_file_templates.values():
|
||||||
|
if (this.outputFileTemplateSettings['${tmpl['setting_mode']}'] == 'hosted') {
|
||||||
|
if (!this.outputFileTemplateSettings['${tmpl['setting_file']}']) {
|
||||||
|
if (!this.outputFileTemplateUploads['${tmpl['key']}']) {
|
||||||
|
return "You must provide a file to upload for the ${tmpl['label']} template."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisPageData.validators.push(ThisPage.methods.validateOutputFileTemplateSettings)
|
||||||
|
|
||||||
|
% endif
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
|
@ -1,2 +1,78 @@
|
||||||
## -*- coding: utf-8; -*-
|
## -*- coding: utf-8; -*-
|
||||||
<%inherit file="wuttaweb:templates/configure.mako" />
|
<%inherit file="wuttaweb:templates/configure.mako" />
|
||||||
|
<%namespace name="tailbone_base" file="tailbone:templates/configure.mako" />
|
||||||
|
|
||||||
|
<%def name="input_file_templates_section()">
|
||||||
|
${tailbone_base.input_file_templates_section()}
|
||||||
|
</%def>
|
||||||
|
|
||||||
|
<%def name="output_file_templates_section()">
|
||||||
|
${tailbone_base.output_file_templates_section()}
|
||||||
|
</%def>
|
||||||
|
|
||||||
|
<%def name="modify_vue_vars()">
|
||||||
|
${parent.modify_vue_vars()}
|
||||||
|
<script>
|
||||||
|
|
||||||
|
##############################
|
||||||
|
## input file templates
|
||||||
|
##############################
|
||||||
|
|
||||||
|
% if input_file_template_settings is not Undefined:
|
||||||
|
|
||||||
|
ThisPageData.inputFileTemplateSettings = ${json.dumps(input_file_template_settings)|n}
|
||||||
|
ThisPageData.inputFileTemplateFileOptions = ${json.dumps(input_file_options)|n}
|
||||||
|
ThisPageData.inputFileTemplateUploads = {
|
||||||
|
% for key in input_file_templates:
|
||||||
|
'${key}': null,
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisPage.methods.validateInputFileTemplateSettings = function() {
|
||||||
|
% for tmpl in input_file_templates.values():
|
||||||
|
if (this.inputFileTemplateSettings['${tmpl['setting_mode']}'] == 'hosted') {
|
||||||
|
if (!this.inputFileTemplateSettings['${tmpl['setting_file']}']) {
|
||||||
|
if (!this.inputFileTemplateUploads['${tmpl['key']}']) {
|
||||||
|
return "You must provide a file to upload for the ${tmpl['label']} template."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisPageData.validators.push(ThisPage.methods.validateInputFileTemplateSettings)
|
||||||
|
|
||||||
|
% endif
|
||||||
|
|
||||||
|
##############################
|
||||||
|
## output file templates
|
||||||
|
##############################
|
||||||
|
|
||||||
|
% if output_file_template_settings is not Undefined:
|
||||||
|
|
||||||
|
ThisPageData.outputFileTemplateSettings = ${json.dumps(output_file_template_settings)|n}
|
||||||
|
ThisPageData.outputFileTemplateFileOptions = ${json.dumps(output_file_options)|n}
|
||||||
|
ThisPageData.outputFileTemplateUploads = {
|
||||||
|
% for key in output_file_templates:
|
||||||
|
'${key}': null,
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisPage.methods.validateOutputFileTemplateSettings = function() {
|
||||||
|
% for tmpl in output_file_templates.values():
|
||||||
|
if (this.outputFileTemplateSettings['${tmpl['setting_mode']}'] == 'hosted') {
|
||||||
|
if (!this.outputFileTemplateSettings['${tmpl['setting_file']}']) {
|
||||||
|
if (!this.outputFileTemplateUploads['${tmpl['key']}']) {
|
||||||
|
return "You must provide a file to upload for the ${tmpl['label']} template."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisPageData.validators.push(ThisPage.methods.validateOutputFileTemplateSettings)
|
||||||
|
|
||||||
|
% endif
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</%def>
|
||||||
|
|
|
@ -117,6 +117,7 @@ class MasterView(View):
|
||||||
supports_prev_next = False
|
supports_prev_next = False
|
||||||
supports_import_batch_from_file = False
|
supports_import_batch_from_file = False
|
||||||
has_input_file_templates = False
|
has_input_file_templates = False
|
||||||
|
has_output_file_templates = False
|
||||||
configurable = False
|
configurable = False
|
||||||
|
|
||||||
# set to True to add "View *global* Objects" permission, and
|
# set to True to add "View *global* Objects" permission, and
|
||||||
|
@ -1820,6 +1821,26 @@ class MasterView(View):
|
||||||
path = os.path.join(basedir, filespec)
|
path = os.path.join(basedir, filespec)
|
||||||
return self.file_response(path)
|
return self.file_response(path)
|
||||||
|
|
||||||
|
def download_output_file_template(self):
|
||||||
|
"""
|
||||||
|
View for downloading an output file template.
|
||||||
|
"""
|
||||||
|
key = self.request.GET['key']
|
||||||
|
filespec = self.request.GET['file']
|
||||||
|
|
||||||
|
matches = [tmpl for tmpl in self.get_output_file_templates()
|
||||||
|
if tmpl['key'] == key]
|
||||||
|
if not matches:
|
||||||
|
raise self.notfound()
|
||||||
|
|
||||||
|
template = matches[0]
|
||||||
|
templatesdir = os.path.join(self.rattail_config.datadir(),
|
||||||
|
'templates', 'output_files',
|
||||||
|
self.get_route_prefix())
|
||||||
|
basedir = os.path.join(templatesdir, template['key'])
|
||||||
|
path = os.path.join(basedir, filespec)
|
||||||
|
return self.file_response(path)
|
||||||
|
|
||||||
def edit(self):
|
def edit(self):
|
||||||
"""
|
"""
|
||||||
View for editing an existing model record.
|
View for editing an existing model record.
|
||||||
|
@ -2848,6 +2869,12 @@ class MasterView(View):
|
||||||
kwargs['input_file_templates'] = OrderedDict([(tmpl['key'], tmpl)
|
kwargs['input_file_templates'] = OrderedDict([(tmpl['key'], tmpl)
|
||||||
for tmpl in templates])
|
for tmpl in templates])
|
||||||
|
|
||||||
|
# add info for downloadable output file templates, if any
|
||||||
|
if self.has_output_file_templates:
|
||||||
|
templates = self.normalize_output_file_templates()
|
||||||
|
kwargs['output_file_templates'] = OrderedDict([(tmpl['key'], tmpl)
|
||||||
|
for tmpl in templates])
|
||||||
|
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def get_input_file_templates(self):
|
def get_input_file_templates(self):
|
||||||
|
@ -2922,6 +2949,81 @@ class MasterView(View):
|
||||||
|
|
||||||
return templates
|
return templates
|
||||||
|
|
||||||
|
def get_output_file_templates(self):
|
||||||
|
return []
|
||||||
|
|
||||||
|
def normalize_output_file_templates(self, templates=None,
|
||||||
|
include_file_options=False):
|
||||||
|
if templates is None:
|
||||||
|
templates = self.get_output_file_templates()
|
||||||
|
|
||||||
|
route_prefix = self.get_route_prefix()
|
||||||
|
|
||||||
|
if include_file_options:
|
||||||
|
templatesdir = os.path.join(self.rattail_config.datadir(),
|
||||||
|
'templates', 'output_files',
|
||||||
|
route_prefix)
|
||||||
|
|
||||||
|
for template in templates:
|
||||||
|
|
||||||
|
if 'config_section' not in template:
|
||||||
|
if hasattr(self, 'output_file_template_config_section'):
|
||||||
|
template['config_section'] = self.output_file_template_config_section
|
||||||
|
else:
|
||||||
|
template['config_section'] = route_prefix
|
||||||
|
section = template['config_section']
|
||||||
|
|
||||||
|
if 'config_prefix' not in template:
|
||||||
|
template['config_prefix'] = '{}.{}'.format(
|
||||||
|
self.output_file_template_config_prefix,
|
||||||
|
template['key'])
|
||||||
|
prefix = template['config_prefix']
|
||||||
|
|
||||||
|
for key in ('mode', 'file', 'url'):
|
||||||
|
|
||||||
|
if 'option_{}'.format(key) not in template:
|
||||||
|
template['option_{}'.format(key)] = '{}.{}'.format(prefix, key)
|
||||||
|
|
||||||
|
if 'setting_{}'.format(key) not in template:
|
||||||
|
template['setting_{}'.format(key)] = '{}.{}'.format(
|
||||||
|
section,
|
||||||
|
template['option_{}'.format(key)])
|
||||||
|
|
||||||
|
if key not in template:
|
||||||
|
value = self.rattail_config.get(
|
||||||
|
section,
|
||||||
|
template['option_{}'.format(key)])
|
||||||
|
if value is not None:
|
||||||
|
template[key] = value
|
||||||
|
|
||||||
|
template.setdefault('mode', 'default')
|
||||||
|
template.setdefault('file', None)
|
||||||
|
template.setdefault('url', template['default_url'])
|
||||||
|
|
||||||
|
if include_file_options:
|
||||||
|
options = []
|
||||||
|
basedir = os.path.join(templatesdir, template['key'])
|
||||||
|
if os.path.exists(basedir):
|
||||||
|
for name in sorted(os.listdir(basedir)):
|
||||||
|
if len(name) == 4 and name.isdigit():
|
||||||
|
files = os.listdir(os.path.join(basedir, name))
|
||||||
|
if len(files) == 1:
|
||||||
|
options.append(os.path.join(name, files[0]))
|
||||||
|
template['file_options'] = options
|
||||||
|
template['file_options_dir'] = basedir
|
||||||
|
|
||||||
|
if template['mode'] == 'external':
|
||||||
|
template['effective_url'] = template['url']
|
||||||
|
elif template['mode'] == 'hosted':
|
||||||
|
template['effective_url'] = self.request.route_url(
|
||||||
|
'{}.download_output_file_template'.format(route_prefix),
|
||||||
|
_query={'key': template['key'],
|
||||||
|
'file': template['file']})
|
||||||
|
else:
|
||||||
|
template['effective_url'] = template['default_url']
|
||||||
|
|
||||||
|
return templates
|
||||||
|
|
||||||
def template_kwargs_index(self, **kwargs):
|
def template_kwargs_index(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
Method stub, so subclass can always invoke super() for it.
|
Method stub, so subclass can always invoke super() for it.
|
||||||
|
@ -2969,6 +3071,12 @@ class MasterView(View):
|
||||||
items.append(tags.link_to(f"Download {template['label']} Template",
|
items.append(tags.link_to(f"Download {template['label']} Template",
|
||||||
template['effective_url']))
|
template['effective_url']))
|
||||||
|
|
||||||
|
if self.has_output_file_templates and self.has_perm('configure'):
|
||||||
|
templates = self.normalize_output_file_templates()
|
||||||
|
for template in templates:
|
||||||
|
items.append(tags.link_to(f"Download {template['label']} Template",
|
||||||
|
template['effective_url']))
|
||||||
|
|
||||||
# if self.viewing:
|
# if self.viewing:
|
||||||
|
|
||||||
# # # TODO: either make this configurable, or just lose it.
|
# # # TODO: either make this configurable, or just lose it.
|
||||||
|
@ -5204,6 +5312,39 @@ class MasterView(View):
|
||||||
data[template['setting_file']] = os.path.join(numdir,
|
data[template['setting_file']] = os.path.join(numdir,
|
||||||
info['filename'])
|
info['filename'])
|
||||||
|
|
||||||
|
if self.has_output_file_templates:
|
||||||
|
templatesdir = os.path.join(self.rattail_config.datadir(),
|
||||||
|
'templates', 'output_files',
|
||||||
|
self.get_route_prefix())
|
||||||
|
|
||||||
|
def get_next_filedir(basedir):
|
||||||
|
nextid = 1
|
||||||
|
while True:
|
||||||
|
path = os.path.join(basedir, '{:04d}'.format(nextid))
|
||||||
|
if not os.path.exists(path):
|
||||||
|
# this should fail if there happens to be a race
|
||||||
|
# condition and someone else got to this id first
|
||||||
|
os.mkdir(path)
|
||||||
|
return path
|
||||||
|
nextid += 1
|
||||||
|
|
||||||
|
for template in self.normalize_output_file_templates():
|
||||||
|
key = '{}.upload'.format(template['setting_file'])
|
||||||
|
if key in uploads:
|
||||||
|
assert self.request.POST[template['setting_mode']] == 'hosted'
|
||||||
|
assert not self.request.POST[template['setting_file']]
|
||||||
|
info = uploads[key]
|
||||||
|
basedir = os.path.join(templatesdir, template['key'])
|
||||||
|
if not os.path.exists(basedir):
|
||||||
|
os.makedirs(basedir)
|
||||||
|
filedir = get_next_filedir(basedir)
|
||||||
|
filepath = os.path.join(filedir, info['filename'])
|
||||||
|
shutil.copyfile(info['filepath'], filepath)
|
||||||
|
shutil.rmtree(info['filedir'])
|
||||||
|
numdir = os.path.basename(filedir)
|
||||||
|
data[template['setting_file']] = os.path.join(numdir,
|
||||||
|
info['filename'])
|
||||||
|
|
||||||
def configure_get_simple_settings(self):
|
def configure_get_simple_settings(self):
|
||||||
"""
|
"""
|
||||||
If you have some "simple" settings, each of which basically
|
If you have some "simple" settings, each of which basically
|
||||||
|
@ -5248,7 +5389,8 @@ class MasterView(View):
|
||||||
simple['option'])
|
simple['option'])
|
||||||
|
|
||||||
def configure_get_context(self, simple_settings=None,
|
def configure_get_context(self, simple_settings=None,
|
||||||
input_file_templates=True):
|
input_file_templates=True,
|
||||||
|
output_file_templates=True):
|
||||||
"""
|
"""
|
||||||
Returns the full context dict, for rendering the configure
|
Returns the full context dict, for rendering the configure
|
||||||
page template.
|
page template.
|
||||||
|
@ -5305,10 +5447,27 @@ class MasterView(View):
|
||||||
context['input_file_options'] = file_options
|
context['input_file_options'] = file_options
|
||||||
context['input_file_option_dirs'] = file_option_dirs
|
context['input_file_option_dirs'] = file_option_dirs
|
||||||
|
|
||||||
|
# add settings for output file templates, if any
|
||||||
|
if output_file_templates and self.has_output_file_templates:
|
||||||
|
settings = {}
|
||||||
|
file_options = {}
|
||||||
|
file_option_dirs = {}
|
||||||
|
for template in self.normalize_output_file_templates(
|
||||||
|
include_file_options=True):
|
||||||
|
settings[template['setting_mode']] = template['mode']
|
||||||
|
settings[template['setting_file']] = template['file']
|
||||||
|
settings[template['setting_url']] = template['url']
|
||||||
|
file_options[template['key']] = template['file_options']
|
||||||
|
file_option_dirs[template['key']] = template['file_options_dir']
|
||||||
|
context['output_file_template_settings'] = settings
|
||||||
|
context['output_file_options'] = file_options
|
||||||
|
context['output_file_option_dirs'] = file_option_dirs
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def configure_gather_settings(self, data, simple_settings=None,
|
def configure_gather_settings(self, data, simple_settings=None,
|
||||||
input_file_templates=True):
|
input_file_templates=True,
|
||||||
|
output_file_templates=True):
|
||||||
settings = []
|
settings = []
|
||||||
|
|
||||||
# maybe collect "simple" settings
|
# maybe collect "simple" settings
|
||||||
|
@ -5354,10 +5513,30 @@ class MasterView(View):
|
||||||
settings.append({'name': template['setting_url'],
|
settings.append({'name': template['setting_url'],
|
||||||
'value': data.get(template['setting_url'])})
|
'value': data.get(template['setting_url'])})
|
||||||
|
|
||||||
|
# maybe also collect output file template settings
|
||||||
|
if output_file_templates and self.has_output_file_templates:
|
||||||
|
for template in self.normalize_output_file_templates():
|
||||||
|
|
||||||
|
# mode
|
||||||
|
settings.append({'name': template['setting_mode'],
|
||||||
|
'value': data.get(template['setting_mode'])})
|
||||||
|
|
||||||
|
# file
|
||||||
|
value = data.get(template['setting_file'])
|
||||||
|
if value:
|
||||||
|
# nb. avoid saving if empty, so can remain "null"
|
||||||
|
settings.append({'name': template['setting_file'],
|
||||||
|
'value': value})
|
||||||
|
|
||||||
|
# url
|
||||||
|
settings.append({'name': template['setting_url'],
|
||||||
|
'value': data.get(template['setting_url'])})
|
||||||
|
|
||||||
return settings
|
return settings
|
||||||
|
|
||||||
def configure_remove_settings(self, simple_settings=None,
|
def configure_remove_settings(self, simple_settings=None,
|
||||||
input_file_templates=True):
|
input_file_templates=True,
|
||||||
|
output_file_templates=True):
|
||||||
app = self.get_rattail_app()
|
app = self.get_rattail_app()
|
||||||
model = self.model
|
model = self.model
|
||||||
names = []
|
names = []
|
||||||
|
@ -5376,6 +5555,14 @@ class MasterView(View):
|
||||||
template['setting_url'],
|
template['setting_url'],
|
||||||
])
|
])
|
||||||
|
|
||||||
|
if output_file_templates and self.has_output_file_templates:
|
||||||
|
for template in self.normalize_output_file_templates():
|
||||||
|
names.extend([
|
||||||
|
template['setting_mode'],
|
||||||
|
template['setting_file'],
|
||||||
|
template['setting_url'],
|
||||||
|
])
|
||||||
|
|
||||||
if names:
|
if names:
|
||||||
# nb. using thread-local session here; we do not use
|
# nb. using thread-local session here; we do not use
|
||||||
# self.Session b/c it may not point to Rattail
|
# self.Session b/c it may not point to Rattail
|
||||||
|
@ -5638,6 +5825,15 @@ class MasterView(View):
|
||||||
route_name='{}.download_input_file_template'.format(route_prefix),
|
route_name='{}.download_input_file_template'.format(route_prefix),
|
||||||
permission='{}.create'.format(permission_prefix))
|
permission='{}.create'.format(permission_prefix))
|
||||||
|
|
||||||
|
# download output file template
|
||||||
|
if cls.has_output_file_templates and cls.configurable:
|
||||||
|
config.add_route(f'{route_prefix}.download_output_file_template',
|
||||||
|
f'{url_prefix}/download-output-file-template')
|
||||||
|
config.add_view(cls, attr='download_output_file_template',
|
||||||
|
route_name=f'{route_prefix}.download_output_file_template',
|
||||||
|
# TODO: this is different from input file, should change?
|
||||||
|
permission=f'{permission_prefix}.configure')
|
||||||
|
|
||||||
# view
|
# view
|
||||||
if cls.viewable:
|
if cls.viewable:
|
||||||
cls._defaults_view(config)
|
cls._defaults_view(config)
|
||||||
|
|
Loading…
Reference in a new issue