From bd19d7c2312f60923a16172a12093547164c9071 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sun, 6 Sep 2020 12:27:02 -0500 Subject: [PATCH] Add view for generating new project from template this was copied as-is from titeship --- tailbone/templates/generate_project.mako | 9 ++ tailbone/views/projects.py | 176 +++++++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 tailbone/templates/generate_project.mako create mode 100644 tailbone/views/projects.py diff --git a/tailbone/templates/generate_project.mako b/tailbone/templates/generate_project.mako new file mode 100644 index 00000000..9ae13d59 --- /dev/null +++ b/tailbone/templates/generate_project.mako @@ -0,0 +1,9 @@ +## -*- coding: utf-8; -*- +<%inherit file="/form.mako" /> + +<%def name="title()">Generate Project + +<%def name="content_title()"> + + +${parent.body()} diff --git a/tailbone/views/projects.py b/tailbone/views/projects.py new file mode 100644 index 00000000..8bf9e7e8 --- /dev/null +++ b/tailbone/views/projects.py @@ -0,0 +1,176 @@ +# -*- coding: utf-8; -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2020 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 . +# +################################################################################ +""" +Project views +""" + +from __future__ import unicode_literals, absolute_import + +import os +import zipfile +# from collections import OrderedDict + +import colander + +from tailbone import forms +from tailbone.views import View + + +class GenerateProject(colander.MappingSchema): + """ + Base schema for the "generate project" form + """ + name = colander.SchemaNode(colander.String()) + + slug = colander.SchemaNode(colander.String()) + + organization = colander.SchemaNode(colander.String()) + + python_project_name = colander.SchemaNode(colander.String()) + + python_name = colander.SchemaNode(colander.String()) + + has_db = colander.SchemaNode(colander.Boolean()) + + extends_db = colander.SchemaNode(colander.Boolean()) + + has_batch_schema = colander.SchemaNode(colander.Boolean()) + + has_web = colander.SchemaNode(colander.Boolean()) + + has_web_api = colander.SchemaNode(colander.Boolean()) + + has_datasync = colander.SchemaNode(colander.Boolean()) + + # has_filemon = colander.SchemaNode(colander.Boolean()) + + # has_tempmon = colander.SchemaNode(colander.Boolean()) + + # has_bouncer = colander.SchemaNode(colander.Boolean()) + + integrates_catapult = colander.SchemaNode(colander.Boolean()) + + integrates_corepos = colander.SchemaNode(colander.Boolean()) + + # integrates_instacart = colander.SchemaNode(colander.Boolean()) + + integrates_locsms = colander.SchemaNode(colander.Boolean()) + + # integrates_mailchimp = colander.SchemaNode(colander.Boolean()) + + uses_fabric = colander.SchemaNode(colander.Boolean()) + + +class GenerateProjectView(View): + """ + View for generating new project source code + """ + + def __init__(self, request): + super(GenerateProjectView, self).__init__(request) + self.handler = self.get_handler() + + def get_handler(self): + from rattail.projects.handler import RattailProjectHandler + return RattailProjectHandler(self.rattail_config) + + def __call__(self): + use_buefy = self.get_use_buefy() + + # choices = OrderedDict([ + # ('has_db', {'prompt': "Does project need its own Rattail DB?", + # 'type': 'bool'}), + # ]) + + form = forms.Form(schema=GenerateProject(), + request=self.request, use_buefy=use_buefy) + form.submit_label = "Generate Project" + form.auto_disable = False + form.auto_disable_save = False + if form.validate(newstyle=True): + zipped = self.generate_project(form) + return self.file_response(zipped) + # self.request.session.flash("New project was generated: {}".format(form.validated['name'])) + # return self.redirect(self.request.current_route_url()) + + form.set_label('python_name', "Python Package Name") + form.set_label('has_db', "Has Rattail DB") + form.set_label('extends_db', "Extends Rattail DB Schema") + form.set_label('has_batch_schema', "Uses Rattail Batch Schema") + form.set_label('has_web', "Has Tailbone Web App") + form.set_label('has_web_api', "Has Tailbone Web API") + form.set_label('has_datasync', "Has DataSync Service") + # form.set_label('has_filemon', "Has FileMon Service") + # form.set_label('has_tempmon', "Has TempMon Service") + # form.set_label('has_bouncer', "Has Bouncer Service") + form.set_label('integrates_catapult', "Integrates w/ Catapult") + form.set_label('integrates_corepos', "Integrates w/ CORE-POS") + # form.set_label('integrates_instacart', "Integrates w/ Instacart") + form.set_label('integrates_locsms', "Integrates w/ LOC SMS") + # form.set_label('integrates_mailchimp', "Integrates w/ Mailchimp") + + # TODO! + form.set_default('name', 'Okay-Then') + form.set_default('slug', 'okay-then') + form.set_default('organization', 'Acme') + form.set_default('python_project_name', 'Acme-Okay-Then') + form.set_default('python_name', 'okay_then') + form.set_default('has_db', True) + form.set_default('has_web', True) + + return { + 'index_title': "Generate Project", + 'handler': self.handler, + # 'choices': choices, + 'form': form, + 'use_buefy': use_buefy, + } + + def generate_project(self, form): + options = form.validated + slug = options['slug'] + path = self.handler.generate_project(slug, options) + + zipped = '{}.zip'.format(path) + with zipfile.ZipFile(zipped, 'w', zipfile.ZIP_DEFLATED) as z: + self.zipdir(z, path, slug) + return zipped + + def zipdir(self, zipf, path, slug): + for root, dirs, files in os.walk(path): + relative_root = os.path.join(slug, root[len(path)+1:]) + for fname in files: + zipf.write(os.path.join(root, fname), + arcname=os.path.join(relative_root, fname)) + + @classmethod + def defaults(cls, config): + config.add_tailbone_permission('common', 'common.generate_project', + "Generate new project source code") + config.add_route('generate_project', '/generate-project') + config.add_view(cls, route_name='generate_project', + renderer='/generate_project.mako') + + +def includeme(config): + GenerateProjectView.defaults(config)