Add basic API view for user feedback
This commit is contained in:
parent
d97f95fb92
commit
19c734683b
78
tailbone/api/common.py
Normal file
78
tailbone/api/common.py
Normal 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
58
tailbone/forms/common.py
Normal 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())
|
|
@ -35,45 +35,17 @@ from rattail.mail import send_email
|
||||||
from rattail.util import OrderedDict
|
from rattail.util import OrderedDict
|
||||||
from rattail.files import resource_path
|
from rattail.files import resource_path
|
||||||
|
|
||||||
import colander
|
|
||||||
from pyramid import httpexceptions
|
from pyramid import httpexceptions
|
||||||
from pyramid.response import Response
|
from pyramid.response import Response
|
||||||
|
|
||||||
import tailbone
|
import tailbone
|
||||||
from tailbone import forms
|
from tailbone import forms
|
||||||
|
from tailbone.forms.common import Feedback
|
||||||
from tailbone.db import Session
|
from tailbone.db import Session
|
||||||
from tailbone.views import View
|
from tailbone.views import View
|
||||||
from tailbone.util import set_app_theme
|
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):
|
class CommonView(View):
|
||||||
"""
|
"""
|
||||||
Base class for common views; override as needed.
|
Base class for common views; override as needed.
|
||||||
|
|
Loading…
Reference in a new issue