1#!/usr/bin/env python3
 2
 3"""Modifier to extend the context object passed to all templates.
 4"""
 5
 6
 7
 8import sys
 9from io import StringIO
10import logging
11
12from django.http.response import Http404
13
14from chart.project import settings
15from chart.common import sendmail
16from chart.common import errors
17
18
19def add_settings(request):  # (unused arg) pylint: disable=W0613
20    """Add `settings` option for all templates.
21    """
22
23    return {'settings': settings}
24
25
26class EmailAlerts:
27    """Django middleware to send an email when a web view function throws an exception.
28    The email includes exception description and a call stack including local variables.
29    """
30
31    def process_exception(self, request, exception):
32        """This function returns nothing. We let the normal Django handler send a response
33        to the user.
34        This function inserts an entry to the web.log file and may send an email alert too.
35        """
36
37        raw_uri = request.META.get('RAW_URI', request.META.get('PATH_INFO'))
38
39        logging.error('Exception {exc} at URL {url}'.format(exc=exception, url=raw_uri))
40
41        if settings.DEBUG:
42            return
43
44        if isinstance(exception, Http404):
45            return
46
47        if 'HTTP_HOST' in str(exception):
48            # get rid of errors from some kind of virus / security scanner
49            return
50
51        subject = 'Error in ' + request.META['PATH_INFO']
52
53        message = StringIO()
54        message.write("""Exception summary:
55  Class: {cls}
56  Message: {mess}
57  URL: {url}
58""".format(cls=type(exception), mess=exception, url=raw_uri))
59
60        message.write("""
61Core dump:
62""")
63        errors.display_tb(sys.exc_info()[2], indent='  ', target=message)
64
65        # record the traceback here otherwise it gets overwritten by the exception later in this
66        # function
67        # exc_str = traceback.format_exc()
68
69        # display_stack(message)
70
71        message.write("""
72Request:
73  """ + '\n  '.join(str(request).split('\n')))
74
75        # print 'request ', request
76        # print 'exception ', exception
77
78        # logging.info('name ' + settings.EMAIL_NAME.format('web'))
79        # logging.info('address ' + settings.EMAIL_ADDRESS.format('web'))
80        # logging.info('admins ' + str(settings.ADMINS))
81        # logging.info('prefix ' + settings.EMAIL_SUBJECT_PREFIX)
82        # logging.info('subject ' + subject)
83
84        # logging.info('message ' + message.getvalue())
85
86        sendmail.sendmail((settings.EMAIL_NAME.format('web'),
87                           settings.EMAIL_ADDRESS.format('web')),
88                          settings.ADMINS,
89                          settings.EMAIL_SUBJECT_PREFIX + subject,
90                          message.getvalue())