Date: Fri, 31 May 2024 21:20:45 -0500
Subject: [PATCH 144/388] Escape all unsafe html for grid data
---
tailbone/grids/core.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/tailbone/grids/core.py b/tailbone/grids/core.py
index b428aaa6..91c3d1f5 100644
--- a/tailbone/grids/core.py
+++ b/tailbone/grids/core.py
@@ -1651,7 +1651,11 @@ class Grid(object):
value = self.obtain_value(rowobj, name)
if value is None:
value = ""
- row[name] = str(value)
+
+ # this value will ultimately be inserted into table
+ # cell a la so we must escape it
+ # here to be safe
+ row[name] = HTML.literal.escape(value)
# maybe add UUID for convenience
if 'uuid' not in self.columns:
From d05458c7fb48e040b046f74900b0ef24e02a5068 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Sat, 1 Jun 2024 13:40:50 -0500
Subject: [PATCH 145/388] Add speedbumps for delete, set preferred email/phone
in profile view
---
tailbone/templates/people/view_profile.mako | 264 +++++++++++++++---
.../themes/butterball/buefy-components.mako | 5 +-
2 files changed, 231 insertions(+), 38 deletions(-)
diff --git a/tailbone/templates/people/view_profile.mako b/tailbone/templates/people/view_profile.mako
index 0ca42cef..bf94b7fa 100644
--- a/tailbone/templates/people/view_profile.mako
+++ b/tailbone/templates/people/view_profile.mako
@@ -341,23 +341,21 @@
-
-
-
-
- {{ option.label }}
-
-
-
+
+
+
+ {{ option.label }}
+
+
+
-
-
-
-
+
+
@@ -439,6 +437,72 @@
${b}-table>
+ <${b}-modal has-modal-card
+ % if request.use_oruga:
+ v-model:active="deletePhoneShowDialog"
+ % else:
+ :active.sync="deletePhoneShowDialog"
+ % endif
+ >
+
+
+
+
+
+ Really delete this phone number?
+ {{ deletePhoneNumber }}
+
+
+
+
+ ${b}-modal>
+
+ <${b}-modal has-modal-card
+ % if request.use_oruga:
+ v-model:active="preferPhoneShowDialog"
+ % else:
+ :active.sync="preferPhoneShowDialog"
+ % endif
+ >
+
+
+
+
+
+ Really make this the preferred phone number?
+ {{ preferPhoneNumber }}
+
+
+
+
+ ${b}-modal>
+
@@ -477,24 +541,21 @@
-
-
-
-
- {{ option.label }}
-
-
-
-
-
-
-
-
+
+
+
+ {{ option.label }}
+
+
+
+
+
+ <${b}-modal has-modal-card
+ % if request.use_oruga:
+ v-model:active="deleteEmailShowDialog"
+ % else:
+ :active.sync="deleteEmailShowDialog"
+ % endif
+ >
+
+
+
+
+
+ Really delete this email address?
+ {{ deleteEmailAddress }}
+
+
+
+
+ ${b}-modal>
+
+ <${b}-modal has-modal-card
+ % if request.use_oruga:
+ v-model:active="preferEmailShowDialog"
+ % else:
+ :active.sync="preferEmailShowDialog"
+ % endif
+ >
+
+
+
+
+
+ Really make this the preferred email address?
+ {{ preferEmailAddress }}
+
+
+
+
+ ${b}-modal>
+
@@ -1657,6 +1784,16 @@
editPhonePreferred: false,
editPhoneSaving: false,
+ deletePhoneShowDialog: false,
+ deletePhoneUUID: null,
+ deletePhoneNumber: null,
+ deletePhoneSaving: false,
+
+ preferPhoneShowDialog: false,
+ preferPhoneUUID: null,
+ preferPhoneNumber: null,
+ preferPhoneSaving: false,
+
editEmailShowDialog: false,
editEmailUUID: null,
editEmailType: null,
@@ -1664,6 +1801,17 @@
editEmailPreferred: null,
editEmailInvalid: false,
editEmailSaving: false,
+
+ deleteEmailShowDialog: false,
+ deleteEmailUUID: null,
+ deleteEmailAddress: null,
+ deleteEmailSaving: false,
+
+ preferEmailShowDialog: false,
+ preferEmailUUID: null,
+ preferEmailAddress: null,
+ preferEmailSaving: false,
+
% endif
}
@@ -1843,26 +1991,47 @@
},
deletePhoneInit(phone) {
+ this.deletePhoneUUID = phone.uuid
+ this.deletePhoneNumber = phone.number
+ this.deletePhoneShowDialog = true
+ },
+
+ deletePhoneSave() {
+ this.deletePhoneSaving = true
let url = '${url('people.profile_delete_phone', uuid=person.uuid)}'
let params = {
- phone_uuid: phone.uuid,
+ phone_uuid: this.deletePhoneUUID,
}
-
this.simplePOST(url, params, response => {
this.$emit('profile-changed', response.data)
this.refreshTab()
+ this.deletePhoneShowDialog = false
+ this.deletePhoneSaving = false
+ }, response => {
+ this.deletePhoneSaving = false
})
},
preferPhoneInit(phone) {
+ this.preferPhoneUUID = phone.uuid
+ this.preferPhoneNumber = phone.number
+ this.preferPhoneShowDialog = true
+ },
+
+ preferPhoneSave() {
+ this.preferPhoneSaving = true
let url = '${url('people.profile_set_preferred_phone', uuid=person.uuid)}'
let params = {
- phone_uuid: phone.uuid,
+ phone_uuid: this.preferPhoneUUID,
}
this.simplePOST(url, params, response => {
this.$emit('profile-changed', response.data)
this.refreshTab()
+ this.preferPhoneShowDialog = false
+ this.preferPhoneSaving = false
+ }, response => {
+ this.preferPhoneSaving = false
})
},
@@ -1917,26 +2086,47 @@
},
deleteEmailInit(email) {
+ this.deleteEmailUUID = email.uuid
+ this.deleteEmailAddress = email.address
+ this.deleteEmailShowDialog = true
+ },
+
+ deleteEmailSave() {
+ this.deleteEmailSaving = true
let url = '${url('people.profile_delete_email', uuid=person.uuid)}'
let params = {
- email_uuid: email.uuid,
+ email_uuid: this.deleteEmailUUID,
}
-
this.simplePOST(url, params, response => {
this.$emit('profile-changed', response.data)
this.refreshTab()
+ this.deleteEmailShowDialog = false
+ this.deleteEmailSaving = false
+ }, response => {
+ this.deleteEmailSaving = false
})
},
preferEmailInit(email) {
+ this.preferEmailUUID = email.uuid
+ this.preferEmailAddress = email.address
+ this.preferEmailShowDialog = true
+ },
+
+ preferEmailSave() {
+ this.preferEmailSaving = true
let url = '${url('people.profile_set_preferred_email', uuid=person.uuid)}'
let params = {
- email_uuid: email.uuid,
+ email_uuid: this.preferEmailUUID,
}
this.simplePOST(url, params, response => {
this.$emit('profile-changed', response.data)
this.refreshTab()
+ this.preferEmailShowDialog = false
+ this.preferEmailSaving = false
+ }, response => {
+ this.preferEmailSaving = false
})
},
diff --git a/tailbone/templates/themes/butterball/buefy-components.mako b/tailbone/templates/themes/butterball/buefy-components.mako
index b11e34ea..7553729b 100644
--- a/tailbone/templates/themes/butterball/buefy-components.mako
+++ b/tailbone/templates/themes/butterball/buefy-components.mako
@@ -365,7 +365,10 @@
// TODO: this does not always work right?
this.$refs.input.$el.querySelector('textarea').focus()
} else {
- this.$refs.input.$el.querySelector('input').focus()
+ // TODO: pretty sure we can rely on the focus()
+ // here, but not sure why we weren't already doing that?
+ //this.$refs.input.$el.querySelector('input').focus()
+ this.$refs.input.focus()
}
},
},
From 6b1c313efd30c7b83ad2fb2384e61a1fa8719879 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Sat, 1 Jun 2024 14:23:35 -0500
Subject: [PATCH 146/388] Fix file upload widget for oruga
---
tailbone/forms/core.py | 4 ++--
tailbone/forms/widgets.py | 17 +++++++++++++++++
tailbone/templates/deform/file_upload.pt | 24 ++++++++++++++++++++++--
3 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/tailbone/forms/core.py b/tailbone/forms/core.py
index 7601fa26..6918a9cc 100644
--- a/tailbone/forms/core.py
+++ b/tailbone/forms/core.py
@@ -52,7 +52,7 @@ from tailbone.util import raw_datetime, get_form_data, render_markdown
from tailbone.forms import types
from tailbone.forms.widgets import (ReadonlyWidget, PlainDateWidget,
JQueryDateWidget, JQueryTimeWidget,
- MultiFileUploadWidget)
+ FileUploadWidget, MultiFileUploadWidget)
from tailbone.exceptions import TailboneJSONFieldError
@@ -646,7 +646,7 @@ class Form(object):
self.set_widget(key, dfwidget.TextAreaWidget(cols=80, rows=8))
elif type_ == 'file':
tmpstore = SessionFileUploadTempStore(self.request)
- kw = {'widget': dfwidget.FileUploadWidget(tmpstore),
+ kw = {'widget': FileUploadWidget(tmpstore, request=self.request),
'title': self.get_label(key)}
if 'required' in kwargs and not kwargs['required']:
kw['missing'] = colander.null
diff --git a/tailbone/forms/widgets.py b/tailbone/forms/widgets.py
index c0bb0b4d..2923b7ec 100644
--- a/tailbone/forms/widgets.py
+++ b/tailbone/forms/widgets.py
@@ -337,6 +337,23 @@ class JQueryAutocompleteWidget(dfwidget.AutocompleteInputWidget):
return field.renderer(template, **tmpl_values)
+class FileUploadWidget(dfwidget.FileUploadWidget):
+ """
+ Widget to handle file upload. Must override to add ``use_oruga``
+ to field template context.
+ """
+
+ def __init__(self, *args, **kwargs):
+ self.request = kwargs.pop('request')
+ super().__init__(*args, **kwargs)
+
+ def get_template_values(self, field, cstruct, kw):
+ values = super().get_template_values(field, cstruct, kw)
+ if self.request:
+ values['use_oruga'] = self.request.use_oruga
+ return values
+
+
class MultiFileUploadWidget(dfwidget.FileUploadWidget):
"""
Widget to handle multiple (arbitrary number) of file uploads.
diff --git a/tailbone/templates/deform/file_upload.pt b/tailbone/templates/deform/file_upload.pt
index e165fdfa..af78eaf9 100644
--- a/tailbone/templates/deform/file_upload.pt
+++ b/tailbone/templates/deform/file_upload.pt
@@ -2,11 +2,14 @@
+ field_name field_name|field.name;
+ use_oruga use_oruga;">
From 43db60bbee167d43032251d856ef77259f1afa23 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Sat, 1 Jun 2024 14:26:17 -0500
Subject: [PATCH 147/388] Update changelog
---
CHANGES.rst | 18 ++++++++++++++++++
tailbone/_version.py | 2 +-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/CHANGES.rst b/CHANGES.rst
index 3f2b16aa..08b01d5e 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -5,6 +5,24 @@ CHANGELOG
Unreleased
----------
+0.10.7 (2024-06-01)
+-------------------
+
+* Add setting to allow decimal quantities for receiving.
+
+* Log error if registry has no rattail config.
+
+* Add column filters for import/export main grid.
+
+* Fix overflow when instance header title is too long (butterball).
+
+* Escape all unsafe html for grid data.
+
+* Add speedbumps for delete, set preferred email/phone in profile view.
+
+* Fix file upload widget for oruga.
+
+
0.10.6 (2024-05-29)
-------------------
diff --git a/tailbone/_version.py b/tailbone/_version.py
index 711da994..21ae87f2 100644
--- a/tailbone/_version.py
+++ b/tailbone/_version.py
@@ -1,3 +1,3 @@
# -*- coding: utf-8; -*-
-__version__ = '0.10.6'
+__version__ = '0.10.7'
From 77eeb63b62fb806fdb0b2c5017bc2b81a52228d8 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Sat, 1 Jun 2024 17:46:35 -0500
Subject: [PATCH 148/388] Add styling for checked grid rows, per
oruga/butterball
---
tailbone/templates/grids/complete.mako | 9 ++++---
.../templates/themes/butterball/base.mako | 25 +++++++++++++++++++
2 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/tailbone/templates/grids/complete.mako b/tailbone/templates/grids/complete.mako
index a54cc127..e200cdc3 100644
--- a/tailbone/templates/grids/complete.mako
+++ b/tailbone/templates/grids/complete.mako
@@ -44,6 +44,9 @@
:data="visibleData"
:loading="loading"
:row-class="getRowClass"
+ % if request.use_oruga:
+ tr-checked-class="is-checked"
+ % endif
% if request.rattail_config.getbool('tailbone', 'sticky_headers'):
sticky-header
@@ -58,9 +61,9 @@
% else:
:checked-rows.sync="checkedRows"
% endif
- % if grid.clicking_row_checks_box:
- @click="rowClick"
- % endif
+ % if grid.clicking_row_checks_box:
+ @click="rowClick"
+ % endif
% endif
% if grid.check_handler:
diff --git a/tailbone/templates/themes/butterball/base.mako b/tailbone/templates/themes/butterball/base.mako
index ba0f64ba..7a27c0ed 100644
--- a/tailbone/templates/themes/butterball/base.mako
+++ b/tailbone/templates/themes/butterball/base.mako
@@ -242,6 +242,31 @@
white-space: nowrap;
}
+ /**************************************************
+ * grid rows which are "checked" (selected)
+ **************************************************/
+
+ /* TODO: this references some color values, whereas it would be preferable
+ * to refer to some sort of "state" instead, color of which was
+ * configurable. b/c these are just the default Buefy theme colors. */
+
+ tr.is-checked {
+ background-color: #7957d5;
+ color: white;
+ }
+
+ tr.is-checked:hover {
+ color: #363636;
+ }
+
+ tr.is-checked a {
+ color: white;
+ }
+
+ tr.is-checked:hover a {
+ color: #7957d5;
+ }
+
/* ****************************** */
/* forms */
/* ****************************** */
From 1bf28eb2862876f9baacd01774c33754c33cfb12 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Sat, 1 Jun 2024 19:07:07 -0500
Subject: [PATCH 149/388] Fix product view template for oruga/butterball
---
tailbone/forms/core.py | 4 +++
tailbone/templates/products/view.mako | 35 +++++++++++++++------------
tailbone/views/products.py | 9 ++++---
3 files changed, 29 insertions(+), 19 deletions(-)
diff --git a/tailbone/forms/core.py b/tailbone/forms/core.py
index 6918a9cc..d6303bb1 100644
--- a/tailbone/forms/core.py
+++ b/tailbone/forms/core.py
@@ -1157,6 +1157,10 @@ class Form(object):
return HTML.tag('div', class_='field-wrapper {}'.format(field_name), c=contents)
+ # nb. for some reason we must wrap once more for oruga,
+ # otherwise it splits up the field?!
+ value = HTML.tag('span', c=[value])
+
# oruga uses
return HTML.tag('o-field', label=label, c=[value], **{':horizontal': 'true'})
diff --git a/tailbone/templates/products/view.mako b/tailbone/templates/products/view.mako
index c4da08ba..bd4afc7f 100644
--- a/tailbone/templates/products/view.mako
+++ b/tailbone/templates/products/view.mako
@@ -4,6 +4,9 @@
<%def name="extra_styles()">
${parent.extra_styles()}
+ ${base_meta.extra_styles()}
%def>
<%def name="make_feedback_component()">
From da6ccf4425b778d80d682626ba4b5ffb5470f036 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Tue, 4 Jun 2024 17:16:57 -0500
Subject: [PATCH 171/388] Fix product lookup component, per butterball
---
tailbone/templates/products/lookup.mako | 32 +++++++++++++++++++------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/tailbone/templates/products/lookup.mako b/tailbone/templates/products/lookup.mako
index 48206de1..7997eb7d 100644
--- a/tailbone/templates/products/lookup.mako
+++ b/tailbone/templates/products/lookup.mako
@@ -56,9 +56,7 @@
-
+ ref="searchTermInput" />
-
- View
+ % if not request.use_oruga:
+ class="grid-action"
+ % endif
+ target="_blank">
+ % if request.use_oruga:
+
+
+ View
+
+ % else:
+
+ View
+ % endif
${b}-table-column>
@@ -236,6 +243,7 @@
lookupShowDialog: false,
searchTerm: null,
+ searchTermInputElement: null,
searchTermLastUsed: null,
searchProductKey: true,
@@ -250,6 +258,16 @@
searchResultSelected: null,
}
},
+
+ mounted() {
+ this.searchTermInputElement = this.$refs.searchTermInput.$el.querySelector('input')
+ this.searchTermInputElement.addEventListener('keydown', this.searchTermInputKeydown)
+ },
+
+ beforeDestroy() {
+ this.searchTermInputElement.removeEventListener('keydown', this.searchTermInputKeydown)
+ },
+
methods: {
focus() {
From 22aceb4d67e184b5a878364489e1858b5eabc668 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Tue, 4 Jun 2024 17:28:07 -0500
Subject: [PATCH 172/388] Include butterball theme by default for new apps
but it is not "the" default yet..
---
tailbone/config.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tailbone/config.py b/tailbone/config.py
index 9326a3cb..ee906149 100644
--- a/tailbone/config.py
+++ b/tailbone/config.py
@@ -49,7 +49,7 @@ class ConfigExtension(BaseExtension):
configure_session(config, Session)
# provide default theme selection
- config.setdefault('tailbone', 'themes.keys', 'default, falafel')
+ config.setdefault('tailbone', 'themes.keys', 'default, butterball')
config.setdefault('tailbone', 'themes.expose_picker', 'true')
From c1892734711401c5bd4cb6c0bc92b72ef1c6870c Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Tue, 4 Jun 2024 21:12:44 -0500
Subject: [PATCH 173/388] Update changelog
---
CHANGES.rst | 18 ++++++++++++++++++
tailbone/_version.py | 2 +-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/CHANGES.rst b/CHANGES.rst
index a3be0af8..c6809592 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -5,6 +5,24 @@ CHANGELOG
Unreleased
----------
+0.10.12 (2024-06-04)
+--------------------
+
+* Require pyramid 2.x; remove 1.x-style auth policies.
+
+* Remove version cap for deform.
+
+* Set explicit referrer when changing app theme.
+
+* Add ```` component shim.
+
+* Include extra styles from ``base_meta`` template for butterball.
+
+* Fix product lookup component, per butterball.
+
+* Include butterball theme by default for new apps.
+
+
0.10.11 (2024-06-03)
--------------------
diff --git a/tailbone/_version.py b/tailbone/_version.py
index d24c3b8e..2af82b6d 100644
--- a/tailbone/_version.py
+++ b/tailbone/_version.py
@@ -1,3 +1,3 @@
# -*- coding: utf-8; -*-
-__version__ = '0.10.11'
+__version__ = '0.10.12'
From 1afc70e788a650ccb4e29d984b008bd307fa6211 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Tue, 4 Jun 2024 22:11:51 -0500
Subject: [PATCH 174/388] Remove old/unused scaffold for use with `pcreate`
we now have a better Generate Project feature
---
setup.cfg | 3 ---
tailbone/scaffolds.py | 45 -------------------------------------------
2 files changed, 48 deletions(-)
delete mode 100644 tailbone/scaffolds.py
diff --git a/setup.cfg b/setup.cfg
index 5f46bc5c..6184c7c2 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -98,6 +98,3 @@ rattail.cleaners =
rattail.config.extensions =
tailbone = tailbone.config:ConfigExtension
-
-pyramid.scaffold =
- rattail = tailbone.scaffolds:RattailTemplate
diff --git a/tailbone/scaffolds.py b/tailbone/scaffolds.py
deleted file mode 100644
index 10bf9640..00000000
--- a/tailbone/scaffolds.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# -*- coding: utf-8 -*-
-################################################################################
-#
-# Rattail -- Retail Software Framework
-# Copyright © 2010-2017 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 .
-#
-################################################################################
-"""
-Pyramid scaffold templates
-"""
-
-from __future__ import unicode_literals, absolute_import
-
-from rattail.files import resource_path
-from rattail.util import prettify
-
-from pyramid.scaffolds import PyramidTemplate
-
-
-class RattailTemplate(PyramidTemplate):
- _template_dir = resource_path('rattail:data/project')
- summary = "Starter project based on Rattail / Tailbone"
-
- def pre(self, command, output_dir, vars):
- """
- Adds some more variables to the template context.
- """
- vars['project_title'] = prettify(vars['project'])
- vars['package_title'] = vars['package'].capitalize()
- return super(RattailTemplate, self).pre(command, output_dir, vars)
From d9911cf23d5864a772d83777c0605c7040382120 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Wed, 5 Jun 2024 23:04:45 -0500
Subject: [PATCH 175/388] Add 'fanstatic' support for sake of libcache assets
for vue.js and oruga etc.
we don't want to include files in tailbone since they are apt to
change over time, and probably need to use different versions for
different apps etc.
much may need to change yet, this is a first attempt but so far it
seems quite promising
---
setup.cfg | 1 +
tailbone/app.py | 2 ++
tailbone/util.py | 21 +++++++++++++++++++++
3 files changed, 24 insertions(+)
diff --git a/setup.cfg b/setup.cfg
index 6184c7c2..50c057f9 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -57,6 +57,7 @@ install_requires =
pyramid_beaker
pyramid_deform
pyramid_exclog
+ pyramid_fanstatic
pyramid_mako
pyramid_retry
pyramid_tm
diff --git a/tailbone/app.py b/tailbone/app.py
index 5ca4c5c9..b0160bd3 100644
--- a/tailbone/app.py
+++ b/tailbone/app.py
@@ -129,6 +129,7 @@ def make_pyramid_config(settings, configure_csrf=True):
# we want the new themes feature!
establish_theme(settings)
+ settings.setdefault('fanstatic.versioning', 'true')
settings.setdefault('pyramid_deform.template_search_path', 'tailbone:templates/deform')
config = Configurator(settings=settings, root_factory=Root)
@@ -147,6 +148,7 @@ def make_pyramid_config(settings, configure_csrf=True):
# Bring in some Pyramid goodies.
config.include('tailbone.beaker')
config.include('pyramid_deform')
+ config.include('pyramid_fanstatic')
config.include('pyramid_mako')
config.include('pyramid_tm')
diff --git a/tailbone/util.py b/tailbone/util.py
index 7d838541..9a993176 100644
--- a/tailbone/util.py
+++ b/tailbone/util.py
@@ -25,6 +25,7 @@ Utilities
"""
import datetime
+import importlib
import logging
import warnings
@@ -195,6 +196,12 @@ def get_liburl(request, key, fallback=True):
version = get_libver(request, key)
+ static = config.get('tailbone.static_libcache.module')
+ if static:
+ static = importlib.import_module(static)
+ needed = request.environ['fanstatic.needed']
+ liburl = needed.library_url(static.libcache) + '/'
+
if key == 'buefy':
return 'https://unpkg.com/buefy@{}/dist/buefy.min.js'.format(version)
@@ -211,24 +218,38 @@ def get_liburl(request, key, fallback=True):
return 'https://use.fontawesome.com/releases/v{}/js/all.js'.format(version)
elif key == 'bb_vue':
+ if static and hasattr(static, 'bb_vue_js'):
+ return liburl + static.bb_vue_js.relpath
return f'https://unpkg.com/vue@{version}/dist/vue.esm-browser.prod.js'
elif key == 'bb_oruga':
+ if static and hasattr(static, 'bb_oruga_js'):
+ return liburl + static.bb_oruga_js.relpath
return f'https://unpkg.com/@oruga-ui/oruga-next@{version}/dist/oruga.mjs'
elif key == 'bb_oruga_bulma':
+ if static and hasattr(static, 'bb_oruga_bulma_js'):
+ return liburl + static.bb_oruga_bulma_js.relpath
return f'https://unpkg.com/@oruga-ui/theme-bulma@{version}/dist/bulma.mjs'
elif key == 'bb_oruga_bulma_css':
+ if static and hasattr(static, 'bb_oruga_bulma_css'):
+ return liburl + static.bb_oruga_bulma_css.relpath
return f'https://unpkg.com/@oruga-ui/theme-bulma@{version}/dist/bulma.css'
elif key == 'bb_fontawesome_svg_core':
+ if static and hasattr(static, 'bb_fontawesome_svg_core_js'):
+ return liburl + static.bb_fontawesome_svg_core_js.relpath
return f'https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-svg-core@{version}/+esm'
elif key == 'bb_free_solid_svg_icons':
+ if static and hasattr(static, 'bb_free_solid_svg_icons_js'):
+ return liburl + static.bb_free_solid_svg_icons_js.relpath
return f'https://cdn.jsdelivr.net/npm/@fortawesome/free-solid-svg-icons@{version}/+esm'
elif key == 'bb_vue_fontawesome':
+ if static and hasattr(static, 'bb_vue_fontawesome_js'):
+ return liburl + static.bb_vue_fontawesome_js.relpath
return f'https://cdn.jsdelivr.net/npm/@fortawesome/vue-fontawesome@{version}/+esm'
From ce290f5f8b400ba0dc2fa5ec51a145d74adf7a8b Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Thu, 6 Jun 2024 15:30:48 -0500
Subject: [PATCH 176/388] Update changelog
---
CHANGES.rst | 8 ++++++++
tailbone/_version.py | 2 +-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/CHANGES.rst b/CHANGES.rst
index c6809592..cc04273e 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -5,6 +5,14 @@ CHANGELOG
Unreleased
----------
+0.10.13 (2024-06-06)
+--------------------
+
+* Remove old/unused scaffold for use with ``pcreate``.
+
+* Add 'fanstatic' support for sake of libcache assets.
+
+
0.10.12 (2024-06-04)
--------------------
diff --git a/tailbone/_version.py b/tailbone/_version.py
index 2af82b6d..1daf8e32 100644
--- a/tailbone/_version.py
+++ b/tailbone/_version.py
@@ -1,3 +1,3 @@
# -*- coding: utf-8; -*-
-__version__ = '0.10.12'
+__version__ = '0.10.13'
From f6f2a53a0c7a542ead7bb5dc9a8414e6057ed774 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Thu, 6 Jun 2024 20:33:36 -0500
Subject: [PATCH 177/388] Use `pkg_resources` to determine package versions
and always add `app_version` to global template context. this was for
sake of "About This App v1.0.0" style links in custom page footers
---
tailbone/subscribers.py | 5 +++++
tailbone/views/common.py | 5 ++---
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/tailbone/subscribers.py b/tailbone/subscribers.py
index 42d3cab7..59ef64dc 100644
--- a/tailbone/subscribers.py
+++ b/tailbone/subscribers.py
@@ -28,6 +28,7 @@ import six
import json
import datetime
import logging
+import pkg_resources
import warnings
from collections import OrderedDict
@@ -168,7 +169,11 @@ def before_render(event):
renderer_globals = event
renderer_globals['rattail_app'] = request.rattail_config.get_app()
+
renderer_globals['app_title'] = request.rattail_config.app_title()
+ pkg = rattail_config.app_package()
+ renderer_globals['app_version'] = pkg_resources.get_distribution(pkg).version
+
renderer_globals['h'] = helpers
renderer_globals['url'] = request.route_url
renderer_globals['rattail'] = rattail
diff --git a/tailbone/views/common.py b/tailbone/views/common.py
index 266561fd..58346f3b 100644
--- a/tailbone/views/common.py
+++ b/tailbone/views/common.py
@@ -24,8 +24,8 @@
Various common views
"""
-import importlib
import os
+import pkg_resources
from collections import OrderedDict
from rattail.batch import consume_batch_id
@@ -108,8 +108,7 @@ class CommonView(View):
return self.project_version
pkg = self.rattail_config.app_package()
- mod = importlib.import_module(pkg)
- return mod.__version__
+ return pkg_resources.get_distribution(pkg).version
def exception(self):
"""
From 0491d8517c59379bf6e272ba1dc93245e6c82930 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Thu, 6 Jun 2024 23:04:47 -0500
Subject: [PATCH 178/388] Update changelog
---
CHANGES.rst | 6 ++++++
tailbone/_version.py | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGES.rst b/CHANGES.rst
index cc04273e..178135e4 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -5,6 +5,12 @@ CHANGELOG
Unreleased
----------
+0.10.14 (2024-06-06)
+--------------------
+
+* Use ``pkg_resources`` to determine package versions.
+
+
0.10.13 (2024-06-06)
--------------------
diff --git a/tailbone/_version.py b/tailbone/_version.py
index 1daf8e32..7a64f8d0 100644
--- a/tailbone/_version.py
+++ b/tailbone/_version.py
@@ -1,3 +1,3 @@
# -*- coding: utf-8; -*-
-__version__ = '0.10.13'
+__version__ = '0.10.14'
From 94d7836321b34d9892f3deace05c7d369c07808f Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Thu, 6 Jun 2024 23:05:40 -0500
Subject: [PATCH 179/388] Ignore dist folder
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index 906dc226..03545d1a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
.coverage
.tox/
+dist/
docs/_build/
htmlcov/
Tailbone.egg-info/
From 610e1666c01b48a5aae4990d51aa1cafc04d60ce Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Fri, 7 Jun 2024 10:07:31 -0500
Subject: [PATCH 180/388] Revert "Use `pkg_resources` to determine package
versions"
This reverts commit f6f2a53a0c7a542ead7bb5dc9a8414e6057ed774.
---
tailbone/subscribers.py | 5 -----
tailbone/views/common.py | 5 +++--
2 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/tailbone/subscribers.py b/tailbone/subscribers.py
index 59ef64dc..42d3cab7 100644
--- a/tailbone/subscribers.py
+++ b/tailbone/subscribers.py
@@ -28,7 +28,6 @@ import six
import json
import datetime
import logging
-import pkg_resources
import warnings
from collections import OrderedDict
@@ -169,11 +168,7 @@ def before_render(event):
renderer_globals = event
renderer_globals['rattail_app'] = request.rattail_config.get_app()
-
renderer_globals['app_title'] = request.rattail_config.app_title()
- pkg = rattail_config.app_package()
- renderer_globals['app_version'] = pkg_resources.get_distribution(pkg).version
-
renderer_globals['h'] = helpers
renderer_globals['url'] = request.route_url
renderer_globals['rattail'] = rattail
diff --git a/tailbone/views/common.py b/tailbone/views/common.py
index 58346f3b..266561fd 100644
--- a/tailbone/views/common.py
+++ b/tailbone/views/common.py
@@ -24,8 +24,8 @@
Various common views
"""
+import importlib
import os
-import pkg_resources
from collections import OrderedDict
from rattail.batch import consume_batch_id
@@ -108,7 +108,8 @@ class CommonView(View):
return self.project_version
pkg = self.rattail_config.app_package()
- return pkg_resources.get_distribution(pkg).version
+ mod = importlib.import_module(pkg)
+ return mod.__version__
def exception(self):
"""
From a849d8452b6f9ece02a3df231b2e520caa5fc9f8 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Fri, 7 Jun 2024 10:25:14 -0500
Subject: [PATCH 181/388] Update changelog
---
CHANGES.rst | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/CHANGES.rst b/CHANGES.rst
index 178135e4..2295867e 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -5,6 +5,12 @@ CHANGELOG
Unreleased
----------
+0.10.15 (unreleased)
+--------------------
+
+* Do *not* Use ``pkg_resources`` to determine package versions.
+
+
0.10.14 (2024-06-06)
--------------------
From 7c3d5b46f38876c70d6114b23e678df5e810f6c6 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Fri, 7 Jun 2024 10:25:48 -0500
Subject: [PATCH 182/388] Update changelog
---
CHANGES.rst | 2 +-
tailbone/_version.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/CHANGES.rst b/CHANGES.rst
index 2295867e..a711be5f 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -5,7 +5,7 @@ CHANGELOG
Unreleased
----------
-0.10.15 (unreleased)
+0.10.15 (2024-06-07)
--------------------
* Do *not* Use ``pkg_resources`` to determine package versions.
diff --git a/tailbone/_version.py b/tailbone/_version.py
index 7a64f8d0..f6e50fc4 100644
--- a/tailbone/_version.py
+++ b/tailbone/_version.py
@@ -1,3 +1,3 @@
# -*- coding: utf-8; -*-
-__version__ = '0.10.14'
+__version__ = '0.10.15'
From b8ace1eb98b76b93025f84311201a4497076dc06 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Sun, 9 Jun 2024 23:07:52 -0500
Subject: [PATCH 183/388] fix: avoid deprecated config methods for app/node
title
---
tailbone/api/common.py | 11 ++++++-----
tailbone/subscribers.py | 5 +++--
tailbone/templates/base_meta.mako | 2 +-
tailbone/views/auth.py | 3 ++-
tailbone/views/common.py | 11 +++++++----
tailbone/views/settings.py | 3 ++-
tailbone/views/upgrades.py | 3 ++-
7 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/tailbone/api/common.py b/tailbone/api/common.py
index 30dfeab1..1dcaff08 100644
--- a/tailbone/api/common.py
+++ b/tailbone/api/common.py
@@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
-# Copyright © 2010-2023 Lance Edgar
+# Copyright © 2010-2024 Lance Edgar
#
# This file is part of Rattail.
#
@@ -27,8 +27,6 @@ Tailbone Web API - "Common" Views
from collections import OrderedDict
import rattail
-from rattail.db import model
-from rattail.mail import send_email
from cornice import Service
from cornice.service import get_services
@@ -66,7 +64,8 @@ class CommonView(APIView):
}
def get_project_title(self):
- return self.rattail_config.app_title(default="Tailbone")
+ app = self.get_rattail_app()
+ return app.get_title()
def get_project_version(self):
import tailbone
@@ -87,6 +86,8 @@ class CommonView(APIView):
"""
View to handle user feedback form submits.
"""
+ app = self.get_rattail_app()
+ model = self.model
# TODO: this logic was copied from tailbone.views.common and is largely
# identical; perhaps should merge somehow?
schema = Feedback().bind(session=Session())
@@ -106,7 +107,7 @@ class CommonView(APIView):
data['client_ip'] = self.request.client_addr
email_key = data['email_key'] or self.feedback_email_key
- send_email(self.rattail_config, email_key, data=data)
+ app.send_email(email_key, data=data)
return {'ok': True}
return {'error': "Form did not validate!"}
diff --git a/tailbone/subscribers.py b/tailbone/subscribers.py
index 42d3cab7..bc851629 100644
--- a/tailbone/subscribers.py
+++ b/tailbone/subscribers.py
@@ -165,10 +165,11 @@ def before_render(event):
request = event.get('request') or threadlocal.get_current_request()
rattail_config = request.rattail_config
+ app = rattail_config.get_app()
renderer_globals = event
- renderer_globals['rattail_app'] = request.rattail_config.get_app()
- renderer_globals['app_title'] = request.rattail_config.app_title()
+ renderer_globals['rattail_app'] = app
+ renderer_globals['app_title'] = app.get_title()
renderer_globals['h'] = helpers
renderer_globals['url'] = request.route_url
renderer_globals['rattail'] = rattail
diff --git a/tailbone/templates/base_meta.mako b/tailbone/templates/base_meta.mako
index 07b13e61..00cfdfe9 100644
--- a/tailbone/templates/base_meta.mako
+++ b/tailbone/templates/base_meta.mako
@@ -1,6 +1,6 @@
## -*- coding: utf-8; -*-
-<%def name="app_title()">${request.rattail_config.node_title(default="Rattail")}%def>
+<%def name="app_title()">${rattail_app.get_node_title()}%def>
<%def name="global_title()">${"[STAGE] " if not request.rattail_config.production() else ''}${self.app_title()}%def>
diff --git a/tailbone/views/auth.py b/tailbone/views/auth.py
index 0f0d1687..7ecdc6cd 100644
--- a/tailbone/views/auth.py
+++ b/tailbone/views/auth.py
@@ -92,6 +92,7 @@ class AuthenticationView(View):
"""
The login view, responsible for displaying and handling the login form.
"""
+ app = self.get_rattail_app()
referrer = self.request.get_referrer(default=self.request.route_url('home'))
# redirect if already logged in
@@ -133,7 +134,7 @@ class AuthenticationView(View):
'form': form,
'referrer': referrer,
'image_url': image_url,
- 'index_title': self.rattail_config.node_title(),
+ 'index_title': app.get_node_title(),
'help_url': global_help_url(self.rattail_config),
}
diff --git a/tailbone/views/common.py b/tailbone/views/common.py
index 266561fd..25eb7dee 100644
--- a/tailbone/views/common.py
+++ b/tailbone/views/common.py
@@ -50,6 +50,7 @@ class CommonView(View):
"""
Home page view.
"""
+ app = self.get_rattail_app()
if not self.request.user:
if self.rattail_config.getbool('tailbone', 'login_is_home', default=True):
raise self.redirect(self.request.route_url('login'))
@@ -60,7 +61,7 @@ class CommonView(View):
context = {
'image_url': image_url,
- 'index_title': self.rattail_config.node_title(),
+ 'index_title': app.get_node_title(),
'help_url': global_help_url(self.rattail_config),
}
@@ -99,7 +100,8 @@ class CommonView(View):
return response
def get_project_title(self):
- return self.rattail_config.app_title()
+ app = self.get_rattail_app()
+ return app.get_title()
def get_project_version(self):
@@ -121,11 +123,12 @@ class CommonView(View):
"""
Generic view to show "about project" info page.
"""
+ app = self.get_rattail_app()
return {
'project_title': self.get_project_title(),
'project_version': self.get_project_version(),
'packages': self.get_packages(),
- 'index_title': self.rattail_config.node_title(),
+ 'index_title': app.get_node_title(),
}
def get_packages(self):
@@ -209,7 +212,7 @@ class CommonView(View):
raise self.forbidden()
app = self.get_rattail_app()
- app_title = self.rattail_config.app_title()
+ app_title = app.get_title()
poser_handler = app.get_poser_handler()
poser_dir = poser_handler.get_default_poser_dir()
poser_dir_exists = os.path.isdir(poser_dir)
diff --git a/tailbone/views/settings.py b/tailbone/views/settings.py
index cce5e53d..8d389530 100644
--- a/tailbone/views/settings.py
+++ b/tailbone/views/settings.py
@@ -67,8 +67,9 @@ class AppInfoView(MasterView):
]
def get_index_title(self):
+ app = self.get_rattail_app()
return "{} for {}".format(self.get_model_title_plural(),
- self.rattail_config.app_title())
+ app.get_title())
def get_data(self, session=None):
pip = os.path.join(sys.prefix, 'bin', 'pip')
diff --git a/tailbone/views/upgrades.py b/tailbone/views/upgrades.py
index a281062e..3276b64d 100644
--- a/tailbone/views/upgrades.py
+++ b/tailbone/views/upgrades.py
@@ -147,10 +147,11 @@ class UpgradeView(MasterView):
def template_kwargs_view(self, **kwargs):
kwargs = super().template_kwargs_view(**kwargs)
+ app = self.get_rattail_app()
model = self.model
upgrade = kwargs['instance']
- kwargs['system_title'] = self.rattail_config.app_title()
+ kwargs['system_title'] = app.get_title()
if upgrade.system:
system = self.upgrade_handler.get_system(upgrade.system)
if system:
From 2c2727bf6632febc6ec823182498e803c9fd5617 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Mon, 10 Jun 2024 09:07:10 -0500
Subject: [PATCH 184/388] feat: standardize how app, package versions are
determined
---
tailbone/api/common.py | 11 +++++------
tailbone/beaker.py | 8 ++++----
tailbone/subscribers.py | 1 +
tailbone/views/common.py | 13 +++++--------
4 files changed, 15 insertions(+), 18 deletions(-)
diff --git a/tailbone/api/common.py b/tailbone/api/common.py
index 1dcaff08..6cacfb06 100644
--- a/tailbone/api/common.py
+++ b/tailbone/api/common.py
@@ -26,13 +26,12 @@ Tailbone Web API - "Common" Views
from collections import OrderedDict
-import rattail
+from rattail.util import get_pkg_version
from cornice import Service
from cornice.service import get_services
from cornice_swagger import CorniceSwagger
-import tailbone
from tailbone import forms
from tailbone.forms.common import Feedback
from tailbone.api import APIView, api
@@ -68,8 +67,8 @@ class CommonView(APIView):
return app.get_title()
def get_project_version(self):
- import tailbone
- return tailbone.__version__
+ app = self.get_rattail_app()
+ return app.get_version()
def get_packages(self):
"""
@@ -77,8 +76,8 @@ class CommonView(APIView):
'about' page.
"""
return OrderedDict([
- ('rattail', rattail.__version__),
- ('Tailbone', tailbone.__version__),
+ ('rattail', get_pkg_version('rattail')),
+ ('Tailbone', get_pkg_version('Tailbone')),
])
@api
diff --git a/tailbone/beaker.py b/tailbone/beaker.py
index b5d592f1..25a450df 100644
--- a/tailbone/beaker.py
+++ b/tailbone/beaker.py
@@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
-# Copyright © 2010-2022 Lance Edgar
+# Copyright © 2010-2024 Lance Edgar
#
# This file is part of Rattail.
#
@@ -27,11 +27,11 @@ Note that most of the code for this module was copied from the beaker and
pyramid_beaker projects.
"""
-from __future__ import unicode_literals, absolute_import
-
import time
from pkg_resources import parse_version
+from rattail.util import get_pkg_version
+
import beaker
from beaker.session import Session
from beaker.util import coerce_session_params
@@ -49,7 +49,7 @@ class TailboneSession(Session):
"Loads the data from this session from persistent storage"
# are we using older version of beaker?
- old_beaker = parse_version(beaker.__version__) < parse_version('1.12')
+ old_beaker = parse_version(get_pkg_version('beaker')) < parse_version('1.12')
self.namespace = self.namespace_class(self.id,
data_dir=self.data_dir,
diff --git a/tailbone/subscribers.py b/tailbone/subscribers.py
index bc851629..3fcd1017 100644
--- a/tailbone/subscribers.py
+++ b/tailbone/subscribers.py
@@ -170,6 +170,7 @@ def before_render(event):
renderer_globals = event
renderer_globals['rattail_app'] = app
renderer_globals['app_title'] = app.get_title()
+ renderer_globals['app_version'] = app.get_version()
renderer_globals['h'] = helpers
renderer_globals['url'] = request.route_url
renderer_globals['rattail'] = rattail
diff --git a/tailbone/views/common.py b/tailbone/views/common.py
index 25eb7dee..3c4b659b 100644
--- a/tailbone/views/common.py
+++ b/tailbone/views/common.py
@@ -24,12 +24,11 @@
Various common views
"""
-import importlib
import os
from collections import OrderedDict
from rattail.batch import consume_batch_id
-from rattail.util import simple_error
+from rattail.util import get_pkg_version, simple_error
from rattail.files import resource_path
from tailbone import forms
@@ -109,9 +108,8 @@ class CommonView(View):
if hasattr(self, 'project_version'):
return self.project_version
- pkg = self.rattail_config.app_package()
- mod = importlib.import_module(pkg)
- return mod.__version__
+ app = self.get_rattail_app()
+ return app.get_version()
def exception(self):
"""
@@ -136,10 +134,9 @@ class CommonView(View):
Should return the full set of packages which should be displayed on the
'about' page.
"""
- import rattail, tailbone
return OrderedDict([
- ('rattail', rattail.__version__),
- ('Tailbone', tailbone.__version__),
+ ('rattail', get_pkg_version('rattail')),
+ ('Tailbone', get_pkg_version('Tailbone')),
])
def change_theme(self):
From dd58c640fa2a626efb4fc6a729cedf368ba3668f Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Mon, 10 Jun 2024 11:11:06 -0500
Subject: [PATCH 185/388] Update changelog
---
CHANGES.rst | 7 +++++++
tailbone/_version.py | 2 +-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/CHANGES.rst b/CHANGES.rst
index a711be5f..ad65b7bf 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -5,6 +5,13 @@ CHANGELOG
Unreleased
----------
+0.10.16 (2024-06-10)
+--------------------
+
+* fix: avoid deprecated config methods for app/node title
+* feat: standardize how app, package versions are determined
+
+
0.10.15 (2024-06-07)
--------------------
diff --git a/tailbone/_version.py b/tailbone/_version.py
index f6e50fc4..e1187ee4 100644
--- a/tailbone/_version.py
+++ b/tailbone/_version.py
@@ -1,3 +1,3 @@
# -*- coding: utf-8; -*-
-__version__ = '0.10.15'
+__version__ = '0.10.16'
From 1402d437b5900aee406577696c5b02ae0281d5ba Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Mon, 10 Jun 2024 16:23:38 -0500
Subject: [PATCH 186/388] feat: switch from setup.cfg to pyproject.toml +
hatchling
---
.gitignore | 2 +
pyproject.toml | 101 +++++++++++++++++++++++++++++++++++++++++++
setup.cfg | 101 -------------------------------------------
setup.py | 29 -------------
tailbone/_version.py | 8 +++-
tasks.py | 13 +++++-
6 files changed, 122 insertions(+), 132 deletions(-)
create mode 100644 pyproject.toml
delete mode 100644 setup.cfg
delete mode 100644 setup.py
diff --git a/.gitignore b/.gitignore
index 03545d1a..b3006f90 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+*~
+*.pyc
.coverage
.tox/
dist/
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 00000000..7c894886
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,101 @@
+
+[build-system]
+requires = ["hatchling"]
+build-backend = "hatchling.build"
+
+
+[project]
+name = "Tailbone"
+version = "0.10.16"
+description = "Backoffice Web Application for Rattail"
+readme = "README.rst"
+authors = [{name = "Lance Edgar", email = "lance@edbob.org"}]
+license = {text = "GNU GPL v3+"}
+classifiers = [
+ "Development Status :: 4 - Beta",
+ "Environment :: Web Environment",
+ "Framework :: Pyramid",
+ "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",
+ "Programming Language :: Python :: 3.6",
+ "Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3.8",
+ "Programming Language :: Python :: 3.9",
+ "Programming Language :: Python :: 3.10",
+ "Programming Language :: Python :: 3.11",
+ "Topic :: Internet :: WWW/HTTP",
+ "Topic :: Office/Business",
+ "Topic :: Software Development :: Libraries :: Python Modules",
+]
+
+dependencies = [
+ "asgiref",
+ "colander",
+ "ColanderAlchemy",
+ "cornice",
+ "cornice-swagger",
+ "deform",
+ "humanize",
+ "Mako",
+ "markdown",
+ "openpyxl",
+ "paginate",
+ "paginate_sqlalchemy",
+ "passlib",
+ "Pillow",
+ "pyramid>=2",
+ "pyramid_beaker",
+ "pyramid_deform",
+ "pyramid_exclog",
+ "pyramid_fanstatic",
+ "pyramid_mako",
+ "pyramid_retry",
+ "pyramid_tm",
+ "rattail[db,bouncer]",
+ "six",
+ "sa-filters",
+ "simplejson",
+ "transaction",
+ "waitress",
+ "WebHelpers2",
+ "zope.sqlalchemy",
+]
+
+
+[project.optional-dependencies]
+docs = ["Sphinx", "sphinx-rtd-theme"]
+tests = ["coverage", "mock", "pytest", "pytest-cov"]
+
+
+[project.entry-points."paste.app_factory"]
+main = "tailbone.app:main"
+webapi = "tailbone.webapi:main"
+
+
+[project.entry-points."rattail.cleaners"]
+beaker = "tailbone.cleanup:BeakerCleaner"
+
+
+[project.entry-points."rattail.config.extensions"]
+tailbone = "tailbone.config:ConfigExtension"
+
+
+[project.urls]
+Homepage = "https://rattailproject.org"
+Repository = "https://kallithea.rattailproject.org/rattail-project/tailbone"
+Issues = "https://redmine.rattailproject.org/projects/tailbone/issues"
+Changelog = "https://kallithea.rattailproject.org/rattail-project/tailbone/files/master/CHANGES.rst"
+
+
+[tool.commitizen]
+version_provider = "pep621"
+tag_format = "v$version"
+update_changelog_on_bump = true
+
+
+# [tool.hatch.build.targets.wheel]
+# packages = ["corepos"]
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 50c057f9..00000000
--- a/setup.cfg
+++ /dev/null
@@ -1,101 +0,0 @@
-# -*- coding: utf-8; -*-
-
-[nosetests]
-nocapture = 1
-cover-package = tailbone
-cover-erase = 1
-cover-html = 1
-cover-html-dir = htmlcov
-
-[metadata]
-name = Tailbone
-version = attr: tailbone.__version__
-author = Lance Edgar
-author_email = lance@edbob.org
-url = http://rattailproject.org/
-license = GNU GPL v3
-description = Backoffice Web Application for Rattail
-long_description = file: README.rst
-classifiers =
- Development Status :: 4 - Beta
- Environment :: Web Environment
- Framework :: Pyramid
- 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
- Programming Language :: Python :: 3.6
- Programming Language :: Python :: 3.7
- Programming Language :: Python :: 3.8
- Programming Language :: Python :: 3.9
- Programming Language :: Python :: 3.10
- Programming Language :: Python :: 3.11
- Topic :: Internet :: WWW/HTTP
- Topic :: Office/Business
- Topic :: Software Development :: Libraries :: Python Modules
-
-
-[options]
-install_requires =
- asgiref
- colander
- ColanderAlchemy
- cornice
- cornice-swagger
- deform
- humanize
- Mako
- markdown
- openpyxl
- paginate
- paginate_sqlalchemy
- passlib
- Pillow
- pyramid>=2
- pyramid_beaker
- pyramid_deform
- pyramid_exclog
- pyramid_fanstatic
- pyramid_mako
- pyramid_retry
- pyramid_tm
- rattail[db,bouncer]
- six
- sa-filters
- simplejson
- transaction
- waitress
- WebHelpers2
- zope.sqlalchemy
-
-tests_require = Tailbone[tests]
-test_suite = tests
-packages = find:
-include_package_data = True
-zip_safe = False
-
-
-[options.packages.find]
-exclude =
- tests.*
- tests
-
-
-[options.extras_require]
-docs = Sphinx; sphinx-rtd-theme
-tests = coverage; mock; pytest; pytest-cov
-
-
-[options.entry_points]
-
-paste.app_factory =
- main = tailbone.app:main
- webapi = tailbone.webapi:main
-
-rattail.cleaners =
- beaker = tailbone.cleanup:BeakerCleaner
-
-rattail.config.extensions =
- tailbone = tailbone.config:ConfigExtension
diff --git a/setup.py b/setup.py
deleted file mode 100644
index 5645ddff..00000000
--- a/setup.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# -*- coding: utf-8; -*-
-################################################################################
-#
-# Rattail -- Retail Software Framework
-# Copyright © 2010-2023 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 .
-#
-################################################################################
-"""
-Setup script for Tailbone
-"""
-
-from setuptools import setup
-
-setup()
diff --git a/tailbone/_version.py b/tailbone/_version.py
index e1187ee4..7095f6c8 100644
--- a/tailbone/_version.py
+++ b/tailbone/_version.py
@@ -1,3 +1,9 @@
# -*- coding: utf-8; -*-
-__version__ = '0.10.16'
+try:
+ from importlib.metadata import version
+except ImportError:
+ from importlib_metadata import version
+
+
+__version__ = version('Tailbone')
diff --git a/tasks.py b/tasks.py
index fba0b699..e9f47ccd 100644
--- a/tasks.py
+++ b/tasks.py
@@ -25,13 +25,24 @@ Tasks for Tailbone
"""
import os
+import re
import shutil
from invoke import task
here = os.path.abspath(os.path.dirname(__file__))
-exec(open(os.path.join(here, 'tailbone', '_version.py')).read())
+__version__ = None
+pattern = re.compile(r'^version = "(\d+\.\d+\.\d+)"$')
+with open(os.path.join(here, 'pyproject.toml'), 'rt') as f:
+ for line in f:
+ line = line.rstrip('\n')
+ match = pattern.match(line)
+ if match:
+ __version__ = match.group(1)
+ break
+if not __version__:
+ raise RuntimeError("could not parse version!")
@task
From f9cb6cb59bdd525540bc46fc85ff1450bc52d11f Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Mon, 10 Jun 2024 16:40:55 -0500
Subject: [PATCH 187/388] =?UTF-8?q?bump:=20version=200.10.16=20=E2=86=92?=
=?UTF-8?q?=200.11.0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
CHANGELOG.md | 218 +++++++++++++++++++++++++++++
CHANGES.rst => docs/OLDCHANGES.rst | 199 +-------------------------
docs/changelog.rst | 8 ++
docs/index.rst | 8 ++
pyproject.toml | 4 +-
5 files changed, 243 insertions(+), 194 deletions(-)
create mode 100644 CHANGELOG.md
rename CHANGES.rst => docs/OLDCHANGES.rst (97%)
create mode 100644 docs/changelog.rst
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 00000000..c51f3fda
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,218 @@
+
+# Changelog
+All notable changes to Tailbone 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.11.0 (2024-06-10)
+
+### Feat
+
+- switch from setup.cfg to pyproject.toml + hatchling
+
+## v0.10.16 (2024-06-10)
+
+### Feat
+
+- standardize how app, package versions are determined
+
+### Fix
+
+- avoid deprecated config methods for app/node title
+
+## v0.10.15 (2024-06-07)
+
+### Fix
+
+- do *not* Use `pkg_resources` to determine package versions
+
+## v0.10.14 (2024-06-06)
+
+### Fix
+
+- use `pkg_resources` to determine package versions
+
+## v0.10.13 (2024-06-06)
+
+### Feat
+
+- remove old/unused scaffold for use with `pcreate`
+
+- add 'fanstatic' support for sake of libcache assets
+
+## v0.10.12 (2024-06-04)
+
+### Feat
+
+- require pyramid 2.x; remove 1.x-style auth policies
+
+- remove version cap for deform
+
+- set explicit referrer when changing app theme
+
+- add `` component shim
+
+- include extra styles from `base_meta` template for butterball
+
+- include butterball theme by default for new apps
+
+### Fix
+
+- fix product lookup component, per butterball
+
+## v0.10.11 (2024-06-03)
+
+### Feat
+
+- fix vue3 refresh bugs for various views
+
+- fix grid bug for tempmon appliance view, per oruga
+
+- fix ordering worksheet generator, per butterball
+
+- fix inventory worksheet generator, per butterball
+
+## v0.10.10 (2024-06-03)
+
+### Feat
+
+- more butterball fixes for "view profile" template
+
+### Fix
+
+- fix focus for `` shim component
+
+## v0.10.9 (2024-06-03)
+
+### Feat
+
+- let master view control context menu items for page
+
+- fix the "new custorder" page for butterball
+
+### Fix
+
+- fix panel style for PO vs. Invoice breakdown in receiving batch
+
+## v0.10.8 (2024-06-02)
+
+### Feat
+
+- add styling for checked grid rows, per oruga/butterball
+
+- fix product view template for oruga/butterball
+
+- allow per-user custom styles for butterball
+
+- use oruga 0.8.9 by default
+
+## v0.10.7 (2024-06-01)
+
+### Feat
+
+- add setting to allow decimal quantities for receiving
+
+- log error if registry has no rattail config
+
+- add column filters for import/export main grid
+
+- escape all unsafe html for grid data
+
+- add speedbumps for delete, set preferred email/phone in profile view
+
+- fix file upload widget for oruga
+
+### Fix
+
+- fix overflow when instance header title is too long (butterball)
+
+## v0.10.6 (2024-05-29)
+
+### Feat
+
+- add way to flag organic products within lookup dialog
+
+- expose db picker for butterball theme
+
+- expose quickie lookup for butterball theme
+
+- fix basic problems with people profile view, per butterball
+
+## v0.10.5 (2024-05-29)
+
+### Feat
+
+- add `` component for oruga
+
+## v0.10.4 (2024-05-12)
+
+### Fix
+
+- fix styles for grid actions, per butterball
+
+## v0.10.3 (2024-05-10)
+
+### Fix
+
+- fix bug with grid date filters
+
+## v0.10.2 (2024-05-08)
+
+### Feat
+
+- remove version restriction for pyramid_beaker dependency
+
+- rename some attrs etc. for buefy components used with oruga
+
+- fix "tools" helper for receiving batch view, per oruga
+
+- more data type fixes for ````
+
+- fix "view receiving row" page, per oruga
+
+- tweak styles for grid action links, per butterball
+
+### Fix
+
+- fix employees grid when viewing department (per oruga)
+
+- fix login "enter" key behavior, per oruga
+
+- fix button text for autocomplete
+
+## v0.10.1 (2024-04-28)
+
+### Feat
+
+- sort list of available themes
+
+- update various icon names for oruga compatibility
+
+- show "View This" button when cloning a record
+
+- stop including 'falafel' as available theme
+
+### Fix
+
+- fix vertical alignment in main menu bar, for butterball
+
+- fix upgrade execution logic/UI per oruga
+
+## v0.10.0 (2024-04-28)
+
+This version bump is to reflect adding support for Vue 3 + Oruga via
+the 'butterball' theme. There is likely more work to be done for that
+yet, but it mostly works at this point.
+
+### Feat
+
+- misc. template and view logic tweaks (applicable to all themes) for
+ better patterns, consistency etc.
+
+- add initial support for Vue 3 + Oruga, via "butterball" theme
+
+
+## Older Releases
+
+Please see `docs/OLDCHANGES.rst` for older release notes.
diff --git a/CHANGES.rst b/docs/OLDCHANGES.rst
similarity index 97%
rename from CHANGES.rst
rename to docs/OLDCHANGES.rst
index ad65b7bf..0a802f40 100644
--- a/CHANGES.rst
+++ b/docs/OLDCHANGES.rst
@@ -2,193 +2,8 @@
CHANGELOG
=========
-Unreleased
-----------
-
-0.10.16 (2024-06-10)
---------------------
-
-* fix: avoid deprecated config methods for app/node title
-* feat: standardize how app, package versions are determined
-
-
-0.10.15 (2024-06-07)
---------------------
-
-* Do *not* Use ``pkg_resources`` to determine package versions.
-
-
-0.10.14 (2024-06-06)
---------------------
-
-* Use ``pkg_resources`` to determine package versions.
-
-
-0.10.13 (2024-06-06)
---------------------
-
-* Remove old/unused scaffold for use with ``pcreate``.
-
-* Add 'fanstatic' support for sake of libcache assets.
-
-
-0.10.12 (2024-06-04)
---------------------
-
-* Require pyramid 2.x; remove 1.x-style auth policies.
-
-* Remove version cap for deform.
-
-* Set explicit referrer when changing app theme.
-
-* Add ```` component shim.
-
-* Include extra styles from ``base_meta`` template for butterball.
-
-* Fix product lookup component, per butterball.
-
-* Include butterball theme by default for new apps.
-
-
-0.10.11 (2024-06-03)
---------------------
-
-* Fix vue3 refresh bugs for various views.
-
-* Fix grid bug for tempmon appliance view, per oruga.
-
-* Fix ordering worksheet generator, per butterball.
-
-* Fix inventory worksheet generator, per butterball.
-
-
-0.10.10 (2024-06-03)
---------------------
-
-* Fix focus for ```` shim component.
-
-* More butterball fixes for "view profile" template.
-
-
-0.10.9 (2024-06-03)
--------------------
-
-* Let master view control context menu items for page.
-
-* Fix panel style for PO vs. Invoice breakdown in receiving batch.
-
-* Fix the "new custorder" page for butterball.
-
-
-0.10.8 (2024-06-02)
--------------------
-
-* Add styling for checked grid rows, per oruga/butterball.
-
-* Fix product view template for oruga/butterball.
-
-* Allow per-user custom styles for butterball.
-
-* Use oruga 0.8.9 by default.
-
-
-0.10.7 (2024-06-01)
--------------------
-
-* Add setting to allow decimal quantities for receiving.
-
-* Log error if registry has no rattail config.
-
-* Add column filters for import/export main grid.
-
-* Fix overflow when instance header title is too long (butterball).
-
-* Escape all unsafe html for grid data.
-
-* Add speedbumps for delete, set preferred email/phone in profile view.
-
-* Fix file upload widget for oruga.
-
-
-0.10.6 (2024-05-29)
--------------------
-
-* Add way to flag organic products within lookup dialog.
-
-* Expose db picker for butterball theme.
-
-* Expose quickie lookup for butterball theme.
-
-* Fix basic problems with people profile view, per butterball.
-
-
-0.10.5 (2024-05-29)
--------------------
-
-* Add ```` component for oruga.
-
-
-0.10.4 (2024-05-12)
--------------------
-
-* Fix styles for grid actions, per butterball.
-
-
-0.10.3 (2024-05-10)
--------------------
-
-* Fix bug with grid date filters.
-
-
-0.10.2 (2024-05-08)
--------------------
-
-* Fix employees grid when viewing department (per oruga).
-
-* Remove version restriction for pyramid_beaker dependency.
-
-* Fix login "enter" key behavior, per oruga.
-
-* Rename some attrs etc. for buefy components used with oruga.
-
-* Fix "tools" helper for receiving batch view, per oruga.
-
-* Fix button text for autocomplete.
-
-* More data type fixes for ````.
-
-* Fix "view receiving row" page, per oruga.
-
-* Tweak styles for grid action links, per butterball.
-
-
-0.10.1 (2024-04-28)
--------------------
-
-* Sort list of available themes.
-
-* Update various icon names for oruga compatibility.
-
-* Fix vertical alignment in main menu bar, for butterball.
-
-* Fix upgrade execution logic/UI per oruga.
-
-* Show "View This" button when cloning a record.
-
-* Stop including 'falafel' as available theme.
-
-
-0.10.0 (2024-04-28)
--------------------
-
-This version bump is to reflect adding support for Vue 3 + Oruga via
-the 'butterball' theme. There is likely more work to be done for that
-yet, but it mostly works at this point.
-
-* Misc. template and view logic tweaks (applicable to all themes) for
- better patterns, consistency etc.
-
-* Add initial support for Vue 3 + Oruga, via "butterball" theme.
+NB. this file contains "old" release notes only. for newer releases
+see the `CHANGELOG.md` file in the source root folder.
0.9.96 (2024-04-25)
@@ -5177,7 +4992,7 @@ and related technologies.
0.6.47 (2017-11-08)
-------------------
-* Fix manifest to include *.pt deform templates
+* Fix manifest to include ``*.pt`` deform templates
0.6.46 (2017-11-08)
@@ -5510,13 +5325,13 @@ and related technologies.
0.6.13 (2017-07-26)
-------------------
+-------------------
* Allow master view to decide whether each grid checkbox is checked
0.6.12 (2017-07-26)
-------------------
+-------------------
* Add basic support for product inventory and status
@@ -5524,7 +5339,7 @@ and related technologies.
0.6.11 (2017-07-18)
-------------------
+-------------------
* Tweak some basic styles for forms/grids
@@ -5532,7 +5347,7 @@ and related technologies.
0.6.10 (2017-07-18)
-------------------
+-------------------
* Fix grid bug if "current page" becomes invalid
diff --git a/docs/changelog.rst b/docs/changelog.rst
new file mode 100644
index 00000000..bbf94f4b
--- /dev/null
+++ b/docs/changelog.rst
@@ -0,0 +1,8 @@
+
+Changelog Archive
+=================
+
+.. toctree::
+ :maxdepth: 1
+
+ OLDCHANGES
diff --git a/docs/index.rst b/docs/index.rst
index 351e910d..db05d0c1 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -60,6 +60,14 @@ Package API:
api/views/purchasing.ordering
+Changelog:
+
+.. toctree::
+ :maxdepth: 1
+
+ changelog
+
+
Documentation To-Do
===================
diff --git a/pyproject.toml b/pyproject.toml
index 7c894886..13a232ae 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
[project]
name = "Tailbone"
-version = "0.10.16"
+version = "0.11.0"
description = "Backoffice Web Application for Rattail"
readme = "README.rst"
authors = [{name = "Lance Edgar", email = "lance@edbob.org"}]
@@ -88,7 +88,7 @@ tailbone = "tailbone.config:ConfigExtension"
Homepage = "https://rattailproject.org"
Repository = "https://kallithea.rattailproject.org/rattail-project/tailbone"
Issues = "https://redmine.rattailproject.org/projects/tailbone/issues"
-Changelog = "https://kallithea.rattailproject.org/rattail-project/tailbone/files/master/CHANGES.rst"
+Changelog = "https://kallithea.rattailproject.org/rattail-project/tailbone/files/master/CHANGELOG.md"
[tool.commitizen]
From fb0c538a2bd0d58f85ea37c4d8524b4fcf8515a0 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Mon, 10 Jun 2024 17:42:29 -0500
Subject: [PATCH 188/388] test: skip running tests for py36
we should soon require python 3.8 anyway
---
tox.ini | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/tox.ini b/tox.ini
index ea833b39..6e45883c 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,9 @@
[tox]
-envlist = py36, py37, py38, py39, py310, py311
+# TODO: i had to remove py36 since something (hatchling?) broke it
+# somehow, and i was not able to quickly fix. as of writing only
+# one app is known to run py36 and hopefully that is not for long.
+envlist = py37, py38, py39, py310, py311
# TODO: can remove this when we drop py36 support
# nb. need this for testing older python versions
From 6e741f6156a50442426f6a59f2321d11eedcbdf3 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Fri, 14 Jun 2024 17:57:01 -0500
Subject: [PATCH 189/388] fix: revert back to setup.py + setup.cfg
apparently with python 3.6 things "mostly" work but then they break if
any specified dependencies have a dot in the name. which in this
project, is the case for `zope.sqlalchemy`
so until we drop python 3.6 support, we cannot use pyproject.toml here
---
pyproject.toml | 101 -------------------------------------------------
setup.cfg | 97 +++++++++++++++++++++++++++++++++++++++++++++++
setup.py | 3 ++
3 files changed, 100 insertions(+), 101 deletions(-)
delete mode 100644 pyproject.toml
create mode 100644 setup.cfg
create mode 100644 setup.py
diff --git a/pyproject.toml b/pyproject.toml
deleted file mode 100644
index 13a232ae..00000000
--- a/pyproject.toml
+++ /dev/null
@@ -1,101 +0,0 @@
-
-[build-system]
-requires = ["hatchling"]
-build-backend = "hatchling.build"
-
-
-[project]
-name = "Tailbone"
-version = "0.11.0"
-description = "Backoffice Web Application for Rattail"
-readme = "README.rst"
-authors = [{name = "Lance Edgar", email = "lance@edbob.org"}]
-license = {text = "GNU GPL v3+"}
-classifiers = [
- "Development Status :: 4 - Beta",
- "Environment :: Web Environment",
- "Framework :: Pyramid",
- "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",
- "Programming Language :: Python :: 3.6",
- "Programming Language :: Python :: 3.7",
- "Programming Language :: Python :: 3.8",
- "Programming Language :: Python :: 3.9",
- "Programming Language :: Python :: 3.10",
- "Programming Language :: Python :: 3.11",
- "Topic :: Internet :: WWW/HTTP",
- "Topic :: Office/Business",
- "Topic :: Software Development :: Libraries :: Python Modules",
-]
-
-dependencies = [
- "asgiref",
- "colander",
- "ColanderAlchemy",
- "cornice",
- "cornice-swagger",
- "deform",
- "humanize",
- "Mako",
- "markdown",
- "openpyxl",
- "paginate",
- "paginate_sqlalchemy",
- "passlib",
- "Pillow",
- "pyramid>=2",
- "pyramid_beaker",
- "pyramid_deform",
- "pyramid_exclog",
- "pyramid_fanstatic",
- "pyramid_mako",
- "pyramid_retry",
- "pyramid_tm",
- "rattail[db,bouncer]",
- "six",
- "sa-filters",
- "simplejson",
- "transaction",
- "waitress",
- "WebHelpers2",
- "zope.sqlalchemy",
-]
-
-
-[project.optional-dependencies]
-docs = ["Sphinx", "sphinx-rtd-theme"]
-tests = ["coverage", "mock", "pytest", "pytest-cov"]
-
-
-[project.entry-points."paste.app_factory"]
-main = "tailbone.app:main"
-webapi = "tailbone.webapi:main"
-
-
-[project.entry-points."rattail.cleaners"]
-beaker = "tailbone.cleanup:BeakerCleaner"
-
-
-[project.entry-points."rattail.config.extensions"]
-tailbone = "tailbone.config:ConfigExtension"
-
-
-[project.urls]
-Homepage = "https://rattailproject.org"
-Repository = "https://kallithea.rattailproject.org/rattail-project/tailbone"
-Issues = "https://redmine.rattailproject.org/projects/tailbone/issues"
-Changelog = "https://kallithea.rattailproject.org/rattail-project/tailbone/files/master/CHANGELOG.md"
-
-
-[tool.commitizen]
-version_provider = "pep621"
-tag_format = "v$version"
-update_changelog_on_bump = true
-
-
-# [tool.hatch.build.targets.wheel]
-# packages = ["corepos"]
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 00000000..83ce9814
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,97 @@
+
+[metadata]
+name = Tailbone
+version = 0.11.0
+author = Lance Edgar
+author_email = lance@edbob.org
+url = http://rattailproject.org/
+license = GNU GPL v3
+description = Backoffice Web Application for Rattail
+long_description = file: README.rst
+classifiers =
+ Development Status :: 4 - Beta
+ Environment :: Web Environment
+ Framework :: Pyramid
+ 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
+ Programming Language :: Python :: 3.6
+ Programming Language :: Python :: 3.7
+ Programming Language :: Python :: 3.8
+ Programming Language :: Python :: 3.9
+ Programming Language :: Python :: 3.10
+ Programming Language :: Python :: 3.11
+ Topic :: Internet :: WWW/HTTP
+ Topic :: Office/Business
+ Topic :: Software Development :: Libraries :: Python Modules
+
+
+[options]
+packages = find:
+include_package_data = True
+install_requires =
+ asgiref
+ colander
+ ColanderAlchemy
+ cornice
+ cornice-swagger
+ deform
+ humanize
+ Mako
+ markdown
+ openpyxl
+ paginate
+ paginate_sqlalchemy
+ passlib
+ Pillow
+ pyramid>=2
+ pyramid_beaker
+ pyramid_deform
+ pyramid_exclog
+ pyramid_fanstatic
+ pyramid_mako
+ pyramid_retry
+ pyramid_tm
+ rattail[db,bouncer]
+ six
+ sa-filters
+ simplejson
+ transaction
+ waitress
+ WebHelpers2
+ zope.sqlalchemy
+
+
+[options.packages.find]
+exclude =
+ tests.*
+ tests
+
+
+[options.extras_require]
+docs = Sphinx; sphinx-rtd-theme
+tests = coverage; mock; pytest; pytest-cov
+
+
+[options.entry_points]
+
+paste.app_factory =
+ main = tailbone.app:main
+ webapi = tailbone.webapi:main
+
+rattail.cleaners =
+ beaker = tailbone.cleanup:BeakerCleaner
+
+rattail.config.extensions =
+ tailbone = tailbone.config:ConfigExtension
+
+
+[nosetests]
+nocapture = 1
+cover-package = tailbone
+cover-erase = 1
+cover-html = 1
+cover-html-dir = htmlcov
diff --git a/setup.py b/setup.py
new file mode 100644
index 00000000..b908cbe5
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,3 @@
+import setuptools
+
+setuptools.setup()
From ab4dbbedf05ffaf927d191fed670391f74a98eb1 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Fri, 14 Jun 2024 18:01:40 -0500
Subject: [PATCH 190/388] =?UTF-8?q?bump:=20version=200.11.0=20=E2=86=92=20?=
=?UTF-8?q?0.11.1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
CHANGELOG.md | 6 ++++++
setup.cfg | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c51f3fda..40dfa16e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,12 @@ All notable changes to Tailbone 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.11.1 (2024-06-14)
+
+### Fix
+
+- revert back to setup.py + setup.cfg
+
## v0.11.0 (2024-06-10)
### Feat
diff --git a/setup.cfg b/setup.cfg
index 83ce9814..2ea746e9 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,7 +1,7 @@
[metadata]
name = Tailbone
-version = 0.11.0
+version = 0.11.1
author = Lance Edgar
author_email = lance@edbob.org
url = http://rattailproject.org/
From da4450b574cef8ec1b8cf77ac0c52085f395d5aa Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Fri, 14 Jun 2024 18:02:39 -0500
Subject: [PATCH 191/388] build: avoid version parse when uploading release
---
tasks.py | 19 +++----------------
1 file changed, 3 insertions(+), 16 deletions(-)
diff --git a/tasks.py b/tasks.py
index e9f47ccd..b57315a0 100644
--- a/tasks.py
+++ b/tasks.py
@@ -25,26 +25,11 @@ Tasks for Tailbone
"""
import os
-import re
import shutil
from invoke import task
-here = os.path.abspath(os.path.dirname(__file__))
-__version__ = None
-pattern = re.compile(r'^version = "(\d+\.\d+\.\d+)"$')
-with open(os.path.join(here, 'pyproject.toml'), 'rt') as f:
- for line in f:
- line = line.rstrip('\n')
- match = pattern.match(line)
- if match:
- __version__ = match.group(1)
- break
-if not __version__:
- raise RuntimeError("could not parse version!")
-
-
@task
def release(c, tests=False):
"""
@@ -53,7 +38,9 @@ def release(c, tests=False):
if tests:
c.run('tox')
+ if os.path.exists('dist'):
+ shutil.rmtree('dist')
if os.path.exists('Tailbone.egg-info'):
shutil.rmtree('Tailbone.egg-info')
c.run('python -m build --sdist')
- c.run(f'twine upload dist/tailbone-{__version__}.tar.gz')
+ c.run('twine upload dist/*')
From 0212e52b6611b4906107217113f1fbe0e30d252d Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Fri, 14 Jun 2024 19:59:52 -0500
Subject: [PATCH 192/388] fix: hide certain custorder settings if not
applicable
---
tailbone/templates/custorders/configure.mako | 51 ++++++++++++--------
1 file changed, 30 insertions(+), 21 deletions(-)
diff --git a/tailbone/templates/custorders/configure.mako b/tailbone/templates/custorders/configure.mako
index d2f6610d..16d26d21 100644
--- a/tailbone/templates/custorders/configure.mako
+++ b/tailbone/templates/custorders/configure.mako
@@ -24,29 +24,38 @@
-
-
- Allow user to enter new contact info
-
-
+
-
- If you allow users to enter new contact info, the default action
- when the order is submitted, is to send email with details of
- the new contact info. Settings for these are at:
-
+
+
+ Allow user to enter new contact info
+
+
-
-
- ${h.link_to("New Phone Request", url('emailprofiles.view', key='new_phone_requested'))}
-
-
- ${h.link_to("New Email Request", url('emailprofiles.view', key='new_email_requested'))}
-
-
+
+
+
+ If you allow users to enter new contact info, the default action
+ when the order is submitted, is to send email with details of
+ the new contact info. Settings for these are at:
+
+
+
+
+ ${h.link_to("New Phone Request", url('emailprofiles.view', key='new_phone_requested'))}
+
+
+ ${h.link_to("New Email Request", url('emailprofiles.view', key='new_email_requested'))}
+
+
+
+
+
Product Handling
From 88e7d86087c590d3ae3bc957dc1685ca7b815414 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Tue, 18 Jun 2024 15:04:05 -0500
Subject: [PATCH 193/388] fix: use different logic for buefy/oruga for product
lookup keydown
i could have swore the new logic worked with buefy..but today it didn't
---
tailbone/templates/products/lookup.mako | 28 +++++++++++++++++--------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/tailbone/templates/products/lookup.mako b/tailbone/templates/products/lookup.mako
index 7997eb7d..bb9590b2 100644
--- a/tailbone/templates/products/lookup.mako
+++ b/tailbone/templates/products/lookup.mako
@@ -56,7 +56,11 @@
+ ref="searchTermInput"
+ % if not request.use_oruga:
+ @keydown.native="searchTermInputKeydown"
+ % endif
+ />
Date: Tue, 18 Jun 2024 16:06:55 -0500
Subject: [PATCH 194/388] fix: product records should be touchable
---
tailbone/views/products.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/tailbone/views/products.py b/tailbone/views/products.py
index 28186ac3..5265edbc 100644
--- a/tailbone/views/products.py
+++ b/tailbone/views/products.py
@@ -81,6 +81,7 @@ class ProductView(MasterView):
supports_autocomplete = True
bulk_deletable = True
mergeable = True
+ touchable = True
configurable = True
labels = {
From a0cd8835e038f4952824da17f37172d5fe9fe334 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Tue, 18 Jun 2024 16:07:07 -0500
Subject: [PATCH 195/388] fix: show flash error message if resolve pending
product fails
---
tailbone/views/products.py | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/tailbone/views/products.py b/tailbone/views/products.py
index 5265edbc..c395ff24 100644
--- a/tailbone/views/products.py
+++ b/tailbone/views/products.py
@@ -2563,7 +2563,14 @@ class PendingProductView(MasterView):
app = self.get_rattail_app()
products_handler = app.get_products_handler()
kwargs = self.get_resolve_product_kwargs()
- products_handler.resolve_product(pending, product, self.request.user, **kwargs)
+
+ try:
+ products_handler.resolve_product(pending, product, self.request.user, **kwargs)
+ except Exception as error:
+ log.warning("failed to resolve product", exc_info=True)
+ self.request.session.flash(f"Resolve failed: {simple_error(error)}", 'error')
+ return redirect
+
return redirect
def get_resolve_product_kwargs(self, **kwargs):
From 525a28f3fe7b0e1b6e21576f06bd0cc341252ff7 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Tue, 18 Jun 2024 18:05:05 -0500
Subject: [PATCH 196/388] =?UTF-8?q?bump:=20version=200.11.1=20=E2=86=92=20?=
=?UTF-8?q?0.11.2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
CHANGELOG.md | 12 ++++++++++++
setup.cfg | 2 +-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 40dfa16e..ed866741 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,18 @@ All notable changes to Tailbone 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.11.2 (2024-06-18)
+
+### Fix
+
+- hide certain custorder settings if not applicable
+
+- use different logic for buefy/oruga for product lookup keydown
+
+- product records should be touchable
+
+- show flash error message if resolve pending product fails
+
## v0.11.1 (2024-06-14)
### Fix
diff --git a/setup.cfg b/setup.cfg
index 2ea746e9..aa14088a 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,7 +1,7 @@
[metadata]
name = Tailbone
-version = 0.11.1
+version = 0.11.2
author = Lance Edgar
author_email = lance@edbob.org
url = http://rattailproject.org/
From 067ca5bd4354f8dd47f5a3e9206627e3c6f6ae32 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Thu, 27 Jun 2024 23:11:13 -0500
Subject: [PATCH 197/388] fix: add link to "resolved by" user for pending
products
---
tailbone/views/products.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tailbone/views/products.py b/tailbone/views/products.py
index c395ff24..bf2d7f14 100644
--- a/tailbone/views/products.py
+++ b/tailbone/views/products.py
@@ -2457,9 +2457,10 @@ class PendingProductView(MasterView):
# resolved*
if self.creating:
f.remove('resolved', 'resolved_by')
+ elif pending.resolved:
+ f.set_renderer('resolved_by', self.render_user)
else:
- if not pending.resolved:
- f.remove('resolved', 'resolved_by')
+ f.remove('resolved', 'resolved_by')
def render_status_code(self, pending, field):
status = pending.status_code
From 3b7cc19faa758e83cb6f358e4bcb93fc3f15c06e Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Fri, 28 Jun 2024 15:36:08 -0500
Subject: [PATCH 198/388] fix: handle error when merging 2 records fails
should give the user some idea of the problem instead of just sending
error email to admins
---
tailbone/views/master.py | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/tailbone/views/master.py b/tailbone/views/master.py
index 48bc32fe..1e917902 100644
--- a/tailbone/views/master.py
+++ b/tailbone/views/master.py
@@ -2292,9 +2292,13 @@ class MasterView(View):
except Exception as error:
self.request.session.flash("Requested merge cannot proceed (maybe swap kept/removed and try again?): {}".format(error), 'error')
else:
- self.merge_objects(object_to_remove, object_to_keep)
- self.request.session.flash("{} has been merged into {}".format(msg, object_to_keep))
- return self.redirect(self.get_action_url('view', object_to_keep))
+ try:
+ self.merge_objects(object_to_remove, object_to_keep)
+ self.request.session.flash("{} has been merged into {}".format(msg, object_to_keep))
+ return self.redirect(self.get_action_url('view', object_to_keep))
+ except Exception as error:
+ error = simple_error(error)
+ self.request.session.flash(f"merge failed: {error}", 'error')
if not object_to_remove or not object_to_keep or object_to_remove is object_to_keep:
return self.redirect(self.get_index_url())
From d17bd35909444f30807b486a3b0eded5bb4915b4 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Fri, 28 Jun 2024 15:39:59 -0500
Subject: [PATCH 199/388] =?UTF-8?q?bump:=20version=200.11.2=20=E2=86=92=20?=
=?UTF-8?q?0.11.3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
CHANGELOG.md | 8 ++++++++
setup.cfg | 2 +-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ed866741..f18a87ea 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,14 @@ All notable changes to Tailbone 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.11.3 (2024-06-28)
+
+### Fix
+
+- add link to "resolved by" user for pending products
+
+- handle error when merging 2 records fails
+
## v0.11.2 (2024-06-18)
### Fix
diff --git a/setup.cfg b/setup.cfg
index aa14088a..2dd65a74 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,7 +1,7 @@
[metadata]
name = Tailbone
-version = 0.11.2
+version = 0.11.3
author = Lance Edgar
author_email = lance@edbob.org
url = http://rattailproject.org/
From ec5ed490d91438b679315ee88cfeb37c2368ac10 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Fri, 28 Jun 2024 17:34:54 -0500
Subject: [PATCH 200/388] fix: start/stop being root should submit POST instead
of GET
obviously it's access-restricted anyway but this just seems more correct
but more importantly this makes the referrer explicit, since for some
unknown reason i am suddenly seeing that be blank for certain installs
where that wasn't the case before (?) - and the result was that every
time you start/stop being root you would be redirected to home page
instead of remaining on current page
---
.../templates/themes/butterball/base.mako | 30 +++++++++++++++++--
tailbone/views/auth.py | 3 ++
2 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/tailbone/templates/themes/butterball/base.mako b/tailbone/templates/themes/butterball/base.mako
index 3f0253ce..339d23bd 100644
--- a/tailbone/templates/themes/butterball/base.mako
+++ b/tailbone/templates/themes/butterball/base.mako
@@ -924,9 +924,23 @@
% endif
% if request.is_root:
- ${h.link_to("Stop being root", url('stop_root'), class_='navbar-item has-background-danger has-text-white')}
+ ${h.form(url('stop_root'), ref='stopBeingRootForm')}
+ ${h.csrf_token(request)}
+
+
+ Stop being root
+
+ ${h.end_form()}
% elif request.is_admin:
- ${h.link_to("Become root", url('become_root'), class_='navbar-item has-background-danger has-text-white')}
+ ${h.form(url('become_root'), ref='startBeingRootForm')}
+ ${h.csrf_token(request)}
+
+
+ Become root
+
+ ${h.end_form()}
% endif
% if messaging_enabled:
${h.link_to("Messages{}".format(" ({})".format(inbox_count) if inbox_count else ''), url('messages.inbox'), class_='navbar-item')}
@@ -1109,6 +1123,18 @@
const key = 'menu_' + hash + '_shown'
this[key] = !this[key]
},
+
+ % if request.is_admin:
+
+ startBeingRoot() {
+ this.$refs.startBeingRootForm.submit()
+ },
+
+ stopBeingRoot() {
+ this.$refs.stopBeingRootForm.submit()
+ },
+
+ % endif
},
}
diff --git a/tailbone/views/auth.py b/tailbone/views/auth.py
index 7ecdc6cd..730d7b6a 100644
--- a/tailbone/views/auth.py
+++ b/tailbone/views/auth.py
@@ -238,6 +238,9 @@ class AuthenticationView(View):
config.add_view(cls, attr='change_password', route_name='change_password', renderer='/change_password.mako')
# become/stop root
+ # TODO: these should require POST but i won't bother until
+ # after butterball becomes default theme..or probably should
+ # just refactor the falafel theme accordingly..?
config.add_route('become_root', '/root/yes')
config.add_view(cls, attr='become_root', route_name='become_root')
config.add_route('stop_root', '/root/no')
From 9b6447c4cb1c5a51486436ee8ddb4ec675c6fb7d Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Fri, 28 Jun 2024 17:58:27 -0500
Subject: [PATCH 201/388] fix: require vendor when making new ordering batch
via api
pretty sure this pattern needs to be expanded and probably improved,
but wanted to fix this one scenario for now, per error email
---
tailbone/api/batch/ordering.py | 2 ++
tailbone/api/master.py | 14 +++++++++-----
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/tailbone/api/batch/ordering.py b/tailbone/api/batch/ordering.py
index 1b11194e..204be8ad 100644
--- a/tailbone/api/batch/ordering.py
+++ b/tailbone/api/batch/ordering.py
@@ -86,6 +86,8 @@ class OrderingBatchViews(APIBatchView):
Sets the mode to "ordering" for the new batch.
"""
data = dict(data)
+ if not data.get('vendor_uuid'):
+ raise ValueError("You must specify the vendor")
data['mode'] = self.enum.PURCHASE_BATCH_MODE_ORDERING
batch = super().create_object(data)
return batch
diff --git a/tailbone/api/master.py b/tailbone/api/master.py
index 70616484..2d17339e 100644
--- a/tailbone/api/master.py
+++ b/tailbone/api/master.py
@@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
-# Copyright © 2010-2023 Lance Edgar
+# Copyright © 2010-2024 Lance Edgar
#
# This file is part of Rattail.
#
@@ -31,7 +31,7 @@ from rattail.db.util import get_fieldnames
from cornice import resource, Service
-from tailbone.api import APIView, api
+from tailbone.api import APIView
from tailbone.db import Session
from tailbone.util import SortColumn
@@ -355,9 +355,13 @@ class APIMasterView(APIView):
data = self.request.json_body
# add instance to session, and return data for it
- obj = self.create_object(data)
- self.Session.flush()
- return self._get(obj)
+ try:
+ obj = self.create_object(data)
+ except Exception as error:
+ return self.json_response({'error': str(error)})
+ else:
+ self.Session.flush()
+ return self._get(obj)
def create_object(self, data):
"""
From 83e4d95741e098a065a41d81f0776232b8008583 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Sun, 30 Jun 2024 10:32:05 -0500
Subject: [PATCH 202/388] fix: don't escape each address for email attempts
grid
now that we are properly escaping the full cell value, no need
---
tailbone/views/email.py | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/tailbone/views/email.py b/tailbone/views/email.py
index 22954782..4014c05e 100644
--- a/tailbone/views/email.py
+++ b/tailbone/views/email.py
@@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
-# Copyright © 2010-2023 Lance Edgar
+# Copyright © 2010-2024 Lance Edgar
#
# This file is part of Rattail.
#
@@ -28,14 +28,13 @@ import logging
import re
import warnings
-from rattail import mail
-from rattail.db import model
-from rattail.config import parse_list
+from wuttjamaican.util import parse_list
+
+from rattail.db.model import EmailAttempt
from rattail.util import simple_error
import colander
from deform import widget as dfwidget
-from webhelpers2.html import HTML
from tailbone import grids
from tailbone.db import Session
@@ -85,7 +84,7 @@ class EmailSettingView(MasterView):
]
def __init__(self, request):
- super(EmailSettingView, self).__init__(request)
+ super().__init__(request)
self.email_handler = self.get_handler()
@property
@@ -204,7 +203,7 @@ class EmailSettingView(MasterView):
return True
def configure_form(self, f):
- super(EmailSettingView, self).configure_form(f)
+ super().configure_form(f)
profile = f.model_instance['_email']
# key
@@ -437,7 +436,7 @@ class EmailPreview(View):
"""
def __init__(self, request):
- super(EmailPreview, self).__init__(request)
+ super().__init__(request)
if hasattr(self, 'get_handler'):
warnings.warn("defining a get_handler() method is deprecated; "
@@ -520,7 +519,7 @@ class EmailAttemptView(MasterView):
"""
Master view for email attempts.
"""
- model_class = model.EmailAttempt
+ model_class = EmailAttempt
route_prefix = 'email_attempts'
url_prefix = '/email/attempts'
creatable = False
@@ -553,7 +552,7 @@ class EmailAttemptView(MasterView):
]
def configure_grid(self, g):
- super(EmailAttemptView, self).configure_grid(g)
+ super().configure_grid(g)
# sent
g.set_sort_defaults('sent', 'desc')
@@ -583,13 +582,12 @@ class EmailAttemptView(MasterView):
if len(recips) > 2:
recips = recips[:2]
recips.append('...')
- recips = [HTML.escape(r) for r in recips]
return ', '.join(recips)
return value
def configure_form(self, f):
- super(EmailAttemptView, self).configure_form(f)
+ super().configure_form(f)
# key
f.set_renderer('key', self.render_email_key)
From eff5341335a898c6770d6a28dd7dde77b2bdad20 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Sun, 30 Jun 2024 10:49:54 -0500
Subject: [PATCH 203/388] =?UTF-8?q?bump:=20version=200.11.3=20=E2=86=92=20?=
=?UTF-8?q?0.11.4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
CHANGELOG.md | 10 ++++++++++
setup.cfg | 2 +-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f18a87ea..8d92a99e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,16 @@ All notable changes to Tailbone 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.11.4 (2024-06-30)
+
+### Fix
+
+- start/stop being root should submit POST instead of GET
+
+- require vendor when making new ordering batch via api
+
+- don't escape each address for email attempts grid
+
## v0.11.3 (2024-06-28)
### Fix
diff --git a/setup.cfg b/setup.cfg
index 2dd65a74..82cf3b25 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,7 +1,7 @@
[metadata]
name = Tailbone
-version = 0.11.3
+version = 0.11.4
author = Lance Edgar
author_email = lance@edbob.org
url = http://rattailproject.org/
From 1dc632174eed4058f07c75ede528e0b7ec0188a9 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Sun, 30 Jun 2024 11:44:33 -0500
Subject: [PATCH 204/388] fix: allow comma in numeric filter input
just remove them and run with the remainder, on the SQL side
---
tailbone/grids/filters.py | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/tailbone/grids/filters.py b/tailbone/grids/filters.py
index 3b198614..7e52bb8d 100644
--- a/tailbone/grids/filters.py
+++ b/tailbone/grids/filters.py
@@ -26,6 +26,7 @@ Grid Filters
import re
import datetime
+import decimal
import logging
from collections import OrderedDict
@@ -647,12 +648,22 @@ class AlchemyNumericFilter(AlchemyGridFilter):
# first just make sure it's somewhat numeric
try:
- float(value)
- except ValueError:
+ self.parse_decimal(value)
+ except decimal.InvalidOperation:
return True
return bool(value and len(str(value)) > 8)
+ def parse_decimal(self, value):
+ if value:
+ value = value.replace(',', '')
+ return decimal.Decimal(value)
+
+ def encode_value(self, value):
+ if value:
+ value = str(self.parse_decimal(value))
+ return super().encode_value(value)
+
def filter_equal(self, query, value):
if self.value_invalid(value):
return query
From 3f7de5872e50f4ffd6e8c510ed8738bd24e0b870 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Sun, 30 Jun 2024 12:40:03 -0500
Subject: [PATCH 205/388] fix: add custom url prefix if needed, for fanstatic
---
tailbone/util.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tailbone/util.py b/tailbone/util.py
index 9a993176..78c41313 100644
--- a/tailbone/util.py
+++ b/tailbone/util.py
@@ -201,6 +201,9 @@ def get_liburl(request, key, fallback=True):
static = importlib.import_module(static)
needed = request.environ['fanstatic.needed']
liburl = needed.library_url(static.libcache) + '/'
+ # nb. add custom url prefix if needed, e.g. /theo
+ if request.script_name:
+ liburl = request.script_name + liburl
if key == 'buefy':
return 'https://unpkg.com/buefy@{}/dist/buefy.min.js'.format(version)
From d6939e52b48bd5d6b947deb67a241782c321b7f0 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Sun, 30 Jun 2024 18:25:01 -0500
Subject: [PATCH 206/388] fix: use vue 3.4.31 and oruga 0.8.12 by default
i.e. for butterball theme
cf. https://github.com/oruga-ui/oruga/issues/974#issuecomment-2198573369
---
tailbone/util.py | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/tailbone/util.py b/tailbone/util.py
index 78c41313..98a7f7d4 100644
--- a/tailbone/util.py
+++ b/tailbone/util.py
@@ -162,11 +162,10 @@ def get_libver(request, key, fallback=True, default_only=False):
return '5.3.1'
elif key == 'bb_vue':
- # TODO: iiuc vue 3.4 does not work with oruga yet
- return '3.3.11'
+ return '3.4.31'
elif key == 'bb_oruga':
- return '0.8.9'
+ return '0.8.12'
elif key in ('bb_oruga_bulma', 'bb_oruga_bulma_css'):
return '0.3.0'
From cad50c9149143eff8c6329e77d3c20015d0f0331 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Sun, 30 Jun 2024 21:28:56 -0500
Subject: [PATCH 207/388] =?UTF-8?q?bump:=20version=200.11.4=20=E2=86=92=20?=
=?UTF-8?q?0.11.5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
CHANGELOG.md | 10 ++++++++++
setup.cfg | 2 +-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8d92a99e..510aa6a1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,16 @@ All notable changes to Tailbone 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.11.5 (2024-06-30)
+
+### Fix
+
+- allow comma in numeric filter input
+
+- add custom url prefix if needed, for fanstatic
+
+- use vue 3.4.31 and oruga 0.8.12 by default
+
## v0.11.4 (2024-06-30)
### Fix
diff --git a/setup.cfg b/setup.cfg
index 82cf3b25..4ee92f01 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,7 +1,7 @@
[metadata]
name = Tailbone
-version = 0.11.4
+version = 0.11.5
author = Lance Edgar
author_email = lance@edbob.org
url = http://rattailproject.org/
From 6f8b825b0b24370af4a66cac02e4faa2eb43fee1 Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Mon, 1 Jul 2024 15:23:56 -0500
Subject: [PATCH 208/388] fix: set explicit referrer when changing dbkey
since for some reason HTTP_REFERER is not always set now??
---
tailbone/templates/themes/butterball/base.mako | 1 +
1 file changed, 1 insertion(+)
diff --git a/tailbone/templates/themes/butterball/base.mako b/tailbone/templates/themes/butterball/base.mako
index 339d23bd..e38696c5 100644
--- a/tailbone/templates/themes/butterball/base.mako
+++ b/tailbone/templates/themes/butterball/base.mako
@@ -747,6 +747,7 @@
${h.form(url('change_db_engine'), ref='dbPickerForm')}
${h.csrf_token(request)}
${h.hidden('engine_type', value=master.engine_type_key)}
+
From 2feb07e1d3488a798028be3ab7cc63b3ef40de1c Mon Sep 17 00:00:00 2001
From: Lance Edgar
Date: Mon, 1 Jul 2024 17:01:01 -0500
Subject: [PATCH 209/388] fix: remove references, dependency for `six` package
---
setup.cfg | 1 -
tailbone/api/batch/labels.py | 10 ++---
tailbone/api/customers.py | 8 +---
tailbone/api/people.py | 8 +---
tailbone/api/upgrades.py | 8 +---
tailbone/api/vendors.py | 8 +---
tailbone/api/workorders.py | 20 ++++------
tailbone/exceptions.py | 7 +---
tailbone/handler.py | 9 ++---
tailbone/subscribers.py | 2 -
tailbone/templates/base.mako | 2 +-
tailbone/templates/configure.mako | 2 +-
tailbone/templates/custorders/items/view.mako | 2 +-
tailbone/templates/generate_feature.mako | 2 +-
tailbone/templates/ordering/worksheet.mako | 4 +-
tailbone/templates/poser/views/configure.mako | 2 +-
tailbone/templates/products/batch.mako | 2 +-
tailbone/templates/shifts/base.mako | 4 +-
.../templates/themes/butterball/base.mako | 2 +-
.../trainwreck/transactions/configure.mako | 2 +-
.../trainwreck/transactions/rollover.mako | 2 +-
tailbone/tweens.py | 7 +---
tailbone/views/batch/labels.py | 16 +++-----
tailbone/views/batch/pricing.py | 24 +++++------
tailbone/views/batch/vendorinvoice.py | 16 +++-----
tailbone/views/exports.py | 24 ++++-------
tailbone/views/poser/reports.py | 14 +++----
tailbone/views/poser/views.py | 40 +++++++++----------
tailbone/views/progress.py | 8 +---
tailbone/views/tempmon/appliances.py | 16 ++++----
tailbone/views/vendors/core.py | 14 +++----
31 files changed, 105 insertions(+), 181 deletions(-)
diff --git a/setup.cfg b/setup.cfg
index 4ee92f01..8afd9be4 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -56,7 +56,6 @@ install_requires =
pyramid_retry
pyramid_tm
rattail[db,bouncer]
- six
sa-filters
simplejson
transaction
diff --git a/tailbone/api/batch/labels.py b/tailbone/api/batch/labels.py
index 4787aeb9..4f154b21 100644
--- a/tailbone/api/batch/labels.py
+++ b/tailbone/api/batch/labels.py
@@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
-# Copyright © 2010-2022 Lance Edgar
+# Copyright © 2010-2024 Lance Edgar
#
# This file is part of Rattail.
#
@@ -24,10 +24,6 @@
Tailbone Web API - Label Batches
"""
-from __future__ import unicode_literals, absolute_import
-
-import six
-
from rattail.db import model
from tailbone.api.batch import APIBatchView, APIBatchRowView
@@ -56,10 +52,10 @@ class LabelBatchRowViews(APIBatchRowView):
def normalize(self, row):
batch = row.batch
- data = super(LabelBatchRowViews, self).normalize(row)
+ data = super().normalize(row)
data['item_id'] = row.item_id
- data['upc'] = six.text_type(row.upc)
+ data['upc'] = str(row.upc)
data['upc_pretty'] = row.upc.pretty() if row.upc else None
data['brand_name'] = row.brand_name
data['description'] = row.description
diff --git a/tailbone/api/customers.py b/tailbone/api/customers.py
index e9953572..85d28c24 100644
--- a/tailbone/api/customers.py
+++ b/tailbone/api/customers.py
@@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
-# Copyright © 2010-2022 Lance Edgar
+# Copyright © 2010-2024 Lance Edgar
#
# This file is part of Rattail.
#
@@ -24,10 +24,6 @@
Tailbone Web API - Customer Views
"""
-from __future__ import unicode_literals, absolute_import
-
-import six
-
from rattail.db import model
from tailbone.api import APIMasterView
@@ -46,7 +42,7 @@ class CustomerView(APIMasterView):
def normalize(self, customer):
return {
'uuid': customer.uuid,
- '_str': six.text_type(customer),
+ '_str': str(customer),
'id': customer.id,
'number': customer.number,
'name': customer.name,
diff --git a/tailbone/api/people.py b/tailbone/api/people.py
index 7e06e969..f7c08dfa 100644
--- a/tailbone/api/people.py
+++ b/tailbone/api/people.py
@@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
-# Copyright © 2010-2022 Lance Edgar
+# Copyright © 2010-2024 Lance Edgar
#
# This file is part of Rattail.
#
@@ -24,10 +24,6 @@
Tailbone Web API - Person Views
"""
-from __future__ import unicode_literals, absolute_import
-
-import six
-
from rattail.db import model
from tailbone.api import APIMasterView
@@ -45,7 +41,7 @@ class PersonView(APIMasterView):
def normalize(self, person):
return {
'uuid': person.uuid,
- '_str': six.text_type(person),
+ '_str': str(person),
'first_name': person.first_name,
'last_name': person.last_name,
'display_name': person.display_name,
diff --git a/tailbone/api/upgrades.py b/tailbone/api/upgrades.py
index 6ce5f778..467c8a0d 100644
--- a/tailbone/api/upgrades.py
+++ b/tailbone/api/upgrades.py
@@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
-# Copyright © 2010-2022 Lance Edgar
+# Copyright © 2010-2024 Lance Edgar
#
# This file is part of Rattail.
#
@@ -24,10 +24,6 @@
Tailbone Web API - Upgrade Views
"""
-from __future__ import unicode_literals, absolute_import
-
-import six
-
from rattail.db import model
from tailbone.api import APIMasterView
@@ -53,7 +49,7 @@ class UpgradeView(APIMasterView):
data['status_code'] = None
else:
data['status_code'] = self.enum.UPGRADE_STATUS.get(upgrade.status_code,
- six.text_type(upgrade.status_code))
+ str(upgrade.status_code))
return data
diff --git a/tailbone/api/vendors.py b/tailbone/api/vendors.py
index 7fa61590..64311b1b 100644
--- a/tailbone/api/vendors.py
+++ b/tailbone/api/vendors.py
@@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
-# Copyright © 2010-2022 Lance Edgar
+# Copyright © 2010-2024 Lance Edgar
#
# This file is part of Rattail.
#
@@ -24,10 +24,6 @@
Tailbone Web API - Vendor Views
"""
-from __future__ import unicode_literals, absolute_import
-
-import six
-
from rattail.db import model
from tailbone.api import APIMasterView
@@ -44,7 +40,7 @@ class VendorView(APIMasterView):
def normalize(self, vendor):
return {
'uuid': vendor.uuid,
- '_str': six.text_type(vendor),
+ '_str': str(vendor),
'id': vendor.id,
'name': vendor.name,
}
diff --git a/tailbone/api/workorders.py b/tailbone/api/workorders.py
index eabe4cdb..19def6c4 100644
--- a/tailbone/api/workorders.py
+++ b/tailbone/api/workorders.py
@@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
-# Copyright © 2010-2022 Lance Edgar
+# Copyright © 2010-2024 Lance Edgar
#
# This file is part of Rattail.
#
@@ -24,12 +24,8 @@
Tailbone Web API - Work Order Views
"""
-from __future__ import unicode_literals, absolute_import
-
import datetime
-import six
-
from rattail.db.model import WorkOrder
from cornice import Service
@@ -44,19 +40,19 @@ class WorkOrderView(APIMasterView):
object_url_prefix = '/workorder'
def __init__(self, *args, **kwargs):
- super(WorkOrderView, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
app = self.get_rattail_app()
self.workorder_handler = app.get_workorder_handler()
def normalize(self, workorder):
- data = super(WorkOrderView, self).normalize(workorder)
+ data = super().normalize(workorder)
data.update({
'customer_name': workorder.customer.name,
'status_label': self.enum.WORKORDER_STATUS[workorder.status_code],
- 'date_submitted': six.text_type(workorder.date_submitted or ''),
- 'date_received': six.text_type(workorder.date_received or ''),
- 'date_released': six.text_type(workorder.date_released or ''),
- 'date_delivered': six.text_type(workorder.date_delivered or ''),
+ 'date_submitted': str(workorder.date_submitted or ''),
+ 'date_received': str(workorder.date_received or ''),
+ 'date_released': str(workorder.date_released or ''),
+ 'date_delivered': str(workorder.date_delivered or ''),
})
return data
@@ -87,7 +83,7 @@ class WorkOrderView(APIMasterView):
if 'status_code' in data:
data['status_code'] = int(data['status_code'])
- return super(WorkOrderView, self).update_object(workorder, data)
+ return super().update_object(workorder, data)
def status_codes(self):
"""
diff --git a/tailbone/exceptions.py b/tailbone/exceptions.py
index beea1366..3468562a 100644
--- a/tailbone/exceptions.py
+++ b/tailbone/exceptions.py
@@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
-# Copyright © 2010-2020 Lance Edgar
+# Copyright © 2010-2024 Lance Edgar
#
# This file is part of Rattail.
#
@@ -24,10 +24,6 @@
Tailbone Exceptions
"""
-from __future__ import unicode_literals, absolute_import
-
-import six
-
from rattail.exceptions import RattailError
@@ -37,7 +33,6 @@ class TailboneError(RattailError):
"""
-@six.python_2_unicode_compatible
class TailboneJSONFieldError(TailboneError):
"""
Error raised when JSON serialization of a form field results in an error.
diff --git a/tailbone/handler.py b/tailbone/handler.py
index db95bc71..22f33cca 100644
--- a/tailbone/handler.py
+++ b/tailbone/handler.py
@@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
-# Copyright © 2010-2023 Lance Edgar
+# Copyright © 2010-2024 Lance Edgar
#
# This file is part of Rattail.
#
@@ -24,9 +24,6 @@
Tailbone Handler
"""
-from __future__ import unicode_literals, absolute_import
-
-import six
from mako.lookup import TemplateLookup
from rattail.app import GenericHandler
@@ -41,7 +38,7 @@ class TailboneHandler(GenericHandler):
"""
def __init__(self, *args, **kwargs):
- super(TailboneHandler, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
# TODO: make templates dir configurable?
templates = [resource_path('rattail:templates/web')]
@@ -67,7 +64,7 @@ class TailboneHandler(GenericHandler):
Returns an iterator over all registered Tailbone providers.
"""
providers = get_all_providers(self.config)
- return six.itervalues(providers)
+ return providers.values()
def write_model_view(self, data, path, **kwargs):
"""
diff --git a/tailbone/subscribers.py b/tailbone/subscribers.py
index 3fcd1017..bd59a033 100644
--- a/tailbone/subscribers.py
+++ b/tailbone/subscribers.py
@@ -24,7 +24,6 @@
Event Subscribers
"""
-import six
import json
import datetime
import logging
@@ -177,7 +176,6 @@ def before_render(event):
renderer_globals['tailbone'] = tailbone
renderer_globals['model'] = request.rattail_config.get_model()
renderer_globals['enum'] = request.rattail_config.get_enum()
- renderer_globals['six'] = six
renderer_globals['json'] = json
renderer_globals['datetime'] = datetime
renderer_globals['colander'] = colander
diff --git a/tailbone/templates/base.mako b/tailbone/templates/base.mako
index f576473d..c4cbd648 100644
--- a/tailbone/templates/base.mako
+++ b/tailbone/templates/base.mako
@@ -890,7 +890,7 @@
% if request.user:
FeedbackFormData.userUUID = ${json.dumps(request.user.uuid)|n}
- FeedbackFormData.userName = ${json.dumps(six.text_type(request.user))|n}
+ FeedbackFormData.userName = ${json.dumps(str(request.user))|n}
% endif
diff --git a/tailbone/templates/configure.mako b/tailbone/templates/configure.mako
index 3aa60f31..f33779c8 100644
--- a/tailbone/templates/configure.mako
+++ b/tailbone/templates/configure.mako
@@ -236,7 +236,7 @@
% if input_file_template_settings is not Undefined:
ThisPage.methods.validateInputFileTemplateSettings = function() {
- % for tmpl in six.itervalues(input_file_templates):
+ % for tmpl in input_file_templates.values():
if (this.inputFileTemplateSettings['${tmpl['setting_mode']}'] == 'hosted') {
if (!this.inputFileTemplateSettings['${tmpl['setting_file']}']) {
if (!this.inputFileTemplateUploads['${tmpl['key']}']) {
diff --git a/tailbone/templates/custorders/items/view.mako b/tailbone/templates/custorders/items/view.mako
index 41567d41..f7a6dd0a 100644
--- a/tailbone/templates/custorders/items/view.mako
+++ b/tailbone/templates/custorders/items/view.mako
@@ -347,7 +347,7 @@
}
ThisPageData.orderItemStatuses = ${json.dumps(enum.CUSTORDER_ITEM_STATUS)|n}
- ThisPageData.orderItemStatusOptions = ${json.dumps([dict(key=k, label=v) for k, v in six.iteritems(enum.CUSTORDER_ITEM_STATUS)])|n}
+ ThisPageData.orderItemStatusOptions = ${json.dumps([dict(key=k, label=v) for k, v in enum.CUSTORDER_ITEM_STATUS.items()])|n}
ThisPageData.oldStatusCode = ${instance.status_code}
diff --git a/tailbone/templates/generate_feature.mako b/tailbone/templates/generate_feature.mako
index a7064331..18a26f58 100644
--- a/tailbone/templates/generate_feature.mako
+++ b/tailbone/templates/generate_feature.mako
@@ -296,7 +296,7 @@
% endfor
}
- % for key, form in six.iteritems(feature_forms):
+ % for key, form in feature_forms.items():
<% safekey = key.replace('-', '_') %>
ThisPageData.${safekey} = {
<% dform = feature_forms[key].make_deform_form() %>
diff --git a/tailbone/templates/ordering/worksheet.mako b/tailbone/templates/ordering/worksheet.mako
index e41fe15f..ca1abf6e 100644
--- a/tailbone/templates/ordering/worksheet.mako
+++ b/tailbone/templates/ordering/worksheet.mako
@@ -73,7 +73,7 @@