diff --git a/.gitignore b/.gitignore index 5d6335c..7893476 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ +*~ +*.pyc +dist/ tailbone_woocommerce.egg-info/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 220b0d8..fa1effb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to tailbone-woocommerce 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.0 (2024-06-11) + +### Feat + +- switch from setup.cfg to pyproject.toml + hatchling + ## [0.1.0] - 2021-01-21 ### Changed - Initial release. diff --git a/README.md b/README.md new file mode 100644 index 0000000..873af83 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ + +# tailbone-woocommerce + +Rattail is a retail software framework, released under the GNU General +Public License. + +This package contains software interfaces for the +[WooCommerce](https://woocommerce.com/) system. + +Please see the [Rattail Project](https://rattailproject.org/) for more +information. diff --git a/README.rst b/README.rst deleted file mode 100644 index d768e06..0000000 --- a/README.rst +++ /dev/null @@ -1,14 +0,0 @@ - -tailbone-woocommerce -==================== - -Rattail is a retail software framework, released under the GNU General Public -License. - -This package contains software interfaces for the `WooCommerce`_ system. - -.. _WooCommerce: https://woocommerce.com/ - -Please see the `Rattail Project`_ for more information. - -.. _`Rattail Project`: https://rattailproject.org/ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..100dd71 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,42 @@ + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + + +[project] +name = "tailbone-woocommerce" +version = "0.2.0" +description = "Tailbone integration for WooCommerce" +readme = "README.md" +authors = [{name = "Lance Edgar", email = "lance@edbob.org"}] +license = {text = "GNU GPL v3+"} +classifiers = [ + "Development Status :: 4 - Beta", + "Environment :: Web Environment", + "Intended Audience :: Developers", + "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", + "Natural Language :: English", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Topic :: Office/Business", + "Topic :: Software Development :: Libraries :: Python Modules", +] +dependencies = [ + "rattail", + "rattail-woocommerce", + "Tailbone", +] + + +[project.urls] +Homepage = "https://rattailproject.org" +Repository = "https://kallithea.rattailproject.org/rattail-project/tailbone-woocommerce" +Changelog = "https://kallithea.rattailproject.org/rattail-project/tailbone-woocommerce/files/master/CHANGELOG.md" + + +[tool.commitizen] +version_provider = "pep621" +tag_format = "v$version" +update_changelog_on_bump = true diff --git a/setup.py b/setup.py deleted file mode 100644 index ffea671..0000000 --- a/setup.py +++ /dev/null @@ -1,95 +0,0 @@ -# -*- 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 . -# -################################################################################ - -import os -from setuptools import setup, find_packages - - -here = os.path.abspath(os.path.dirname(__file__)) -exec(open(os.path.join(here, 'tailbone_woocommerce', '_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 - - 'rattail', # 0.9.138 - 'rattail-woocommerce', # 0.1.0 - 'Tailbone', # 0.8.103 -] - - -setup( - name = "tailbone-woocommerce", - version = __version__, - author = "Lance Edgar", - author_email = "lance@edbob.org", - url = "https://rattailproject.org/", - license = "GNU GPL v3", - description = "Tailbone integration for WooCommerce", - long_description = README, - - classifiers = [ - 'Development Status :: 4 - Beta', - 'Environment :: Web Environment', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)', - 'Natural Language :: English', - 'Operating System :: OS Independent', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - 'Topic :: Office/Business', - 'Topic :: Software Development :: Libraries :: Python Modules', - ], - - install_requires = requires, - packages = find_packages(), - include_package_data = True, - zip_safe = False, -) diff --git a/tailbone_woocommerce/_version.py b/tailbone_woocommerce/_version.py index e41b669..5c5048a 100644 --- a/tailbone_woocommerce/_version.py +++ b/tailbone_woocommerce/_version.py @@ -1,3 +1,6 @@ # -*- coding: utf-8; -*- -__version__ = '0.1.0' +from importlib.metadata import version + + +__version__ = version('tailbone-woocommerce') diff --git a/tailbone_woocommerce/templates/products/view.mako b/tailbone_woocommerce/templates/products/view.mako deleted file mode 100644 index 29c92d4..0000000 --- a/tailbone_woocommerce/templates/products/view.mako +++ /dev/null @@ -1,52 +0,0 @@ -## -*- coding: utf-8; -*- -<%inherit file="tailbone:templates/products/view.mako" /> - -<%def name="object_helpers()"> - ${parent.object_helpers()} - ${self.render_xref_helper()} - - -<%def name="render_xref_store_button()"> - - View in WooCommerce Store - - - -<%def name="render_xref_admin_button()"> - - View in WooCommerce Admin - - - -<%def name="render_xref_helper()"> -
-

