Coverage for .tox/coverage/lib/python3.11/site-packages/wuttaweb/views/base.py: 100%
34 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-08-26 14:40 -0500
« prev ^ index » next coverage.py v7.6.1, created at 2024-08-26 14:40 -0500
1# -*- coding: utf-8; -*-
2################################################################################
3#
4# wuttaweb -- Web App for Wutta Framework
5# Copyright © 2024 Lance Edgar
6#
7# This file is part of Wutta Framework.
8#
9# Wutta Framework is free software: you can redistribute it and/or modify it
10# under the terms of the GNU General Public License as published by the Free
11# Software Foundation, either version 3 of the License, or (at your option) any
12# later version.
13#
14# Wutta Framework is distributed in the hope that it will be useful, but
15# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17# more details.
18#
19# You should have received a copy of the GNU General Public License along with
20# Wutta Framework. If not, see <http://www.gnu.org/licenses/>.
21#
22################################################################################
23"""
24Base Logic for Views
25"""
27import os
29from pyramid import httpexceptions
30from pyramid.renderers import render_to_response
31from pyramid.response import FileResponse
33from wuttaweb import forms, grids
36class View:
37 """
38 Base class for all class-based views.
40 Instances of this class (or rather, a subclass) are created by
41 Pyramid when processing a request. They will have the following
42 attributes:
44 .. attribute:: request
46 Reference to the current :term:`request` object.
48 .. attribute:: app
50 Reference to the :term:`app handler`.
52 .. attribute:: config
54 Reference to the app :term:`config object`.
55 """
57 def __init__(self, request, context=None):
58 self.request = request
59 self.config = self.request.wutta_config
60 self.app = self.config.get_app()
62 def forbidden(self):
63 """
64 Convenience method, to raise a HTTP 403 Forbidden exception::
66 raise self.forbidden()
67 """
68 return httpexceptions.HTTPForbidden()
70 def make_form(self, **kwargs):
71 """
72 Make and return a new :class:`~wuttaweb.forms.base.Form`
73 instance, per the given ``kwargs``.
75 This is the "base" factory which merely invokes the
76 constructor.
77 """
78 return forms.Form(self.request, **kwargs)
80 def make_grid(self, **kwargs):
81 """
82 Make and return a new :class:`~wuttaweb.grids.base.Grid`
83 instance, per the given ``kwargs``.
85 This is the "base" factory which merely invokes the
86 constructor.
87 """
88 return grids.Grid(self.request, **kwargs)
90 def make_grid_action(self, key, **kwargs):
91 """
92 Make and return a new :class:`~wuttaweb.grids.base.GridAction`
93 instance, per the given ``key`` and ``kwargs``.
95 This is the "base" factory which merely invokes the
96 constructor.
97 """
98 return grids.GridAction(self.request, key, **kwargs)
100 def notfound(self):
101 """
102 Convenience method, to raise a HTTP 404 Not Found exception::
104 raise self.notfound()
105 """
106 return httpexceptions.HTTPNotFound()
108 def redirect(self, url, **kwargs):
109 """
110 Convenience method to return a HTTP 302 response.
112 Note that this technically returns an "exception" - so in
113 your code, you can either return that error, or raise it::
115 return self.redirect('/')
116 # ..or
117 raise self.redirect('/')
119 Which you should do will depend on context, but raising the
120 error is always "safe" since Pyramid will handle that
121 correctly no matter what.
122 """
123 return httpexceptions.HTTPFound(location=url, **kwargs)
125 def file_response(self, path, attachment=True, filename=None):
126 """
127 Returns a generic file response for the given path.
129 :param path: Path to a file on local disk; must be accessible
130 by the web app.
132 :param attachment: Whether the file should come down as an
133 "attachment" instead of main payload.
135 The attachment behavior is the default here, and will cause
136 the user to be prompted for where to save the file.
138 Set ``attachment=False`` in order to cause the browser to
139 render the file as if it were the page being navigated to.
141 :param filename: Optional filename to use for attachment
142 behavior. This will be the "suggested filename" when user
143 is prompted to save the download. If not specified, the
144 filename is derived from ``path``.
146 :returns: A :class:`~pyramid:pyramid.response.FileResponse`
147 object with file content.
148 """
149 if not os.path.exists(path):
150 return self.notfound()
152 response = FileResponse(path, request=self.request)
153 response.content_length = os.path.getsize(path)
155 if attachment:
156 if not filename:
157 filename = os.path.basename(path)
158 response.content_disposition = f'attachment; filename="{filename}"'
160 return response
162 def json_response(self, context):
163 """
164 Returns a JSON response with the given context data.
166 :param context: Context data to be rendered as JSON.
168 :returns: A :term:`response` with JSON content type.
169 """
170 return render_to_response('json', context, request=self.request)