Initial commit, re-branded from first attempt..
This commit is contained in:
		
						commit
						7058ebf75e
					
				
					 17 changed files with 871 additions and 0 deletions
				
			
		
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| messkit.egg-info/ | ||||
							
								
								
									
										5
									
								
								README.rst
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								README.rst
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| 
 | ||||
| messkit | ||||
| ======= | ||||
| 
 | ||||
| Hopefully some kind of generic data manipulation thingy, we'll see... | ||||
							
								
								
									
										27
									
								
								messkit/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								messkit/__init__.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 <http://www.gnu.org/licenses/>. | ||||
| # | ||||
| ###################################################################### | ||||
| """ | ||||
| messkit | ||||
| """ | ||||
| 
 | ||||
| from ._version import __version__ | ||||
							
								
								
									
										3
									
								
								messkit/_version.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								messkit/_version.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| # -*- coding: utf-8; -*- | ||||
| 
 | ||||
| __version__ = '0.1.0' | ||||
							
								
								
									
										35
									
								
								messkit/appsettings.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								messkit/appsettings.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 <http://www.gnu.org/licenses/>. | ||||
| # | ||||
| ###################################################################### | ||||
| """ | ||||
| messkit app settings | ||||
| """ | ||||
| 
 | ||||
| # bring in some common settings from rattail | ||||
| from rattail.settings import ( | ||||
| 
 | ||||
|     # (General) | ||||
|     rattail_app_title, | ||||
| 
 | ||||
|     # Mail | ||||
|     rattail_mail_record_attempts, | ||||
| ) | ||||
							
								
								
									
										249
									
								
								messkit/commands.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								messkit/commands.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 <http://www.gnu.org/licenses/>. | ||||
| # | ||||
| ###################################################################### | ||||
| """ | ||||
| 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) | ||||
							
								
								
									
										51
									
								
								messkit/config.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								messkit/config.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 <http://www.gnu.org/licenses/>. | ||||
| # | ||||
| ###################################################################### | ||||
| """ | ||||
| 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) | ||||
							
								
								
									
										0
									
								
								messkit/db/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								messkit/db/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										32
									
								
								messkit/db/model.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								messkit/db/model.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 <http://www.gnu.org/licenses/>. | ||||
| # | ||||
| ###################################################################### | ||||
| """ | ||||
| messkit Data Model | ||||
| """ | ||||
| 
 | ||||
| from rattail.db.model import * | ||||
| 
 | ||||
| try: | ||||
|     from poser.db.model import * | ||||
| except ImportError: | ||||
|     pass | ||||
							
								
								
									
										0
									
								
								messkit/web/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								messkit/web/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										54
									
								
								messkit/web/app.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								messkit/web/app.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 <http://www.gnu.org/licenses/>. | ||||
| # | ||||
| ###################################################################### | ||||
| """ | ||||
| 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() | ||||
							
								
								
									
										140
									
								
								messkit/web/menus.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								messkit/web/menus.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 <http://www.gnu.org/licenses/>. | ||||
| # | ||||
| ###################################################################### | ||||
| """ | ||||
| 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 | ||||
							
								
								
									
										30
									
								
								messkit/web/static/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								messkit/web/static/__init__.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 <http://www.gnu.org/licenses/>. | ||||
| # | ||||
| ###################################################################### | ||||
| """ | ||||
| messkit static assets | ||||
| """ | ||||
| 
 | ||||
| 
 | ||||
| def includeme(config): | ||||
|     config.include('tailbone.static') | ||||
|     config.add_static_view('messkit', 'messkit.web:static', cache_max_age=3600) | ||||
							
								
								
									
										37
									
								
								messkit/web/subscribers.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								messkit/web/subscribers.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 <http://www.gnu.org/licenses/>. | ||||
| # | ||||
| ###################################################################### | ||||
| """ | ||||
| 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') | ||||
							
								
								
									
										49
									
								
								messkit/web/views/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								messkit/web/views/__init__.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 <http://www.gnu.org/licenses/>. | ||||
| # | ||||
| ###################################################################### | ||||
| """ | ||||
| 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') | ||||
							
								
								
									
										39
									
								
								messkit/web/views/common.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								messkit/web/views/common.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 <http://www.gnu.org/licenses/>. | ||||
| # | ||||
| ###################################################################### | ||||
| """ | ||||
| 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) | ||||
							
								
								
									
										119
									
								
								setup.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								setup.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 <http://www.gnu.org/licenses/>. | ||||
| # | ||||
| ###################################################################### | ||||
| """ | ||||
| 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', | ||||
|         ], | ||||
|     }, | ||||
| ) | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lance Edgar
						Lance Edgar