<commit_before>
from urllib import urlopen, urlencode
from uuid import uuid4

from django.conf import settings
from django.contrib import admin
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.core.urlresolvers import reverse, NoReverseMatch
from django.db.models import Model
from django.template import Context, Template
from django.template.loader import get_template
from django.utils.html import strip_tags
from django.utils.simplejson import loads
from django.utils.text import capfirst

from mezzanine import template
from mezzanine.core.forms import get_edit_form
from mezzanine.settings import load_settings as _load_settings
from mezzanine.utils import decode_html_entities, is_editable


mezz_settings = _load_settings("ADMIN_MENU_ORDER", "DASHBOARD_TAGS")

register = template.Library()


@register.render_tag
def load_settings(context, token):
    """
    Push the given setting names into the context.
    """
    names = token.split_contents()[1:]
    for name in names:
        if name not in context:
            mezz_settings = _load_settings(*names)
            for name in names:
                context[name] = getattr(mezz_settings, name)
            break
    return ""


@register.render_tag
def set_short_url_for(context, token):
    """
    Sets the ``short_url`` attribute of the given model using the bit.ly
    credentials if they have been specified and saves it.
    """
    obj = context[token.split_contents()[1]]
    request = context["request"]
    if getattr(obj, "short_url") is None:
        obj.short_url = request.build_absolute_uri(request.path)
        mezz_settings = _load_settings("BLOG_BITLY_USER", "BLOG_BITLY_KEY")
        args = {
            "login": mezz_settings.BLOG_BITLY_USER,
            "apiKey": mezz_settings.BLOG_BITLY_KEY,
            "longUrl": obj.short_url,
        }
        if args["login"] and args["apiKey"]:
            url = "http://api.bit.ly/v3/shorten?%s" % urlencode(args)
            response = loads(urlopen(url).read())
            if response["status_code"] == 200:
                obj.short_url = response["data"]["url"]
                obj.save()
    return ""


@register.to_end_tag
def metablock(parsed):
    """
    Remove HTML tags, entities and superfluous characters from meta blocks.
    """
    parsed = " ".join(parsed.replace("\n", "").split()).replace(" ,", ",")
    return strip_tags(decode_html_entities(parsed))


@register.inclusion_tag("includes/pagination.html", takes_context=True)
def pagination_for(context, current_page):
    """
    Include the pagination template and data for persisting querystring in
    pagination links.
    """
    querystring = context["request"].GET.copy()
    if "page" in querystring:
        del querystring["page"]
    querystring = querystring.urlencode()
    return {"current_page": current_page, "querystring": querystring}


@register.inclusion_tag("includes/editable_loader.html", takes_context=True)
def editable_loader(context):
    """
    Set up the required JS/CSS for the in-line editing toolbar and controls.
    """
    t = get_template("includes/editable_toolbar.html")
    context["REDIRECT_FIELD_NAME"] = REDIRECT_FIELD_NAME
    context["toolbar"] = t.render(Context(context))
    return context


@register.to_end_tag
def editable(parsed, context, token):
    """
    Add the required HTML to the parsed content for in-line editing, such as
    the icon and edit form if the object is deemed to be editable - either it
    has an ``editable`` method which returns True, or the logged in user has
    change permissions for the model.
    """
    def parse_field(field):
        field = field.split(".")
        obj = context[field.pop(0)]
        attr = field.pop()
        while field:
            obj = getattr(obj, field.pop(0))
        return obj, attr

    fields = [parse_field(f) for f in token.split_contents()[1:]]
    if fields:
        fields = [f for f in fields if len(f) == 2 and f[0] is fields[0][0]]
    if not parsed.strip():
        parsed = "".join([unicode(getattr(*field)) for field in fields])
    if fields:
        obj = fields[0][0]
        if isinstance(obj, Model) and is_editable(obj, context["request"]):
            field_names = ",".join([f[1] for f in fields])
            context["form"] = get_edit_form(obj, field_names)
            context["original"] = parsed
            context["uuid"] = uuid4()
        t = get_template("includes/editable_form.html")
        return t.render(Context(context))
    return parsed


@register.simple_tag
def admin_url(url_name):
    """
    Mimics Django's ``url`` template tag. Used for urls in admin templates as 
    for some reason these urls won't resolve when admin tests are running, so 
    here they just fail silently.
    """
    try:
        url = reverse(url_name)
    except NoReverseMatch:
        return ""
    return url


