diff --git a/README.rst b/README.rst index 568916b..7aa0dfd 100644 --- a/README.rst +++ b/README.rst @@ -4,10 +4,19 @@ Error Tracker **Full featured error tracking module for Python apps supports Flask and Django** +.. image:: https://img.shields.io/pypi/v/error-tracker.svg?color=dark-green + :target: https://pypi.org/project/error-tracker + +.. image:: https://img.shields.io/pypi/pyversions/error-tracker.svg?color=dark-green + :target: https://pypi.org/project/error-tracker + +.. image:: https://img.shields.io/github/license/sonus21/error-tracker.svg?color=dark-green + :target: https://github.com/sonus21/error-tracker/blob/master/LICENSE.txt + .. image:: https://travis-ci.org/sonus21/error-tracker.svg?branch=master :target: https://travis-ci.org/sonus21/error-tracker -.. image:: https://coveralls.io/repos/github/sonus21/error-tracker/badge.svg +.. image:: https://coveralls.io/repos/github/sonus21/error-tracker/badge.svg?color=dark-green :target: https://coveralls.io/github/sonus21/error-tracker Introduction diff --git a/docs/source/index.rst b/docs/source/index.rst index 8723bd9..53c876b 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -145,7 +145,7 @@ We need to update settings.py file as .. [1] This should be added at the end so that it can process exception 1st in the middleware call stack. .. note:: - Exception listing page is only enable for admin by default. + Exception listing page is only enable for super users by default. You can enable for others by providing a custom implementation of ViewPermissionMixin. This class must return True/False based on the current request, False means not authorized, True means authorized. @@ -155,7 +155,7 @@ We need to update settings.py file as APP_ERROR_RECIPIENT_EMAIL = ('example@example.com',) APP_ERROR_SUBJECT_PREFIX = "Server Error" APP_ERROR_EMAIL_SENDER = 'user@example.com' - # optional setting otherwise it's enabled for admin only + # optional setting otherwise it's enabled for super users only APP_ERROR_VIEW_PERMISSION = 'permission.ErrorViewPermission' INSTALLED_APPS = [ diff --git a/error_tracker/__init__.py b/error_tracker/__init__.py index fce4ace..0580b9f 100644 --- a/error_tracker/__init__.py +++ b/error_tracker/__init__.py @@ -6,7 +6,7 @@ # :license: BSD-3-Clause # -__version__ = '1.1.3' +__version__ = '1.1.5' __author__ = 'Sonu Kumar' __email__ = 'sonunitw12@gmail.com' diff --git a/error_tracker/django/utils.py b/error_tracker/django/utils.py index 0ca167d..40d016d 100644 --- a/error_tracker/django/utils.py +++ b/error_tracker/django/utils.py @@ -11,17 +11,20 @@ from django.http import RawPostDataException from error_tracker.libs.mixins import ContextBuilderMixin, NotificationMixin, ViewPermissionMixin +from error_tracker.libs.utils import get_context_dict from django.core.mail import send_mail -# noinspection PyMethodMayBeStatic class DefaultDjangoContextBuilder(ContextBuilderMixin): """ Default request builder, this records, form data, header and URL parameters and mask them if necessary """ - def _get_form_data(self, request): + @staticmethod + def _get_form_data(request): form = {} + if request is None: + return form post = request.POST if post is None or len(post) == 0: body = None @@ -46,37 +49,28 @@ def _get_form_data(self, request): form = post.dict() return form - def _get_headers(self, request): - try: - headers = request.headers.dict() - except AttributeError: - regex = re.compile('^HTTP_') - headers = dict((regex.sub('', header), value) for (header, value) - in request.META.items() if header.startswith('HTTP_')) - return headers + @staticmethod + def _get_headers(request): + if request is not None: + try: + headers = request.headers.dict() + except AttributeError: + regex = re.compile('^HTTP_') + headers = dict((regex.sub('', header), value) for (header, value) + in request.META.items() if header.startswith('HTTP_')) + return headers - def get_context(self, request, masking=None, additional_context=None): - request_data = dict() - if additional_context is not None and len(additional_context) != 0: - request_data['context'] = additional_context + @staticmethod + def _get_args(request): if request is not None: - form = self._get_form_data(request) - headers = self._get_headers(request) - if masking: - for key in form: - masked, value = masking(key) - if masked: - form[key] = value - for key in headers: - masked, value = masking(key) - if masked: - headers[key] = value - request_data.update({ - 'headers': headers, - 'args': request.GET.dict(), - 'form': form, - }) - return str(request_data) + return request.GET.dict() + + def get_context(self, request, masking=None, additional_context=None): + return str(get_context_dict(headers=self._get_headers(request), + form=self._get_form_data(request), + args=self._get_args(request), + context=additional_context, + masking=masking)) class DjangoNotification(NotificationMixin): diff --git a/error_tracker/libs/utils.py b/error_tracker/libs/utils.py index 1b98c0b..3983712 100644 --- a/error_tracker/libs/utils.py +++ b/error_tracker/libs/utils.py @@ -120,3 +120,29 @@ def get_class_instance(module_path, mixin, default, message_prefix, *args): message = "Default " + message_prefix + " module will be used" warnings.warn(message) return default(*args) + + +def get_context_dict(headers=None, context=None, form=None, args=None, masking=None): + request_data = dict() + form = form or {} + headers = headers or {} + args = args or {} + context = context or {} + if len(context) != 0: + request_data['context'] = context + if masking: + for key in form: + masked, value = masking(key) + if masked: + form[key] = value + for key in headers: + masked, value = masking(key) + if masked: + headers[key] = value + if len(headers) != 0: + request_data['headers'] = headers + if len(args) != 0: + request_data['args'] = args + if len(form) != 0: + request_data['form'] = form + return request_data