Add basic API view for user feedback

This commit is contained in:
Lance Edgar 2019-08-29 18:30:13 -05:00
parent d97f95fb92
commit 19c734683b
3 changed files with 137 additions and 29 deletions

78
tailbone/api/common.py Normal file
View file

@ -0,0 +1,78 @@
# -*- coding: utf-8; -*-
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2019 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 <http://www.gnu.org/licenses/>.
#
################################################################################
"""
Tailbone Web API - "Common" Views
"""
from __future__ import unicode_literals, absolute_import
from rattail.db import model
from rattail.mail import send_email
from tailbone import forms
from tailbone.forms.common import Feedback
from tailbone.api import APIView, api
from tailbone.db import Session
class CommonView(APIView):
@api
def feedback(self):
"""
View to handle user feedback form submits.
"""
# TODO: this logic was copied from tailbone.views.common and is largely
# identical; perhaps should merge somehow?
schema = Feedback().bind(session=Session())
form = forms.Form(schema=schema, request=self.request)
if form.validate(newstyle=True):
data = dict(form.validated)
# figure out who the sending user is, if any
if self.request.user:
data['user'] = self.request.user
elif data['user']:
data['user'] = Session.query(model.User).get(data['user'])
# TODO: should provide URL to view user
if data['user']:
data['user_url'] = '#' # TODO: could get from config?
data['client_ip'] = self.request.client_addr
send_email(self.rattail_config, 'user_feedback', data=data)
return {'ok': True}
return {'error': "Form did not validate!"}
@classmethod
def defaults(cls, config):
# feedback
config.add_route('api.feedback', '/feedback', request_method=('OPTIONS', 'POST'))
config.add_view(cls, attr='feedback', route_name='api.feedback', renderer='json')
def includeme(config):
CommonView.defaults(config)

58
tailbone/forms/common.py Normal file
View file

@ -0,0 +1,58 @@
# -*- coding: utf-8; -*-
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2019 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 <http://www.gnu.org/licenses/>.
#
################################################################################
"""
Common Forms
"""
from __future__ import unicode_literals, absolute_import
from rattail.db import model
import colander
@colander.deferred
def validate_user(node, kw):
session = kw['session']
def validate(node, value):
user = session.query(model.User).get(value)
if not user:
raise colander.Invalid(node, "User not found")
return user.uuid
return validate
class Feedback(colander.Schema):
"""
Form schema for user feedback.
"""
referrer = colander.SchemaNode(colander.String())
user = colander.SchemaNode(colander.String(),
missing=colander.null,
validator=validate_user)
user_name = colander.SchemaNode(colander.String(),
missing=colander.null)
message = colander.SchemaNode(colander.String())

View file

@ -35,45 +35,17 @@ from rattail.mail import send_email
from rattail.util import OrderedDict
from rattail.files import resource_path
import colander
from pyramid import httpexceptions
from pyramid.response import Response
import tailbone
from tailbone import forms
from tailbone.forms.common import Feedback
from tailbone.db import Session
from tailbone.views import View
from tailbone.util import set_app_theme
@colander.deferred
def validate_user(node, kw):
session = kw['session']
def validate(node, value):
user = session.query(model.User).get(value)
if not user:
raise colander.Invalid(node, "User not found")
return user.uuid
return validate
class Feedback(colander.Schema):
"""
Form schema for user feedback.
"""
referrer = colander.SchemaNode(colander.String())
user = colander.SchemaNode(colander.String(),
missing=colander.null,
validator=validate_user)
user_name = colander.SchemaNode(colander.String(),
missing=colander.null)
message = colander.SchemaNode(colander.String())
class CommonView(View):
"""
Base class for common views; override as needed.