diff --git a/CHANGELOG.md b/CHANGELOG.md index 78f5e5d..67d5a23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,23 +5,6 @@ All notable changes to rattail will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## v0.2.4 (2024-11-24) - -### Fix - -- update project links, kallithea -> forgejo -- avoid deprecated base class for config extension -- just use upstream `main()` for webapi -- update menu config per wuttaweb -- update config for default app model -- remove unused alembic script - -## v0.2.3 (2024-07-01) - -### Fix - -- use rattail function to create top-level command - ## v0.2.2 (2024-06-30) ### Fix diff --git a/README.md b/README.rst similarity index 57% rename from README.md rename to README.rst index 6792c08..a7f9721 100644 --- a/README.md +++ b/README.rst @@ -1,9 +1,11 @@ -# Rattail Demo +Rattail Demo +============ -This project serves as a working demo, to illustrate various concepts -of the Rattail software framework. See the [Rattail -Wiki](https://rattailproject.org/moin/) for more info. +This project serves as a working demo, to illustrate various concepts of the +Rattail software framework. See the `Rattail Wiki`_ for more info. Note that it *can be* usable as a starting point for your own project(s), should you need one. But probably the Rattail Tutorial is a better one. + +.. _`Rattail Wiki`: https://rattailproject.org/moin/ diff --git a/pyproject.toml b/pyproject.toml index dbc3511..089efa8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,9 +6,9 @@ build-backend = "hatchling.build" [project] name = "rattail-demo" -version = "0.2.4" +version = "0.2.2" description = "Rattail Software Demo" -readme = "README.md" +readme = "README.rst" authors = [{name = "Lance Edgar", email = "lance@edbob.org"}] classifiers = [ "Development Status :: 3 - Alpha", @@ -51,8 +51,8 @@ rattail-demo = "rattail_demo.config:DemoConfigExtension" [project.urls] Homepage = "https://demo.rattailproject.org" -Repository = "https://forgejo.wuttaproject.org/rattail/rattail-demo" -Changelog = "https://forgejo.wuttaproject.org/rattail/rattail-demo/src/branch/master/CHANGELOG.md" +Repository = "https://kallithea.rattailproject.org/rattail-project/rattail-demo" +Changelog = "https://kallithea.rattailproject.org/rattail-project/rattail-demo/files/master/CHANGELOG.md" [tool.commitizen] diff --git a/rattail_demo/commands.py b/rattail_demo/commands.py index d408b22..30cc967 100644 --- a/rattail_demo/commands.py +++ b/rattail_demo/commands.py @@ -11,7 +11,7 @@ import shutil import typer from typing_extensions import Annotated -from rattail.commands.typer import (make_typer, typer_get_runas_user, +from rattail.commands.typer import (typer_callback, typer_get_runas_user, importer_command, file_exporter_command) from rattail.commands.importing import ImportCommandHandler from rattail.commands.purging import run_purge @@ -19,9 +19,9 @@ from rattail.commands.purging import run_purge log = logging.getLogger(__name__) -# nb. this is the top-level command -rattail_demo_typer = make_typer( - name='rattail_demo', +# nb. this is the top-level command for titeship +rattail_demo_typer = typer.Typer( + callback=typer_callback, help="Rattail Demo (custom Rattail system)" ) diff --git a/rattail_demo/config.py b/rattail_demo/config.py index 6a427da..dc66ba5 100644 --- a/rattail_demo/config.py +++ b/rattail_demo/config.py @@ -3,10 +3,10 @@ Rattail Demo config extension """ -from wuttjamaican.conf import WuttaConfigExtension +from rattail.config import ConfigExtension -class DemoConfigExtension(WuttaConfigExtension): +class DemoConfigExtension(ConfigExtension): """ Rattail Demo config extension """ @@ -17,13 +17,11 @@ class DemoConfigExtension(WuttaConfigExtension): config.setdefault('rattail', 'app_package', 'rattail_demo') # tell rattail where our stuff lives - config.setdefault('rattail', 'model_spec', 'rattail_demo.db.model') + config.setdefault('rattail', 'model', 'rattail_demo.db.model') config.setdefault('rattail.trainwreck', 'model', 'rattail.trainwreck.db.model.defaults') + config.setdefault('tailbone.menus', 'handler', 'rattail_demo.web.menus:DemoMenuHandler') config.setdefault('tailbone.static_libcache.module', 'rattail_demo.web.static') - # menus - config.setdefault('rattail.web.menus.handler_spec', 'rattail_demo.web.menus:DemoMenuHandler') - # default app handlers config.setdefault('rattail', 'products.handler', 'rattail_corepos.products:CoreProductsHandler') diff --git a/rattail_demo/db/alembic/env.py b/rattail_demo/db/alembic/env.py new file mode 100644 index 0000000..5a9183c --- /dev/null +++ b/rattail_demo/db/alembic/env.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8; mode: python; -*- +""" +Alembic environment script +""" + +from alembic import context +from sqlalchemy.orm import configure_mappers + +from rattail.config import make_config +from rattail.db.util import get_default_engine +from rattail.db.continuum import configure_versioning + + +# this is the Alembic Config object, which provides +# access to the values within the .ini file in use. +alembic_config = context.config + +# use same config file for Rattail +rattail_config = make_config(alembic_config.config_file_name, usedb=False, versioning=False) + +# configure Continuum..this is trickier than we want but it works.. +configure_versioning(rattail_config, force=True) +from rattail_demo.db import model +configure_mappers() + +# needed for 'autogenerate' support +target_metadata = model.Base.metadata + + +def run_migrations_offline(): + """Run migrations in 'offline' mode. + + This configures the context with just a URL + and not an Engine, though an Engine is acceptable + here as well. By skipping the Engine creation + we don't even need a DBAPI to be available. + + Calls to context.execute() here emit the given string to the + script output. + + """ + engine = get_default_engine(rattail_config) + context.configure( + url=engine.url, + target_metadata=target_metadata) + + with context.begin_transaction(): + context.run_migrations() + + +def run_migrations_online(): + """Run migrations in 'online' mode. + + In this scenario we need to create an Engine + and associate a connection with the context. + + """ + engine = get_default_engine(rattail_config) + connection = engine.connect() + context.configure( + connection=connection, + target_metadata=target_metadata) + + try: + with context.begin_transaction(): + context.run_migrations() + finally: + connection.close() + + +if context.is_offline_mode(): + run_migrations_offline() +else: + run_migrations_online() diff --git a/rattail_demo/web/menus.py b/rattail_demo/web/menus.py index 2927157..9468903 100644 --- a/rattail_demo/web/menus.py +++ b/rattail_demo/web/menus.py @@ -7,7 +7,7 @@ from tailbone import menus as base from tailbone_corepos.menus import make_corepos_menu -class DemoMenuHandler(base.TailboneMenuHandler): +class DemoMenuHandler(base.MenuHandler): """ Demo menu handler """ @@ -62,7 +62,7 @@ class DemoMenuHandler(base.TailboneMenuHandler): }, { 'title': "Source Code", - 'url': 'https://forgejo.wuttaproject.org/rattail/rattail-demo', + 'url': 'https://kallithea.rattailproject.org/rattail-project/rattail-demo', 'target': '_blank', }, { diff --git a/rattail_demo/web/views/upgrades.py b/rattail_demo/web/views/upgrades.py index af722f4..8035303 100644 --- a/rattail_demo/web/views/upgrades.py +++ b/rattail_demo/web/views/upgrades.py @@ -15,8 +15,8 @@ class UpgradeView(base.UpgradeView): projects.update({ 'rattail_demo': { - 'commit_url': 'https://forgejo.wuttaproject.org/rattail/rattail-demo/compare/{{old_version}}...{{new_version}}', - 'release_url': 'https://forgejo.wuttaproject.org/rattail/rattail-demo/src/tag/v{{new_version}}/CHANGELOG.md', + 'commit_url': 'https://kallithea.rattailproject.org/rattail-project/rattail-demo/changelog/{new_version}/?size=10', + 'release_url': 'https://kallithea.rattailproject.org/rattail-project/rattail-demo/files/{new_version}/CHANGES.rst', }, }) diff --git a/rattail_demo/web/webapi.py b/rattail_demo/web/webapi.py index 40ad5b1..591b2e6 100644 --- a/rattail_demo/web/webapi.py +++ b/rattail_demo/web/webapi.py @@ -3,11 +3,50 @@ Rattail Demo web API """ -from tailbone import webapi as base +from __future__ import unicode_literals, absolute_import + +from pyramid.config import Configurator +from pyramid.authentication import SessionAuthenticationPolicy + +from tailbone import app +from tailbone.auth import TailboneAuthorizationPolicy def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ - return base.main(global_config, **settings) + # make config objects + rattail_config = app.make_rattail_config(settings) + pyramid_config = Configurator(settings=settings, root_factory=app.Root) + + # configure user authorization / authentication + pyramid_config.set_authorization_policy(TailboneAuthorizationPolicy()) + pyramid_config.set_authentication_policy(SessionAuthenticationPolicy()) + + # always require CSRF token protection + pyramid_config.set_default_csrf_options(require_csrf=True, token='_csrf', header='X-XSRF-TOKEN') + + # bring in some Pyramid goodies + pyramid_config.include('tailbone.beaker') + pyramid_config.include('pyramid_tm') + pyramid_config.include('cornice') + + # bring in the pyramid_retry logic, if available + # TODO: pretty soon we can require this package, hopefully.. + try: + import pyramid_retry + except ImportError: + pass + else: + pyramid_config.include('pyramid_retry') + + # add some permissions magic + pyramid_config.add_directive('add_tailbone_permission_group', 'tailbone.auth.add_permission_group') + pyramid_config.add_directive('add_tailbone_permission', 'tailbone.auth.add_permission') + + # bring in some Tailbone + pyramid_config.include('tailbone.subscribers') + pyramid_config.include('tailbone.api') + + return pyramid_config.make_wsgi_app() diff --git a/tasks.py b/tasks.py deleted file mode 100644 index d296ec9..0000000 --- a/tasks.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*- coding: utf-8; -*- -""" -Tasks for rattail-demo -""" - -import os -import shutil - -from invoke import task - - -@task -def release(c): - """ - Release a new version of 'rattail-demo' - """ - if os.path.exists('dist'): - shutil.rmtree('dist') - if os.path.exists('rattail_demo.egg-info'): - shutil.rmtree('rattail_demo.egg-info') - - c.run('python -m build --sdist') - c.run('twine upload dist/*')