def admin_app_list(request):
    """
    Adopted from ``django.contrib.admin.sites.AdminSite.index``. Returns a 
    list of lists of models grouped and ordered according to <commit_msg>Fix rendering editable fields when not authenticated.<commit_after>
from urllib import urlopen, urlencode
from uuid import uuid4

from django.conf import settings
from django.contrib import admin
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.core.urlresolvers import reverse, NoReverseMatch
from django.db.models import Model
from django.template import Context, Template
from django.template.loader import get_template
from django.utils.html import strip_tags
from django.utils.simplejson import loads
from django.utils.text import capfirst

from mezzanine import template
from mezzanine.core.forms import get_edit_form
from mezzanine.settings import load_settings as _load_settings
from mezzanine.utils import decode_html_entities, is_editable


mezz_settings = _load_settings("ADMIN_MENU_ORDER", "DASHBOARD_TAGS")

register = template.Library()


@register.render_tag
def load_settings(context, token):
    """
    Push the given setting names into the context.
    """
    names = token.split_contents()[1:]
    for name in names:
        if name not in context:
            mezz_settings = _load_settings(*names)
            for name in names:
                context[name] = getattr(mezz_settings, name)
            break
    return ""


@register.render_tag
def set_short_url_for(context, token):
    """
    Sets the ``short_url`` attribute of the given model using the bit.ly
    credentials if they have been specified and saves it.
    """
    obj = context[token.split_contents()[1]]
    request = context["request"]
    if getattr(obj, "short_url") is None:
        obj.short_url = request.build_absolute_uri(request.path)
        mezz_settings = _load_settings("BLOG_BITLY_USER", "BLOG_BITLY_KEY")
        args = {
            "login": mezz_settings.BLOG_BITLY_USER,
            "apiKey": mezz_settings.BLOG_BITLY_KEY,
            "longUrl": obj.short_url,
        }
        if args["login"] and args["apiKey"]:
            url = "http://api.bit.ly/v3/shorten?%s" % urlencode(args)
            response = loads(urlopen(url).read())
            if response["status_code"] == 200:
                obj.short_url = response["data"]["url"]
                obj.save()
    return ""


@register.to_end_tag
def metablock(parsed):
    """
    Remove HTML tags, entities and superfluous characters from meta blocks.
    """
    parsed = " ".join(parsed.replace("\n", "").split()).replace(" ,", ",")
    return strip_tags(decode_html_entities(parsed))


@register.inclusion_tag("includes/pagination.html", takes_context=True)
def pagination_for(context, current_page):
    """
    Include the pagination template and data for persisting querystring in
    pagination links.
    """
    querystring = context["request"].GET.copy()
    if "page" in querystring:
        del querystring["page"]
    querystring = querystring.urlencode()
    return {"current_page": current_page, "querystring": querystring}


@register.inclusion_tag("includes/editable_loader.html", takes_context=True)
def editable_loader(context):
    """
    Set up the required JS/CSS for the in-line editing toolbar and controls.
    """
    t = get_template("includes/editable_toolbar.html")
    context["REDIRECT_FIELD_NAME"] = REDIRECT_FIELD_NAME
    context["toolbar"] = t.render(Context(context))
    return context


@register.to_end_tag
def editable(parsed, context, token):
    """
    Add the required HTML to the parsed content for in-line editing, such as
    the icon and edit form if the object is deemed to be editable - either it
    has an ``editable`` method which returns True, or the logged in user has
    change permissions for the model.
    """
    def parse_field(field):
        field = field.split(".")
        obj = context[field.pop(0)]
        attr = field.pop()
        while field:
            obj = getattr(obj, field.pop(0))
        return obj, attr

    fields = [parse_field(f) for f in token.split_contents()[1:]]
    if fields:
        fields = [f for f in fields if len(f) == 2 and f[0] is fields[0][0]]
    if not parsed.strip():
        parsed = "".join([unicode(getattr(*field)) for field in fields])
    if fields:
        obj = fields[0][0]
        if isinstance(obj, Model) and is_editable(obj, context["request"]):
            field_names = ",".join([f[1] for f in fields])
            context["form"] = get_edit_form(obj, field_names)
            context["original"] = parsed
            context["uuid"] = uuid4()
            t = get_template("includes/editable_form.html")
            return t.render(Context(context))
    return parsed


@register.simple_tag
def admin_url(url_name):
    """
    Mimics Django's ``url`` template tag. Used for urls in admin templates as 
    for some reason these urls won't resolve when admin tests are running, so 
    here they just fail silently.
    """
    try:
        url = reverse(url_name)
    except NoReverseMatch:
        return ""
    return url


def admin_app_list(request):
    """
    Adopted from ``django.contrib.admin.sites.AdminSite.index``. Returns a 
    list of lists of models grouped and ordered according to 
{'fraction_non_alphanumeric': 0.10497835497835498, 'fraction_numerical': 0.0035419126328217238, 'mean_word_length': 3.172824302134647, 'pattern_counts': {'":': 10, '<': 3, '<?xml version=': 0, '>': 3, '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': '3008557', 'n_tokens_mistral': 3023, 'n_tokens_neox': 2957, 'n_words': 864}