Remove old-style continuum version views

This commit is contained in:
Lance Edgar 2017-07-06 00:19:31 -05:00
parent 83751f7c9e
commit 66cc6cd39a
10 changed files with 11 additions and 357 deletions

View file

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8; -*-
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2015 Lance Edgar # Copyright © 2010-2017 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -29,7 +29,6 @@ from __future__ import unicode_literals, absolute_import
from rattail.db import model from rattail.db import model
from tailbone.views import MasterView, AutocompleteView from tailbone.views import MasterView, AutocompleteView
from tailbone.views.continuum import VersionView, version_defaults
class BrandsView(MasterView): class BrandsView(MasterView):
@ -56,14 +55,6 @@ class BrandsView(MasterView):
return fs return fs
class BrandVersionView(VersionView):
"""
View which shows version history for a brand.
"""
parent_class = model.Brand
route_model_view = 'brands.view'
class BrandsAutocomplete(AutocompleteView): class BrandsAutocomplete(AutocompleteView):
mapped_class = model.Brand mapped_class = model.Brand
@ -78,4 +69,3 @@ def includeme(config):
renderer='json', permission='brands.list') renderer='json', permission='brands.list')
BrandsView.defaults(config) BrandsView.defaults(config)
version_defaults(config, BrandVersionView, 'brand')

View file

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8; -*-
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2016 Lance Edgar # Copyright © 2010-2017 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -29,7 +29,6 @@ from __future__ import unicode_literals, absolute_import
from rattail.db import model from rattail.db import model
from tailbone.views import MasterView from tailbone.views import MasterView
from tailbone.views.continuum import VersionView, version_defaults
class CategoriesView(MasterView): class CategoriesView(MasterView):
@ -64,16 +63,5 @@ class CategoriesView(MasterView):
return fs return fs
class CategoryVersionView(VersionView):
"""
View which shows version history for a category.
"""
parent_class = model.Category
model_title_plural = "Categories"
route_model_list = 'categories'
route_model_view = 'categories.view'
def includeme(config): def includeme(config):
CategoriesView.defaults(config) CategoriesView.defaults(config)
version_defaults(config, CategoryVersionView, 'category', template_prefix='/categories')

View file

