<commit_before># vim: fileencoding=utf-8

import fnmatch
import os
import werkzeug

from docutils import nodes
from docutils.core import publish_parts
from docutils.parsers.rst import Directive, directives

from pygments import highlight
from pygments.formatters import HtmlFormatter
from pygments.lexers import LEXERS, guess_lexer_for_filename, TextLexer

from blikit import utils
from blikit.models import BlobObject
from blikit.docutilsext import Writer

class Document(object):
    title = None
    description = None
    body = None
    def __init__(self, **attrs):
        for name, value in attrs.iteritems():
            if name.startswith('_'):
                continue
            setattr(self, name, value)


renderer_map = []

def register_for(*pats):
    def _register_for(func):
        for p in pats:
            renderer_map.append((p, func))
        return func

    return _register_for


def render_blob(ctx, blob_obj):
    u'''render BlobObject as HTML portion using proper render function

    return <Document object>

    if there is no render function for this object, return None
    '''
    if not isinstance(blob_obj, BlobObject):
        # TODO: raise proper exception
        # XXX: may this function treat TreeObject?
        raise Exception

    for p, func in renderer_map:
        if fnmatch.fnmatch(blob_obj.name, p):
            result = func(ctx, blob_obj)
            break
    else:
        result = None

    return result


@register_for('*.txt')
def render_text(ctx, blob_obj):
    udata = blob_obj.data.decode('utf-8', 'replace')
    return Document(title=blob_obj.name,
                    body=u'<pre>' + werkzeug.escape(udata) + u'</pre>')


@register_for('*.rst')
def render_rst(ctx, blob_obj):
    parts = publish_parts(blob_obj.data, writer=Writer(),
                          settings_overrides={'ctx': ctx, 'obj': blob_obj})
    parts['description'] = parts['title']
    return Document(**parts)


@register_for('*.png', '*.jpg', '*.jpeg', '*.gif')
def render_images(ctx, blob_obj):
    w, h = utils.calc_thumb_size(blob_obj.data, (640, 480))
    url = ctx.url_for('view_obj',
                      rev=blob_obj.commit.name, path=blob_obj.root_path)<commit_msg>add more attributes to Document object and cache this<commit_after># vim: fileencoding=utf-8

import fnmatch
import os
import werkzeug

from docutils import nodes
from docutils.core import publish_parts
from docutils.parsers.rst import Directive, directives

from pygments import highlight
from pygments.formatters import HtmlFormatter
from pygments.lexers import LEXERS, guess_lexer_for_filename, TextLexer

from blikit import utils
from blikit.models import BlobObject
from blikit.docutilsext import Writer

class Document(object):
    title = None
    description = None
    body = None
    author_name = None
    last_modified = None
    created = None

    def __init__(self, **attrs):
        for name, value in attrs.iteritems():
            if name.startswith('_'):
                continue
            setattr(self, name, value)


renderer_map = []

def register_for(*pats):
    def _register_for(func):
        for p in pats:
            renderer_map.append((p, func))
        return func

    return _register_for


def render_blob(ctx, blob_obj):
    u'''render BlobObject as HTML portion using proper render function

    return <Document object>

    if there is no render function for this object, return None
    '''
    cache_key = 'render.render_blob:%s:%s' % \
            (blob_obj.commit.sha, blob_obj.abs_name)

    cached = ctx.app.cache.get(cache_key)
    if cached is not None:
        return cached

    if not isinstance(blob_obj, BlobObject):
        # TODO: raise proper exception
        # XXX: may this function treat TreeObject?
        raise Exception

    for p, func in renderer_map:
        if fnmatch.fnmatch(blob_obj.name, p):
            result = func(ctx, blob_obj)
            break
    else:
        result = None

    if isinstance(result, Document):
        if result.author_name is None:
            result.author_name = blob_obj.author_name

        if result.last_modified is None:
            result.last_modified = blob_obj.last_modified

        if result.created is None:
            result.created = blob_obj.created

    ctx.app.cache.set(cache_key, result)

    return result


@register_for('*.txt')
def render_text(ctx, blob_obj):
    udata = blob_obj.data.decode('utf-8', 'replace')
    return Document(title=blob_obj.name,
                    body=u'<pre>' + werkzeug.escape(udata) + u'</pre>')


@register_for('*.rst')
def render_rst(ctx, blob_obj):
    parts = publish_parts(blob_obj.data, writer=Writer(),
                          settings_overrides={'ctx': ctx, 'obj': blob_obj})
    parts['description'] = parts['title']
    return Document(**parts)


@register_for('*.png', '*.jpg', '*.jpeg', '*.gif')
def render_images(ctx, blob_obj):
    w, h = utils.calc_thumb_size(blob_obj.data, (640, 480))
    url = ctx.url_for('view_obj',
                      rev=blob_obj.commit.name, path=blob_obj.root_path)
{'fraction_non_alphanumeric': 0.10102402520677432, 'fraction_numerical': 0.0031508467900748325, 'mean_word_length': 2.9189814814814814, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, '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': '2174213', 'n_tokens_mistral': 1582, 'n_tokens_neox': 1533, 'n_words': 423}