<commit_before># coding: utf-8

import csv

try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO

from django.conf.urls import url
from django.contrib import admin
from django.core.exceptions import PermissionDenied
from django.db.models import F, FloatField, ExpressionWrapper
from django.http import HttpResponseRedirect, HttpResponse

from speedinfo import profiler, settings
from speedinfo.models import ViewProfiler

try:
    from django.urls import reverse  # Django >= 1.10
except ImportError:
    from django.core.urlresolvers import reverse


class ViewProfilerAdmin(admin.ModelAdmin):
    list_display_links = None
    actions = None
    ordering = ('-total_time',)

    class Media:
        css = {
            'all': ('speedinfo/css/admin.css',)
        }

    def get_queryset(self, request):
        qs = super(ViewProfilerAdmin, self).get_queryset(request)
        return qs.annotate(
            percall=ExpressionWrapper(F('total_time') / F('total_calls'), output_field=FloatField())
        )

    def get_list_display(self, request):
        """Creates and returns list of callables to represent
        model field values with a custom format.

        :param request: Request object
        :type request: :class:`django.http.HttpRequest`
        :return: list containing fields to be displayed on the changelist
        """
        list_display = []

        for rc in settings.SPEEDINFO_REPORT_COLUMNS_FORMAT:
            if rc.attr_name in settings.SPEEDINFO_REPORT_COLUMNS:

                def wrapper(col):
                    def field_format(obj):
                        return col.format.format(getattr(obj, col.attr_name))
                    field_format.short_description = col.name
                    field_format.admin_order_field = col.order_field

                    return field_format

                list_display.append(
                    wrapper(rc)
                )

        return list_display

    def change_view(self, *args, **kwargs):
        raise PermissionDenied

    def has_add_permission(self, request):
        return False

    def has_delete_permission(self, request, obj=None):
        return False

    def changelist_view(self, request, extra_context=None):
        return super(ViewProfilerAdmin, self).changelist_view(request, extra_context={
            'title': 'Views profiler',
            'profiler_is_on': profiler.is_on,
        })

    def get_urls(self):
        return [
            url(r'^switch/$', self.admin_site.admin_view(self.switch), name='speedinfo-profiler-switch'),
            url(r'^export/$', self.admin_site.admin_view(self.export), name='speedinfo-profiler-export'),
            url(r'^reset/$', self.admin_site.admin_view(self.reset), name='speedinfo-profiler-reset'),
        ] + super(ViewProfilerAdmin, self).get_urls()

    def switch(self, request):
        profiler.is_on = not profiler.is_on
        return HttpResponseRedirect(reverse('admin:speedinfo_viewprofiler_changelist'))

    def export(self, request):
        """Exports profiling data as a comma-separated file.

        :param request: :class:`django.http.HttpRequest`<commit_msg>Fix broken admin sorting in Django >= 2.0.<commit_after># coding: utf-8

import csv

try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO

from django.conf.urls import url
from django.contrib import admin
from django.core.exceptions import PermissionDenied
from django.db.models import F, FloatField, ExpressionWrapper
from django.http import HttpResponseRedirect, HttpResponse

from speedinfo import profiler, settings
from speedinfo.models import ViewProfiler

try:
    from django.urls import reverse  # Django >= 1.10
except ImportError:
    from django.core.urlresolvers import reverse


def field_wrapper(col):
    """Helper function to dynamically create list display method
    for :class:`ViewProfilerAdmin` to control value formating
    and sort order.

    :type col: :data:`settings.ReportColumnFormat`
    :rtype: function
    """
    def field_format(obj):
        return col.format.format(getattr(obj, col.attr_name))

    field_format.short_description = col.name
    field_format.admin_order_field = col.order_field

    return field_format


class ViewProfilerAdmin(admin.ModelAdmin):
    list_display_links = None
    actions = None
    ordering = ('-total_time',)

    class Media:
        css = {
            'all': ('speedinfo/css/admin.css',)
        }

    def __init__(self, *args, **kwargs):
        """Initializes the list of visible columns and
        the way they are formating the values.
        """
        super(ViewProfilerAdmin, self).__init__(*args, **kwargs)
        self.list_display = []

        for rc in settings.SPEEDINFO_REPORT_COLUMNS_FORMAT:
            if rc.attr_name in settings.SPEEDINFO_REPORT_COLUMNS:
                method_name = '{}_wrapper'.format(rc.attr_name)
                setattr(self, method_name, field_wrapper(rc))
                self.list_display.append(method_name)

    def get_queryset(self, request):
        qs = super(ViewProfilerAdmin, self).get_queryset(request)
        return qs.annotate(
            percall=ExpressionWrapper(F('total_time') / F('total_calls'), output_field=FloatField())
        )

    def change_view(self, *args, **kwargs):
        raise PermissionDenied

    def has_add_permission(self, request):
        return False

    def has_delete_permission(self, request, obj=None):
        return False

    def changelist_view(self, request, extra_context=None):
        return super(ViewProfilerAdmin, self).changelist_view(request, extra_context={
            'title': 'Views profiler',
            'profiler_is_on': profiler.is_on,
        })

    def get_urls(self):
        return [
            url(r'^switch/$', self.admin_site.admin_view(self.switch), name='speedinfo-profiler-switch'),
            url(r'^export/$', self.admin_site.admin_view(self.export), name='speedinfo-profiler-export'),
            url(r'^reset/$', self.admin_site.admin_view(self.reset), name='speedinfo-profiler-reset'),
        ] + super(ViewProfilerAdmin, self).get_urls()

    def switch(self, request):
        profiler.is_on = not profiler.is_on
        return HttpResponseRedirect(reverse('admin:speedinfo_viewprofiler_changelist'))

    def export(self, request):
        """Exports profiling data as a comma-separated file.

        :param request: :class:`django.http.HttpRequest`
{'fraction_non_alphanumeric': 0.09646550393579256, 'fraction_numerical': 0.0015434480629726809, 'mean_word_length': 2.956043956043956, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1956078', 'n_tokens_mistral': 1883, 'n_tokens_neox': 1836, 'n_words': 437}