@ -1,229 +0,0 @@
# -*- coding: utf-8 -*-
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2015 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 Affero 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 Affero General Public License for
# more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Rattail. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
Continuum Version Views
"""
from __future__ import unicode_literals
import sqlalchemy as sa
import sqlalchemy_continuum as continuum
from rattail.db import model
from rattail.db.continuum import model_transaction_query
import formalchemy
from pyramid.httpexceptions import HTTPNotFound
from tailbone.db import Session
from tailbone.views import PagedAlchemyGridView, View
class VersionView(PagedAlchemyGridView):
"""
View which shows version history for a model instance.
"""
@property
def parent_class(self):
"""
Model class which is "parent" to the version class.
"""
raise NotImplementedError("Please set `parent_class` on your `VersionView` subclass.")
@property
def child_classes(self):
"""
Model class(es) which are "children" to the version's parent class.
"""
return []
@property
def model_title(self):
"""
Human-friendly title for the parent model class.
"""
return self.parent_class.__name__
@property
def model_title_plural(self):
"""
Plural version of the human-friendly title for the parent model class.
"""
return '{0}s'.format(self.model_title)
@property
def prefix(self):
return self.parent_class.__name__.lower()
@property
def config_prefix(self):
return self.prefix
@property
def transaction_class(self):
return continuum.transaction_class(self.parent_class)
@property
def mapped_class(self):
return self.transaction_class
@property
def version_class(self):
return continuum.version_class(self.parent_class)
@property
def route_model_list(self):
return '{0}s'.format(self.prefix)
@property
def route_model_view(self):
return self.prefix
def join_map(self):
return {
'user':
lambda q: q.outerjoin(model.User, self.transaction_class.user_uuid == model.User.uuid),
}
def sort_config(self):
return self.make_sort_config(sort='issued_at', dir='desc')
def sort_map(self):
return self.make_sort_map('issued_at', 'remote_addr',
user=self.sorter(model.User.username))
def transaction_query(self, session=Session):
uuid = self.request.matchdict['uuid']
return model_transaction_query(session, uuid, self.parent_class,
child_classes=self.child_classes)
def make_query(self, session=Session):
query = self.transaction_query(session)
return self.modify_query(query)
def grid(self):
g = self.make_grid()
g.configure(
include=[
g.issued_at.label("When"),
g.user.label("Who"),
g.remote_addr.label("Client IP"),
],
readonly=True)
g.viewable = True
g.view_route_name = '{0}.version'.format(self.prefix)
g.view_route_kwargs = self.view_route_kwargs
return g
def render_kwargs(self):
instance = Session.query(self.parent_class).get(self.request.matchdict['uuid'])
return {'model_title': self.model_title,
'model_title_plural': self.model_title_plural,
'model_instance': instance,
'route_model_list': self.route_model_list,
'route_model_view': self.route_model_view}
def view_route_kwargs(self, transaction):
return {'uuid': self.request.matchdict['uuid'],
'transaction_id': transaction.id}
def list(self):
"""
View which shows the version history list for a model instance.
"""
return self()
def details(self):
"""
View which shows the change details of a model version.
"""
kwargs = self.render_kwargs()
uuid = self.request.matchdict['uuid']
transaction_id = self.request.matchdict['transaction_id']
transaction = Session.query(self.transaction_class).get(transaction_id)
if not transaction:
raise HTTPNotFound
version = Session.query(self.version_class).get((uuid, transaction_id))
def normalize_child_classes():
classes = []
for cls in self.child_classes:
if not isinstance(cls, tuple):
cls = (cls, 'uuid')
classes.append(cls)
return classes
versions = []
if version:
versions.append(version)
for model_class, attr in normalize_child_classes():
if isinstance(model_class, type) and issubclass(model_class, model.Base):
cls = continuum.version_class(model_class)
ver = Session.query(cls).filter_by(transaction_id=transaction_id, **{attr: uuid}).first()
if ver:
versions.append(ver)
previous_transaction = self.transaction_query()\
.order_by(self.transaction_class.id.desc())\
.filter(self.transaction_class.id < transaction.id)\
.first()
next_transaction = self.transaction_query()\
.order_by(self.transaction_class.id.asc())\
.filter(self.transaction_class.id > transaction.id)\
.first()
kwargs.update({
'route_prefix': self.prefix,
'version': version,
'transaction': transaction,
'versions': versions,
'parent_class': continuum.parent_class,
'previous_transaction': previous_transaction,
'next_transaction': next_transaction,
})
return kwargs
def version_defaults(config, VersionView, prefix, template_prefix=None):
"""
Apply default route/view configuration for the given ``VersionView``.
"""
if template_prefix is None:
template_prefix = '/{0}s'.format(prefix)
template_prefix = template_prefix.rstrip('/')
# list changesets
config.add_route('{0}.versions'.format(prefix), '/{0}/{{uuid}}/changesets/'.format(prefix))
config.add_view(VersionView, attr='list', route_name='{0}.versions'.format(prefix),
renderer='{0}/versions/index.mako'.format(template_prefix),
permission='{0}.versions.view'.format(prefix))
# view changeset
config.add_route('{0}.version'.format(prefix), '/{0}/{{uuid}}/changeset/{{transaction_id}}'.format(prefix))
config.add_view(VersionView, attr='details', route_name='{0}.version'.format(prefix),
renderer='{0}/versions/view.mako'.format(template_prefix),
permission='{0}.versions.view'.format(prefix))

View file

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8; -*-
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2016 Lance Edgar # Copyright © 2010-2017 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -29,7 +29,6 @@ from __future__ import unicode_literals, absolute_import
from rattail.db import model from rattail.db import model
from tailbone.views import MasterView, AutocompleteView, AlchemyGridView from tailbone.views import MasterView, AutocompleteView, AlchemyGridView
from tailbone.views.continuum import VersionView, version_defaults
from tailbone.newgrids import AlchemyGrid, GridAction from tailbone.newgrids import AlchemyGrid, GridAction
@ -81,14 +80,6 @@ class DepartmentsView(MasterView):
return kwargs return kwargs
class DepartmentVersionView(VersionView):
"""
View which shows version history for a department.
"""
parent_class = model.Department
route_model_view = 'departments.view'
class DepartmentsByVendorGrid(AlchemyGridView): class DepartmentsByVendorGrid(AlchemyGridView):
mapped_class = model.Department mapped_class = model.Department
@ -134,4 +125,3 @@ def includeme(config):
permission='departments.list') permission='departments.list')
DepartmentsView.defaults(config) DepartmentsView.defaults(config)
version_defaults(config, DepartmentVersionView, 'department')

View file

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8; -*-
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2016 Lance Edgar # Copyright © 2010-2017 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -33,7 +33,6 @@ from pyramid.httpexceptions import HTTPFound
from tailbone import forms from tailbone import forms
from tailbone.db import Session from tailbone.db import Session
from tailbone.views import MasterView from tailbone.views import MasterView
from tailbone.views.continuum import VersionView, version_defaults
class ProfilesView(MasterView): class ProfilesView(MasterView):
@ -83,16 +82,6 @@ class ProfilesView(MasterView):
pass pass
class LabelProfileVersionView(VersionView):
"""
View which shows version history for a label profile.
"""
parent_class = model.LabelProfile
model_title = "Label Profile"
route_model_list = 'label_profiles'
route_model_view = 'labelprofiles.view'
def printer_settings(request): def printer_settings(request):
uuid = request.matchdict['uuid'] uuid = request.matchdict['uuid']
profile = Session.query(model.LabelProfile).get(uuid) if uuid else None profile = Session.query(model.LabelProfile).get(uuid) if uuid else None
@ -123,7 +112,6 @@ def printer_settings(request):
def includeme(config): def includeme(config):
ProfilesView.defaults(config) ProfilesView.defaults(config)
version_defaults(config, LabelProfileVersionView, 'labelprofile', template_prefix='/labels/profiles')
# edit printer settings # edit printer settings
config.add_route('labelprofiles.printer_settings', '/labels/profiles/{uuid}/printer') config.add_route('labelprofiles.printer_settings', '/labels/profiles/{uuid}/printer')

View file

@ -49,7 +49,6 @@ from webhelpers.html import tags
from tailbone import forms, newgrids as grids from tailbone import forms, newgrids as grids
from tailbone.db import Session from tailbone.db import Session
from tailbone.views import MasterView, SearchableAlchemyGridView, AutocompleteView from tailbone.views import MasterView, SearchableAlchemyGridView, AutocompleteView
from tailbone.views.continuum import VersionView, version_defaults
from tailbone.progress import SessionProgress from tailbone.progress import SessionProgress
@ -539,37 +538,6 @@ class ProductsView(MasterView):
config.add_view(cls, attr='image', route_name='products.image') config.add_view(cls, attr='image', route_name='products.image')
class ProductVersionView(VersionView):
"""
View which shows version history for a product.
"""
parent_class = model.Product
route_model_view = 'product.read'
child_classes = [
(model.ProductCode, 'product_uuid'),
(model.ProductCost, 'product_uuid'),
(model.ProductPrice, 'product_uuid'),
]
def warn_if_deleted(self):
"""
Maybe set flash warning if product is marked deleted.
"""
uuid = self.request.matchdict['uuid']
product = Session.query(model.Product).get(uuid)
assert product, "No product found for UUID: {}".format(repr(uuid))
if product.deleted:
self.request.session.flash("This product is marked as deleted.", 'error')
def list(self):
self.warn_if_deleted()
return super(ProductVersionView, self).list()
def details(self):
self.warn_if_deleted()
return super(ProductVersionView, self).details()
class ProductsAutocomplete(AutocompleteView): class ProductsAutocomplete(AutocompleteView):
""" """
Autocomplete view for products. Autocomplete view for products.
@ -630,4 +598,3 @@ def includeme(config):
renderer='json', permission='products.print_labels') renderer='json', permission='products.print_labels')
ProductsView.defaults(config) ProductsView.defaults(config)
version_defaults(config, ProductVersionView, 'product')

View file

@ -1,4 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8; -*-
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
@ -38,7 +38,6 @@ from webhelpers.html import HTML, tags
from tailbone import forms from tailbone import forms
from tailbone.db import Session from tailbone.db import Session
from tailbone.views.principal import PrincipalMasterView from tailbone.views.principal import PrincipalMasterView
from tailbone.views.continuum import VersionView, version_defaults
from tailbone.newgrids import AlchemyGrid, GridAction from tailbone.newgrids import AlchemyGrid, GridAction
@ -140,14 +139,5 @@ class PermissionsField(fa.Field):
role.permissions = self.renderer.deserialize() role.permissions = self.renderer.deserialize()
class RoleVersionView(VersionView):
"""
View which shows version history for a role.
"""
parent_class = model.Role
route_model_view = 'roles.view'
def includeme(config): def includeme(config):
RolesView.defaults(config) RolesView.defaults(config)
version_defaults(config, RoleVersionView, 'role')

View file

@ -1,4 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8; -*-
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
@ -30,7 +30,6 @@ from rattail.db import model
from tailbone.db import Session from tailbone.db import Session
from tailbone.views import MasterView from tailbone.views import MasterView
from tailbone.views.continuum import VersionView, version_defaults
class SubdepartmentsView(MasterView): class SubdepartmentsView(MasterView):
@ -88,14 +87,5 @@ class SubdepartmentsView(MasterView):
Session.delete(removing) Session.delete(removing)
class SubdepartmentVersionView(VersionView):
"""
View which shows version history for a subdepartment.
"""
parent_class = model.Subdepartment
route_model_view = 'subdepartments.view'
def includeme(config): def includeme(config):
SubdepartmentsView.defaults(config) SubdepartmentsView.defaults(config)
version_defaults(config, SubdepartmentVersionView, 'subdepartment')

View file

@ -1,4 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8; -*-
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
@ -41,7 +41,6 @@ from webhelpers.html import HTML, tags
from tailbone import forms from tailbone import forms
from tailbone.db import Session from tailbone.db import Session
from tailbone.views.principal import PrincipalMasterView from tailbone.views.principal import PrincipalMasterView
from tailbone.views.continuum import VersionView, version_defaults
def unique_username(value, field): def unique_username(value, field):
@ -252,14 +251,5 @@ class UsersView(PrincipalMasterView):
self.Session.delete(removing) self.Session.delete(removing)
class UserVersionView(VersionView):
"""
View which shows version history for a user.
"""
parent_class = model.User
route_model_view = 'users.view'
def includeme(config): def includeme(config):
UsersView.defaults(config) UsersView.defaults(config)
version_defaults(config, UserVersionView, 'user')

View file

@ -31,7 +31,6 @@ from rattail.db import model
from tailbone import forms from tailbone import forms
from tailbone.db import Session from tailbone.db import Session
from tailbone.views import MasterView, AutocompleteView from tailbone.views import MasterView, AutocompleteView
from tailbone.views.continuum import VersionView, version_defaults
class VendorsView(MasterView): class VendorsView(MasterView):
@ -87,14 +86,6 @@ class VendorsView(MasterView):
] ]
class VendorVersionView(VersionView):
"""
View which shows version history for a vendor.
"""
parent_class = model.Vendor
route_model_view = 'vendors.view'
class VendorsAutocomplete(AutocompleteView): class VendorsAutocomplete(AutocompleteView):
mapped_class = model.Vendor mapped_class = model.Vendor
@ -109,4 +100,3 @@ def includeme(config):
renderer='json', permission='vendors.list') renderer='json', permission='vendors.list')
VendorsView.defaults(config) VendorsView.defaults(config)
version_defaults(config, VendorVersionView, 'vendor')