From ca602ff8452247d1732b8067c42d4b5dc6a17cb8 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sun, 17 Jan 2021 12:08:33 -0600 Subject: [PATCH] Add feature to generate new features... at least that's the idea. guess we'll see where this goes --- setup.py | 1 + tailbone/templates/generate_feature.mako | 219 +++++++++++++++++++++++ tailbone/views/features.py | 116 ++++++++++++ 3 files changed, 336 insertions(+) create mode 100644 tailbone/templates/generate_feature.mako create mode 100644 tailbone/views/features.py diff --git a/setup.py b/setup.py index 4a7badf7..692c5c10 100644 --- a/setup.py +++ b/setup.py @@ -85,6 +85,7 @@ requires = [ 'ColanderAlchemy', # 0.3.3 'humanize', # 0.5.1 'Mako', # 0.6.2 + 'markdown', # 3.3.3 'openpyxl', # 2.4.7 'paginate', # 0.5.6 'paginate_sqlalchemy', # 0.2.0 diff --git a/tailbone/templates/generate_feature.mako b/tailbone/templates/generate_feature.mako new file mode 100644 index 00000000..658aab12 --- /dev/null +++ b/tailbone/templates/generate_feature.mako @@ -0,0 +1,219 @@ +## -*- coding: utf-8; -*- +<%inherit file="/page.mako" /> + +<%def name="title()">Generate Feature + +<%def name="content_title()"> + +<%def name="extra_styles()"> + ${parent.extra_styles()} + + + +<%def name="page_content()"> + + + + + + + + + + + + + + + + + +
+ ${h.form(request.current_route_url(), ref='new-table-form')} + ${h.csrf_token(request)} + ${h.hidden('feature_type', value='new-table')} + ${h.hidden('app_prefix', **{'v-model': 'app.app_prefix'})} + ${h.hidden('app_cap_prefix', **{'v-model': 'app.app_cap_prefix'})} + +
+
+
+

New Table

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + {{ new_table.versioned }} + + + +
+
+
+ + ${h.end_form()} +
+ +
+ ${h.form(request.current_route_url(), ref='new-report-form')} + ${h.csrf_token(request)} + ${h.hidden('feature_type', value='new-report')} + ${h.hidden('app_prefix', **{'v-model': 'app.app_prefix'})} + ${h.hidden('app_cap_prefix', **{'v-model': 'app.app_cap_prefix'})} + +
+
+
+

New Report

+
+
+
+ + + + + + + + + +
+
+
+ + ${h.end_form()} +
+ +
+
+ + +
+ +
+
+

+ Please follow these instructions carefully. +

+
+
+
${rendered_result or ""|n}
+
+
+ + + +<%def name="modify_this_page_vars()"> + ${parent.modify_this_page_vars()} + + + + +${parent.body()} diff --git a/tailbone/views/features.py b/tailbone/views/features.py new file mode 100644 index 00000000..f2919fbc --- /dev/null +++ b/tailbone/views/features.py @@ -0,0 +1,116 @@ +# -*- coding: utf-8; -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2021 Lance Edgar +# +# This file is part of Rattail. +# +# Rattail is free software: you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# Rattail. If not, see . +# +################################################################################ +""" +Feature views +""" + +from __future__ import unicode_literals, absolute_import + +import six +import colander +import markdown + +from tailbone import forms +from tailbone.views import View + + +class GenerateFeatureView(View): + """ + View for generating new feature source code + """ + + def __init__(self, request): + super(GenerateFeatureView, self).__init__(request) + self.handler = self.get_handler() + + def get_handler(self): + app = self.get_rattail_app() + handler = app.get_feature_handler() + return handler + + def __call__(self): + use_buefy = self.get_use_buefy() + + schema = self.handler.make_schema() + app_form = forms.Form(schema=schema, request=self.request, + use_buefy=use_buefy) + for key, value in six.iteritems(self.handler.get_defaults()): + app_form.set_default(key, value) + + feature_forms = {} + for feature in self.handler.iter_features(): + schema = feature.make_schema() + form = forms.Form(schema=schema, request=self.request, + use_buefy=use_buefy) + for key, value in six.iteritems(feature.get_defaults()): + form.set_default(key, value) + feature_forms[feature.feature_key] = form + + result = rendered_result = None + feature_type = 'new-table' + if self.request.method == 'POST': + if app_form.validate(newstyle=True): + + feature_type = self.request.POST['feature_type'] + feature = self.handler.get_feature(feature_type) + if not feature: + raise ValueError("Unknown feature type: {}".format(feature_type)) + + feature_form = feature_forms[feature.feature_key] + if feature_form.validate(newstyle=True): + context = dict(app_form.validated) + context.update(feature_form.validated) + result = self.handler.do_generate(feature, **context) + rendered_result = self.render_result(result) + + context = { + 'index_title': "Generate Feature", + 'handler': self.handler, + 'use_buefy': use_buefy, + 'app_form': app_form, + 'feature_type': feature_type, + 'feature_forms': feature_forms, + 'result': result, + 'rendered_result': rendered_result, + } + + return context + + def render_result(self, result): + return markdown.markdown(result, extensions=['fenced_code', + 'codehilite']) + + @classmethod + def defaults(cls, config): + + # generate feature + config.add_tailbone_permission('common', 'common.generate_feature', + "Generate new feature source code") + config.add_route('generate_feature', '/generate-feature') + config.add_view(cls, route_name='generate_feature', + permission='common.generate_feature', + renderer='/generate_feature.mako') + + +def includeme(config): + GenerateFeatureView.defaults(config)