diff --git a/tailbone/api/__init__.py b/tailbone/api/__init__.py index 6c310fa7..d09c669a 100644 --- a/tailbone/api/__init__.py +++ b/tailbone/api/__init__.py @@ -27,7 +27,10 @@ Tailbone Web API from __future__ import unicode_literals, absolute_import from .core import APIView, api +from .master import APIMasterView def includeme(config): config.include('tailbone.api.auth') + config.include('tailbone.api.customers') + config.include('tailbone.api.users') diff --git a/tailbone/api/customers.py b/tailbone/api/customers.py new file mode 100644 index 00000000..75f1b438 --- /dev/null +++ b/tailbone/api/customers.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8; -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2018 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 . +# +################################################################################ +""" +Tailbone Web API - Customer Views +""" + +from __future__ import unicode_literals, absolute_import + +from rattail.db import model + +from tailbone.api import APIMasterView + + +class CustomerView(APIMasterView): + + model_class = model.Customer + + def normalize(self, customer): + return { + 'id': customer.id, + 'name': customer.name, + } + + +def includeme(config): + CustomerView.defaults(config) diff --git a/tailbone/api/master.py b/tailbone/api/master.py new file mode 100644 index 00000000..ff3261c9 --- /dev/null +++ b/tailbone/api/master.py @@ -0,0 +1,101 @@ +# -*- coding: utf-8; -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2018 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 . +# +################################################################################ +""" +Tailbone Web API - Master View +""" + +from __future__ import unicode_literals, absolute_import + +from tailbone.api import APIView, api +from tailbone.db import Session + + +class APIMasterView(APIView): + + @classmethod + def get_model_class(cls): + if hasattr(cls, 'model_class'): + return cls.model_class + raise NotImplementedError("must set `model_class` for {}".format(cls.__name__)) + + @classmethod + def get_model_key(cls): + if hasattr(cls, 'model_key'): + return cls.model_name + return cls.get_model_class().__name__.lower() + + @classmethod + def get_model_key_plural(cls): + if hasattr(cls, 'model_key_plural'): + return cls.model_key_plural + return '{}s'.format(cls.get_model_key()) + + @classmethod + def get_route_prefix(cls): + if hasattr(cls, 'route_prefix'): + return cls.route_prefix + return 'api.{}'.format(cls.get_model_key_plural()) + + @classmethod + def get_permission_prefix(cls): + if hasattr(cls, 'permission_prefix'): + return cls.permission_prefix + return cls.get_model_key_plural() + + @classmethod + def get_url_prefix(cls): + if hasattr(cls, 'url_prefix'): + return cls.url_prefix + return '/api/{}'.format(cls.get_model_key_plural()) + + @property + def Session(self): + return Session + + @api + def index(self): + objects = self.Session.query(self.model_class) + + sort = self.request.params.get('sort') + if sort: + # TODO: this is fragile, but what to do if bad params? + sortkey, sortdir = sort.split('|') + sortkey = getattr(self.model_class, sortkey) + objects = objects.order_by(getattr(sortkey, sortdir)()) + + data = [self.normalize(obj) for obj in objects] + return data + + def normalize(self, obj): + raise NotImplementedError("must implement `normalize()` method for: {}".format(self.__class__.__name__)) + + @classmethod + def defaults(cls, config): + route_prefix = cls.get_route_prefix() + url_prefix = cls.get_url_prefix() + permission_prefix = cls.get_permission_prefix() + + # index + config.add_route(route_prefix, '{}/'.format(url_prefix), request_method='GET') + config.add_view(cls, attr='index', route_name=route_prefix, + renderer='json', permission='{}.list'.format(permission_prefix)) diff --git a/tailbone/api/users.py b/tailbone/api/users.py new file mode 100644 index 00000000..56cf17fd --- /dev/null +++ b/tailbone/api/users.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8; -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2018 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 . +# +################################################################################ +""" +Tailbone Web API - User Views +""" + +from __future__ import unicode_literals, absolute_import + +import six + +from rattail.db import model + +from tailbone.api import APIMasterView + + +class UserView(APIMasterView): + + model_class = model.User + + def normalize(self, user): + return { + 'username': user.username, + 'person': six.text_type(user.person or ''), + } + + +def includeme(config): + UserView.defaults(config)