From 7058ebf75edfe5e5807826bbc221b31cabb683b4 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Wed, 2 Mar 2022 16:41:28 -0600 Subject: [PATCH] Initial commit, re-branded from first attempt.. --- .gitignore | 1 + README.rst | 5 + messkit/__init__.py | 27 ++++ messkit/_version.py | 3 + messkit/appsettings.py | 35 +++++ messkit/commands.py | 249 +++++++++++++++++++++++++++++++++ messkit/config.py | 51 +++++++ messkit/db/__init__.py | 0 messkit/db/model.py | 32 +++++ messkit/web/__init__.py | 0 messkit/web/app.py | 54 +++++++ messkit/web/menus.py | 140 ++++++++++++++++++ messkit/web/static/__init__.py | 30 ++++ messkit/web/subscribers.py | 37 +++++ messkit/web/views/__init__.py | 49 +++++++ messkit/web/views/common.py | 39 ++++++ setup.py | 119 ++++++++++++++++ 17 files changed, 871 insertions(+) create mode 100644 .gitignore create mode 100644 README.rst create mode 100644 messkit/__init__.py create mode 100644 messkit/_version.py create mode 100644 messkit/appsettings.py create mode 100644 messkit/commands.py create mode 100644 messkit/config.py create mode 100644 messkit/db/__init__.py create mode 100644 messkit/db/model.py create mode 100644 messkit/web/__init__.py create mode 100644 messkit/web/app.py create mode 100644 messkit/web/menus.py create mode 100644 messkit/web/static/__init__.py create mode 100644 messkit/web/subscribers.py create mode 100644 messkit/web/views/__init__.py create mode 100644 messkit/web/views/common.py create mode 100644 setup.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..645e03d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +messkit.egg-info/ diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..a0cc7f1 --- /dev/null +++ b/README.rst @@ -0,0 +1,5 @@ + +messkit +======= + +Hopefully some kind of generic data manipulation thingy, we'll see... diff --git a/messkit/__init__.py b/messkit/__init__.py new file mode 100644 index 0000000..1d25760 --- /dev/null +++ b/messkit/__init__.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8; -*- +###################################################################### +# +# messkit -- Generic-ish Data Utility App +# Copyright © 2022 Lance Edgar +# +# This file is part of messkit. +# +# messkit 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. +# +# messkit 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 messkit. If not, see . +# +###################################################################### +""" +messkit +""" + +from ._version import __version__ diff --git a/messkit/_version.py b/messkit/_version.py new file mode 100644 index 0000000..e41b669 --- /dev/null +++ b/messkit/_version.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8; -*- + +__version__ = '0.1.0' diff --git a/messkit/appsettings.py b/messkit/appsettings.py new file mode 100644 index 0000000..be51dda --- /dev/null +++ b/messkit/appsettings.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8; -*- +###################################################################### +# +# messkit -- Generic-ish Data Utility App +# Copyright © 2022 Lance Edgar +# +# This file is part of messkit. +# +# messkit 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. +# +# messkit 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 messkit. If not, see . +# +###################################################################### +""" +messkit app settings +""" + +# bring in some common settings from rattail +from rattail.settings import ( + + # (General) + rattail_app_title, + + # Mail + rattail_mail_record_attempts, +) diff --git a/messkit/commands.py b/messkit/commands.py new file mode 100644 index 0000000..d667139 --- /dev/null +++ b/messkit/commands.py @@ -0,0 +1,249 @@ +# -*- coding: utf-8; -*- +###################################################################### +# +# messkit -- Generic-ish Data Utility App +# Copyright © 2022 Lance Edgar +# +# This file is part of messkit. +# +# messkit 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. +# +# messkit 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 messkit. If not, see . +# +###################################################################### +""" +messkit commands +""" + +import os +import sys +import subprocess + +import sqlalchemy as sa +from prompt_toolkit import prompt +from prompt_toolkit.styles import Style +from rich import print as rprint +from alembic.util.messaging import obfuscate_url_pw + +from rattail import commands + +from messkit import __version__ + + +def main(*args): + """ + Main entry point for messkit command system + """ + args = list(args or sys.argv[1:]) + cmd = Command() + cmd.run(*args) + + +class Command(commands.Command): + """ + Main command for messkit + """ + name = 'messkit' + version = __version__ + description = "messkit (Generic Data App)" + long_description = '' + + +class Install(commands.Subcommand): + """ + Install a messkit app + """ + name = 'install' + description = __doc__.strip() + + def run(self, args): + + rprint("\n\t[blue]Welcome to messkit![/blue]") + rprint("\n\tThis tool will install and configure a new app.") + rprint("\n\t[italic]NB. You should already have created a new database in PostgreSQL.[/italic]") + + # get appdir path + appdir = os.path.join(sys.prefix, 'app') + appdir = self.basic_prompt('appdir path', appdir) + + # appdir must not yet exist + if os.path.exists(appdir): + rprint("\n\t[bold red]appdir already exists:[/bold red] {}\n".format(appdir)) + sys.exit(1) + + # get db info + dbhost = self.basic_prompt('postgres host', 'localhost') + dbport = self.basic_prompt('postgres port', '5432') + dbname = self.basic_prompt('postgres db', 'messkit') + dbuser = self.basic_prompt('postgres user', 'rattail') + + # get db password + dbpass = None + while not dbpass: + dbpass = self.basic_prompt('postgres pass', is_password=True) + + # test db connection + rprint("\n\ttesting db connection... ", end='') + dburl = self.make_db_url(dbhost, dbport, dbname, dbuser, dbpass) + error = self.test_db_connection(dburl) + if error: + rprint("[bold red]cannot connect![/bold red] ..error was:") + rprint("\n{}".format(error)) + rprint("\n\t[bold yellow]aborting mission[/bold yellow]\n") + sys.exit(1) + rprint("[bold green]good[/bold green]") + + # make the appdir + self.app.make_appdir(appdir) + + # make config files + context = { + 'app_title': "messkit", + 'appdir': appdir, + 'db_url': dburl, + 'pyramid_egg': 'messkit', + 'beaker_key': 'messkit', + } + rattail_conf = self.app.make_config_file( + 'rattail-complete', os.path.join(appdir, 'rattail.conf'), + **context) + quiet_conf = self.app.make_config_file('quiet', appdir) + web_conf = self.app.make_config_file( + 'web-complete', os.path.join(appdir, 'web.conf'), + **context) + + rprint("\n\tappdir created at: [bold green]{}[/bold green]".format(appdir)) + + bindir = os.path.join(sys.prefix, 'bin') + + schema_installed = False + if self.basic_prompt("install db schema?", True, is_bool=True): + rprint() + + # install db schema + alembic = os.path.join(bindir, 'alembic') + cmd = [alembic, '-c', rattail_conf, 'upgrade', 'heads'] + subprocess.check_call(cmd) + schema_installed = True + + rprint("\n\tdb schema installed to: [bold green]{}[/bold green]".format( + obfuscate_url_pw(dburl))) + + if self.basic_prompt("create admin user?", True, is_bool=True): + + # get admin credentials + username = self.basic_prompt('admin username', 'admin') + password = None + while not password: + password = self.basic_prompt('admin password', is_password=True) + if password: + confirm = self.basic_prompt('confirm password', is_password=True) + if not confirm or confirm != password: + rprint("[bold yellow]passwords did not match[/bold yellow]") + password = None + + rprint() + + # make admin user + rattail = os.path.join(bindir, 'rattail') + cmd = [rattail, '-c', quiet_conf, 'make-user', '-A', username, + '--password', password] + subprocess.check_call(cmd) + + rprint("\n\tadmin user created: [bold green]{}[/bold green]".format( + username)) + + if self.basic_prompt("make poser dir?", True, is_bool=True): + rprint() + + poser_handler = self.app.get_poser_handler() + poserdir = poser_handler.make_poser_dir() + + rprint("\n\tposer dir created: [bold green]{}[/bold green]".format( + poserdir)) + + rprint("\n\t[bold green]initial setup is complete![/bold green]") + + if schema_installed: + rprint("\n\tyou can run the web app with this command:") + pserve = os.path.join(bindir, 'pserve') + rprint("\n\t[blue]{} --reload file+ini:{}[/blue]".format(pserve, web_conf)) + + rprint() + + def basic_prompt(self, info, default=None, is_password=False, is_bool=False): + + # message formatting styles + style = Style.from_dict({ + '': '', + 'bold': 'bold', + }) + + # build prompt message + message = [ + ('', '\n'), + ('class:bold', info), + ] + if default is not None: + if is_bool: + message.append(('', ' [{}]: '.format('Y' if default else 'N'))) + else: + message.append(('', ' [{}]: '.format(default))) + else: + message.append(('', ': ')) + + # prompt user for input + try: + text = prompt(message, style=style, is_password=is_password) + except (KeyboardInterrupt, EOFError): + rprint("\n\t[bold yellow]operation canceled by user[/bold yellow]\n", + file=self.stderr) + sys.exit(2) + + if is_bool: + if text == '': + return default + elif text.upper() == 'Y': + return True + elif text.upper() == 'N': + return False + rprint("\n\t[bold yellow]ambiguous, please try again[/bold yellow]\n") + return self.basic_prompt(info, default, is_bool=True) + + return text or default + + def make_db_url(self, dbhost, dbport, dbname, dbuser, dbpass): + try: + # newer style + from sqlalchemy.engine import URL + factory = URL.create + except ImportError: + # older style + from sqlalchemy.engine.url import URL + factory = URL + + return factory(drivername='postgresql+psycopg2', + username=dbuser, + password=dbpass, + host=dbhost, + port=dbport, + database=dbname) + + def test_db_connection(self, url): + engine = sa.create_engine(url) + + # check for random table; does not matter if it exists, we + # just need to test interaction and this is a neutral way + try: + engine.has_table('whatever') + except Exception as error: + return str(error) diff --git a/messkit/config.py b/messkit/config.py new file mode 100644 index 0000000..18f5f67 --- /dev/null +++ b/messkit/config.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8; -*- +###################################################################### +# +# messkit -- Generic-ish Data Utility App +# Copyright © 2022 Lance Edgar +# +# This file is part of messkit. +# +# messkit 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. +# +# messkit 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 messkit. If not, see . +# +###################################################################### +""" +Config extension for messkit +""" + +import os +import sys + +from rattail.config import ConfigExtension + + +class MesskitConfig(ConfigExtension): + """ + Rattail config extension for messkit + """ + key = 'messkit' + + def configure(self, config): + + # set some default config values + config.setdefault('rattail', 'app_title', "messkit") + config.setdefault('tailbone', 'menus', 'messkit.web.menus') + config.setdefault('rattail', 'model', 'messkit.db.model') + config.setdefault('rattail', 'settings', 'messkit.appsettings') + + # # always try to append poser to path + # # TODO: location of poser dir should come from config/app/handler? + # poser = os.path.join(sys.prefix, 'app', 'poser') + # if poser not in sys.path and os.path.isdir(poser): + # sys.path.append(poser) diff --git a/messkit/db/__init__.py b/messkit/db/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/messkit/db/model.py b/messkit/db/model.py new file mode 100644 index 0000000..8b30c99 --- /dev/null +++ b/messkit/db/model.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8; -*- +###################################################################### +# +# messkit -- Generic-ish Data Utility App +# Copyright © 2022 Lance Edgar +# +# This file is part of messkit. +# +# messkit 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. +# +# messkit 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 messkit. If not, see . +# +###################################################################### +""" +messkit Data Model +""" + +from rattail.db.model import * + +try: + from poser.db.model import * +except ImportError: + pass diff --git a/messkit/web/__init__.py b/messkit/web/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/messkit/web/app.py b/messkit/web/app.py new file mode 100644 index 0000000..27102d1 --- /dev/null +++ b/messkit/web/app.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8; -*- +###################################################################### +# +# messkit -- Generic-ish Data Utility App +# Copyright © 2022 Lance Edgar +# +# This file is part of messkit. +# +# messkit 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. +# +# messkit 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 messkit. If not, see . +# +###################################################################### +""" +messkit web app +""" + +from tailbone import app + + +def main(global_config, **settings): + """ + This function returns a Pyramid WSGI application. + """ + # prefer messkit templates over Tailbone + settings.setdefault('mako.directories', ['messkit.web:templates', + 'tailbone:templates',]) + + # for graceful handling of postgres restart + settings.setdefault('retry.attempts', 2) + + # make config objects + rattail_config = app.make_rattail_config(settings) + pyramid_config = app.make_pyramid_config(settings) + + # bring in the rest of messkit + pyramid_config.include('messkit.web.static') + pyramid_config.include('messkit.web.subscribers') + pyramid_config.include('messkit.web.views') + + # for graceful handling of postgres restart + pyramid_config.add_tween('tailbone.tweens.sqlerror_tween_factory', + under='pyramid_tm.tm_tween_factory') + + return pyramid_config.make_wsgi_app() diff --git a/messkit/web/menus.py b/messkit/web/menus.py new file mode 100644 index 0000000..c7c0b86 --- /dev/null +++ b/messkit/web/menus.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8; -*- +###################################################################### +# +# messkit -- Generic-ish Data Utility App +# Copyright © 2022 Lance Edgar +# +# This file is part of messkit. +# +# messkit 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. +# +# messkit 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 messkit. If not, see . +# +###################################################################### +""" +Web Menus +""" + + +def simple_menus(request): + url = request.route_url + + # reports_menu = { + # 'title': "Reports", + # 'type': 'menu', + # 'items': [ + # { + # 'title': "New Report", + # 'url': url('report_output.create'), + # 'perm': 'report_output.create', + # }, + # { + # 'title': "Generated Reports", + # 'url': url('report_output'), + # 'perm': 'report_output.list', + # }, + # { + # 'title': "Problem Reports", + # 'url': url('problem_reports'), + # 'perm': 'problem_reports.list', + # }, + # ], + # } + + # other_menu = { + # 'title': "Other", + # 'type': 'menu', + # 'items': [ + # { + # 'title': "Generate New Feature", + # 'url': url('generate_feature'), + # 'perm': 'common.generate_feature', + # }, + # { + # 'title': "Generate New Project", + # 'url': url('generate_project'), + # 'perm': 'common.generate_project', + # }, + # ], + # } + + admin_menu = { + 'title': "Admin", + 'type': 'menu', + 'items': [ + { + 'title': "Users", + 'url': url('users'), + 'perm': 'users.list', + }, + # { + # 'title': "User Events", + # 'url': url('userevents'), + # 'perm': 'userevents.list', + # }, + { + 'title': "Roles", + 'url': url('roles'), + 'perm': 'roles.list', + }, + {'type': 'sep'}, + { + 'title': "App Settings", + 'url': url('appsettings'), + 'perm': 'settings.list', + }, + { + 'title': "Email Settings", + 'url': url('emailprofiles'), + 'perm': 'emailprofiles.list', + }, + # { + # 'title': "Email Attempts", + # 'url': url('email_attempts'), + # 'perm': 'email_attempts.list', + # }, + { + 'title': "Raw Settings", + 'url': url('settings'), + 'perm': 'settings.list', + }, + {'type': 'sep'}, + # { + # 'title': "DataSync Changes", + # 'url': url('datasyncchanges'), + # 'perm': 'datasync_changes.list', + # }, + # { + # 'title': "Importing / Exporting", + # 'url': url('importing'), + # 'perm': 'importing.list', + # }, + { + 'title': "Tables", + 'url': url('tables'), + 'perm': 'tables.list', + }, + { + 'title': "messkit Upgrades", + 'url': url('upgrades'), + 'perm': 'upgrades.list', + }, + ], + } + + menus = [ + # reports_menu, + # other_menu, + admin_menu, + ] + + return menus diff --git a/messkit/web/static/__init__.py b/messkit/web/static/__init__.py new file mode 100644 index 0000000..21cf400 --- /dev/null +++ b/messkit/web/static/__init__.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8; -*- +###################################################################### +# +# messkit -- Generic-ish Data Utility App +# Copyright © 2022 Lance Edgar +# +# This file is part of messkit. +# +# messkit 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. +# +# messkit 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 messkit. If not, see . +# +###################################################################### +""" +messkit static assets +""" + + +def includeme(config): + config.include('tailbone.static') + config.add_static_view('messkit', 'messkit.web:static', cache_max_age=3600) diff --git a/messkit/web/subscribers.py b/messkit/web/subscribers.py new file mode 100644 index 0000000..9227248 --- /dev/null +++ b/messkit/web/subscribers.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8; -*- +###################################################################### +# +# messkit -- Generic-ish Data Utility App +# Copyright © 2022 Lance Edgar +# +# This file is part of messkit. +# +# messkit 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. +# +# messkit 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 messkit. If not, see . +# +###################################################################### +""" +Pyramid event subscribers +""" + +import messkit + + +def add_messkit_to_context(event): + renderer_globals = event + renderer_globals['messkit'] = messkit + + +def includeme(config): + config.include('tailbone.subscribers') + config.add_subscriber(add_messkit_to_context, 'pyramid.events.BeforeRender') diff --git a/messkit/web/views/__init__.py b/messkit/web/views/__init__.py new file mode 100644 index 0000000..5c2dca2 --- /dev/null +++ b/messkit/web/views/__init__.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8; -*- +###################################################################### +# +# messkit -- Generic-ish Data Utility App +# Copyright © 2022 Lance Edgar +# +# This file is part of messkit. +# +# messkit 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. +# +# messkit 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 messkit. If not, see . +# +###################################################################### +""" +messkit web views +""" + + +def includeme(config): + + # core + config.include('messkit.web.views.common') + config.include('tailbone.views.auth') + config.include('tailbone.views.menus') + # config.include('tailbone.views.importing') + config.include('tailbone.views.poser') + config.include('tailbone.views.progress') + + # config.include('tailbone.views.features') + + config.include('tailbone.views.reports') + + # main tables + config.include('tailbone.views.email') + config.include('tailbone.views.people') + config.include('tailbone.views.roles') + config.include('tailbone.views.settings') + config.include('tailbone.views.tables') + config.include('tailbone.views.upgrades') + config.include('tailbone.views.users') diff --git a/messkit/web/views/common.py b/messkit/web/views/common.py new file mode 100644 index 0000000..0d43306 --- /dev/null +++ b/messkit/web/views/common.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8; -*- +###################################################################### +# +# messkit -- Generic-ish Data Utility App +# Copyright © 2022 Lance Edgar +# +# This file is part of messkit. +# +# messkit 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. +# +# messkit 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 messkit. If not, see . +# +###################################################################### +""" +Common views +""" + +from tailbone.views import common as base + +import messkit + + +class CommonView(base.CommonView): + + project_title = "messkit" + project_version = messkit.__version__ + '+dev' + + +def includeme(config): + CommonView.defaults(config) diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..4c48960 --- /dev/null +++ b/setup.py @@ -0,0 +1,119 @@ +# -*- coding: utf-8; -*- +###################################################################### +# +# messkit -- Generic-ish Data Utility App +# Copyright © 2022 Lance Edgar +# +# This file is part of messkit. +# +# messkit 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. +# +# messkit 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 messkit. If not, see . +# +###################################################################### +""" +messkit setup script +""" + +import os +from setuptools import setup, find_packages + + +here = os.path.abspath(os.path.dirname(__file__)) +exec(open(os.path.join(here, 'messkit', '_version.py')).read()) +README = open(os.path.join(here, 'README.rst')).read() + + +requires = [ + # + # Version numbers within comments below have specific meanings. + # Basically the 'low' value is a "soft low," and 'high' a "soft high." + # In other words: + # + # If either a 'low' or 'high' value exists, the primary point to be + # made about the value is that it represents the most current (stable) + # version available for the package (assuming typical public access + # methods) whenever this project was started and/or documented. + # Therefore: + # + # If a 'low' version is present, you should know that attempts to use + # versions of the package significantly older than the 'low' version + # may not yield happy results. (A "hard" high limit may or may not be + # indicated by a true version requirement.) + # + # Similarly, if a 'high' version is present, and especially if this + # project has laid dormant for a while, you may need to refactor a bit + # when attempting to support a more recent version of the package. (A + # "hard" low limit should be indicated by a true version requirement + # when a 'high' version is present.) + # + # In any case, developers and other users are encouraged to play + # outside the lines with regard to these soft limits. If bugs are + # encountered then they should be filed as such. + # + # package # low high + + # TODO: user should get to choose which of these is needed? + 'mysql-connector-python', # 8.0.28 + 'psycopg2', # 2.9.3 + + 'prompt_toolkit', # 3.0.28 + 'rich', # 11.2.0 + 'Tailbone', # 0.8.206 +] + + +setup( + name = "messkit", + version = __version__, + author = "Lance Edgar", + author_email = "lance@edbob.org", + url = "https://rattailproject.org", + description = "Generic-ish Data Utility App", + long_description = README, + + classifiers = [ + 'Development Status :: 3 - Alpha', + 'Environment :: Console', + 'Environment :: Web Environment', + 'Framework :: Pyramid', + 'Intended Audience :: Developers', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3', + 'Topic :: Office/Business', + ], + + install_requires = requires, + packages = find_packages(), + include_package_data = True, + + entry_points = { + + 'rattail.config.extensions': [ + 'messkit = messkit.config:MesskitConfig', + ], + + 'console_scripts': [ + 'messkit = messkit.commands:main', + ], + + 'messkit.commands': [ + 'install = messkit.commands:Install', + ], + + 'paste.app_factory': [ + 'main = messkit.web.app:main', + ], + }, +)