Cross-Reference

-
- ${self.render_xref_store_button()} - ${self.render_xref_admin_button()} -
-
- - -<%def name="extra_main_fields(form)"> - ${parent.extra_main_fields(form)} - ${self.extra_main_fields_woocommerce(form)} - - -<%def name="extra_main_fields_woocommerce(form)"> - ${form.render_field_readonly('woocommerce_id')} - - -${parent.body()} diff --git a/tailbone_woocommerce/views/__init__.py b/tailbone_woocommerce/views/__init__.py index e69de29..6be242f 100644 --- a/tailbone_woocommerce/views/__init__.py +++ b/tailbone_woocommerce/views/__init__.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8; -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2022 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 . +# +################################################################################ +""" +Views w/ WooCommerce integration +""" + + +def includeme(config): + config.include('tailbone_woocommerce.views.products') diff --git a/tailbone_woocommerce/views/products.py b/tailbone_woocommerce/views/products.py index 545d22f..f38525e 100644 --- a/tailbone_woocommerce/views/products.py +++ b/tailbone_woocommerce/views/products.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2021 Lance Edgar +# Copyright © 2010-2022 Lance Edgar # # This file is part of Rattail. # @@ -28,72 +28,68 @@ from sqlalchemy import orm from rattail_woocommerce.config import woocommerce_admin_product_url -from tailbone.views import products as base +from webhelpers2.html import tags + +from tailbone.views import ViewSupplement -class ProductView(base.ProductsView): +class ProductViewSupplement(ViewSupplement): """ - Master view for the Product class. + Product view supplement for WooCommerce integration """ + route_prefix = 'products' + labels = { 'woocommerce_id': "WooCommerce ID", } - @property - def form_fields(self): - fields = super(ProductView, self).form_fields - return self.woocommerce_add_form_fields(fields) - - def woocommerce_add_form_fields(self, fields): - fields.extend([ - 'woocommerce_id', - ]) - return fields - - def query(self, session): - query = super(ProductView, self).query(session) - return self.woocommerce_modify_query(query) - - def woocommerce_modify_query(self, query): + def get_grid_query(self, query): model = self.model return query.outerjoin(model.WooProductExtension) def configure_grid(self, g): - super(ProductView, self).configure_grid(g) - self.woocommerce_configure_grid(g) - - def woocommerce_configure_grid(self, g): model = self.model g.set_filter('woocommerce_id', model.WooProductExtension.woocommerce_id) def configure_form(self, f): - super(ProductView, self).configure_form(f) - self.woocommerce_configure_form(f) - - def woocommerce_configure_form(self, f): - f.set_required('woocommerce_id', False) - if self.creating: - f.remove('woocommerce_id') + if not self.master.creating: + f.append('woocommerce_id') def get_version_child_classes(self): - classes = super(ProductView, self).get_version_child_classes() - return self.woocommerce_add_version_classes(classes) - - def woocommerce_add_version_classes(self, classes): model = self.model - classes.extend([ - model.WooProductExtension, - ]) - return classes + return [model.WooProductExtension] - def template_kwargs_view(self, **kwargs): - kwargs = super(ProductView, self).template_kwargs_view(**kwargs) - return self.woocommerce_template_kwargs_view(**kwargs) + def get_panel_fields_main(self, product): + return ['woocommerce_id'] + + def get_xref_buttons(self, product): + buttons = [] + + woo_cached = self.get_woo_cached_product(product) + if woo_cached: + buttons.append({'url': woo_cached.permalink, + 'text': "View in WooCommerce Store"}) + + woo_id = woo_cached.id if woo_cached else product.woocommerce_id + if woo_id: + url = woocommerce_admin_product_url(self.rattail_config, woo_id) + if url: + buttons.append({'url': url, + 'text': "View in WooCommerce Admin"}) + + return buttons + + def get_xref_links(self, product): + if product.woocommerce_cache_product: + url = self.request.route_url('woocommerce.products.view', + uuid=product.woocommerce_cache_product.uuid) + return [tags.link_to("View WooCommerce Product", url)] def get_woo_cached_product(self, product): """ Tries to identify the WooCacheProduct for the given Rattail Product. """ + model = self.model woo_cached = None if product.woocommerce_cache_product: @@ -102,7 +98,6 @@ class ProductView(base.ProductsView): elif product.item_id: # try to find matching woo product, even though not linked - model = self.rattail_config.get_model() try: woo_cached = self.Session.query(model.WooCacheProduct)\ .filter(model.WooCacheProduct.sku == product.item_id)\ @@ -112,45 +107,6 @@ class ProductView(base.ProductsView): return woo_cached - def woocommerce_template_kwargs_view(self, **kwargs): - product = kwargs['instance'] - woo_cached = self.get_woo_cached_product(product) - - # WooCommerce Store URL - store_url = why_not = None - if woo_cached: - store_url = woo_cached.permalink - else: - why_not = "WooCommerce cache product not found" - kwargs['woocommerce_store_url'] = store_url - kwargs['woocommerce_store_why_no_url'] = why_not - - # WooCommerce Admin URL - admin_url = why_not = None - woo_id = woo_cached.id if woo_cached else product.woocommerce_id - if woo_id: - admin_url = woocommerce_admin_product_url(self.rattail_config, - woo_id) - if not admin_url: - why_not = "WooCommerce Admin URL is not configured" - else: - why_not = "Product is not known to exist in WooCommerce" - kwargs['woocommerce_admin_url'] = admin_url - kwargs['woocommerce_admin_why_no_url'] = why_not - - return kwargs - def includeme(config): - - # TODO: getting pretty tired of copy/pasting this extra config... - config.add_route('products.autocomplete', '/products/autocomplete') - config.add_view(base.ProductsAutocomplete, route_name='products.autocomplete', - renderer='json', permission='products.list') - - # TODO: getting pretty tired of copy/pasting this extra config... - config.add_route('products.print_labels', '/products/labels') - config.add_view(base.print_labels, route_name='products.print_labels', - renderer='json', permission='products.print_labels') - - ProductView.defaults(config) + ProductViewSupplement.defaults(config) diff --git a/tasks.py b/tasks.py index 469b737..a376936 100644 --- a/tasks.py +++ b/tasks.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2021 Lance Edgar +# Copyright © 2010-2024 Lance Edgar # # This file is part of Rattail. # @@ -30,15 +30,14 @@ import shutil from invoke import task -here = os.path.abspath(os.path.dirname(__file__)) -exec(open(os.path.join(here, 'tailbone_woocommerce', '_version.py')).read()) - - @task -def release(ctx): +def release(c): """ Release a new version of 'tailbone-woocommerce'. """ - shutil.rmtree('tailbone_woocommerce.egg-info') - ctx.run('python setup.py sdist --formats=gztar') - ctx.run('twine upload dist/tailbone-woocommerce-{}.tar.gz'.format(__version__)) + if os.path.exists('dist'): + shutil.rmtree('dist') + if os.path.exists('tailbone_woocommerce.egg-info'): + shutil.rmtree('tailbone_woocommerce.egg-info') + c.run('python -m build --sdist') + c.run('twine upload dist/*')