Allow jobs to run as pipelines
[mailman-postorious.git] / src / postorius / middleware.py
blob8eaafdf00b1361a63dabcb317a9aa0b035e4404e
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2015-2022 by the Free Software Foundation, Inc.
4 # This file is part of Postorius.
6 # Postorius is free software: you can redistribute it and/or modify it under
7 # the terms of the GNU General Public License as published by the Free
8 # Software Foundation, either version 3 of the License, or (at your option)
9 # any later version.
11 # Postorius is distributed in the hope that it will be useful, but WITHOUT
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 # more details.
16 # You should have received a copy of the GNU General Public License along with
17 # Postorius. If not, see <http://www.gnu.org/licenses/>.
19 import logging
20 from urllib.error import HTTPError
22 from django_mailman3.lib import mailman
23 from mailmanclient import MailmanConnectionError
25 from postorius import utils
26 from postorius.models import MailmanApiError
29 logger = logging.getLogger('postorius')
32 __all__ = [
33 'PostoriusMiddleware',
37 class PostoriusMiddleware(object):
38 def __init__(self, get_response=None):
39 self.get_response = get_response
41 def __call__(self, request):
42 return self.get_response(request)
44 def process_exception(self, request, exception):
45 if isinstance(exception, (MailmanApiError, MailmanConnectionError)):
46 logger.exception('Mailman REST API not available')
47 return utils.render_api_error(request)
48 elif isinstance(exception, HTTPError):
49 logger.exception('Un-handled exception: %s', str(exception))
50 return utils.render_client_error(request, exception)
53 class APICountingMiddleware:
54 """Counts the total number of API calls made to Core and prints summary.
56 It hooks into mailmanclient's hooking mechanism, facilitated by
57 ``django_mailman3.lib.mailman.mailmanclient_request_hook``. It stores the
58 parameter of each API call made in `self.api_call_counter()` and prints it
59 *before* returning the response in `__call__`.
61 It hooks up ``_trace_api_calls()`` method into the Hooks API. Even if the
62 hooking happens multiple times, it is only added once since it
63 deduplicates the hooks.
65 Output looks something like:
67 DEBUG: =======================
68 DEBUG: Handle reqsponse for /postorius/lists/mylist.lists.araj.me/settings/
69 DEBUG: View function was postorius.views.list.list_settings
70 DEBUG: 4 calls to API
71 DEBUG: [GET] http://localhost:8001/3.1/lists/mylist.lists.araj.me with None
72 DEBUG: [snip]
73 DEBUG: ======================
75 Note: If you don't see the output on console, check the 'postorius' logger
76 settings and make sure that it has `console` handler and level is set to
77 'DEBUG'.
79 """
81 def __init__(self, get_response=None):
82 self.get_response = get_response
83 mailman.mailmanclient_request_hook(self._trace_api_calls)
84 self.api_call_counter = []
85 self.view_func = ''
87 def __call__(self, request):
88 self.request = request
89 response = self.get_response(request)
90 logger.debug('=======================')
91 logger.debug('Handle reqsponse for %s', request.path)
92 logger.debug('View function was %s', self.view_func)
93 logger.debug('%s calls to API', len(self.api_call_counter))
94 for each in self.api_call_counter:
95 logger.debug(
96 '[%s] %s with %s',
97 each.get('method'),
98 each.get('url'),
99 each.get('data'),
101 logger.debug('=======================')
102 self.api_call_counter = []
103 return response
105 def _trace_api_calls(self, params):
106 """Hook that adds all the call parameters to self.api_call_counter.
108 :param params: List of request params from mailmanclient.
110 self.api_call_counter.append(params)
111 return params
113 def process_view(self, request, view_func, view_args, view_kwars):
114 """Get a pointer to view function object."""
115 self.view_func = '{}.{}'.format(
116 view_func.__module__, view_func.__name__