<commit_before>from pyramid.threadlocal import manager
from pyramid.view import view_config
from ..storage import (
    DBSession,
    CurrentStatement,
    Resource,
    )

collections = [
    ('antibodies', 'antibody_approval'),
    ('organisms', 'organism'),
    ('sources', 'source'),
    ('targets', 'target'),
    ('validations', 'validation'),
    ('antibody-lots', 'antibody_lot'),
    ]


def includeme(config):
    config.add_route('home', '')
    for collection, item_type in collections:
        config.add_route(collection, '/%s/' % collection)
        config.add_route(item_type, '/%s/{name}' % collection)
    config.scan('.views')


def include(request, path):
    # Should really be more careful about what gets included instead.
    # Cache cut response time from ~800ms to ~420ms.
    cache = None
    if manager.stack:
        cache = manager.stack[0].setdefault('encoded_include_cache', {})
        result = cache.get(path, None)
        if result is not None:
            return result
    subreq = request.blank(path)
    subreq.override_renderer = 'null_renderer'
    result = request.invoke_subrequest(subreq)
    if cache is not None:
        cache[path] = result
    return result


class CollectionViews(object):
    collection = None
    item_type = None
    properties = None
    links = {
        'self': {'href': '/{collection}/{_uuid}', 'templated': True},
        'collection': {'href': '/{collection}/', 'templated': True},
        'profile': {'href': '/profiles/{item_type}', 'templated': True},
        }
    embedded = None

    @classmethod
    def config(cls, **settings):
        settings['_depth'] = settings.get('_depth', 0) + 1

        def decorate(wrapped):
            assert issubclass(wrapped, cls), "Can only configure %s" % cls.__name__
            view_config(route_name=wrapped.collection, request_method='GET', attr='list', **settings)(wrapped)
            view_config(route_name=wrapped.collection, request_method='POST', attr='create', **settings)(wrapped)
            view_config(route_name=wrapped.item_type, request_method='GET', attr='get', **settings)(wrapped)
            return wrapped

        return decorate

    def __init__(self, request):
        self.request = request
        self.collection_uri = request.route_path(self.collection)

    def item_uri(self, name):
        return self.request.route_path(self.item_type, name=name)

    def expand_embedded(self, model, item):
        if self.embedded is None:
            return None
        objects = {}
        for rel, value in self.embedded.items():
            if isinstance(value, basestring):
                value = include(self.request, value.format(
                    collection_uri=self.collection_uri,
                    item_type=self.item_type,
                    collection=self.collection,
                    **item))
            objects[rel] = value
        return objects

    def expand_links(self, model, item):
        # This should probably go on a metaclass
        merged_links = {}
        for cls in reversed(type(self).mro()):
            merged_links.update(vars(cls).get('links', {}))
        links = {}
        for rel, value in merged_links.items():
            if value is None:
                continue
            if isinstance(value, list):
                out = []
                for member in value:
                    if not member.get('templated', False):
                        out.append(member)
                        continue
                    templated = member.copy()
                    del templated['templated']
                    repeat = templated.pop('repeat', None)
                    if repeat:
                        ns = item.copy()
                        repeat_name, repeater = repeat.split()
                        for repeat_value in item[repeater]:
                            ns[repeat_name] = repeat_value
                            templated['href'] = member['href'].format(
                                collection_uri=self.collection_uri,
                                item_type=self.item_type,
                                collection=self.collection,
                                **ns)
                            out.append(templated)
                    else:
                        ns = item
                        ns[repeat_name] = repeat_value
                        templated['href'] = member['href'].format(
                            collection_uri=self.collection_uri,
                            item_type=self.item_type,
                            collection=self.collection,
                            **ns)
                        out.append(templated)
                value = out
            elif value.get('templated', False):
                value = value.copy()
                del value['templated']
                assert not value.get('repeat')
                value['href'] = value['href'].format(
                    collection_uri=self.collection_uri,<commit_msg>Fix repeated links<commit_after>from pyramid.threadlocal import manager
from pyramid.view import view_config
from ..storage import (
    DBSession,
    CurrentStatement,
    Resource,
    )

collections = [
    ('antibodies', 'antibody_approval'),
    ('organisms', 'organism'),
    ('sources', 'source'),
    ('targets', 'target'),
    ('validations', 'validation'),
    ('antibody-lots', 'antibody_lot'),
    ]


def includeme(config):
    config.add_route('home', '')
    for collection, item_type in collections:
        config.add_route(collection, '/%s/' % collection)
        config.add_route(item_type, '/%s/{name}' % collection)
    config.scan('.views')


def include(request, path):
    # Should really be more careful about what gets included instead.
    # Cache cut response time from ~800ms to ~420ms.
    cache = None
    if manager.stack:
        cache = manager.stack[0].setdefault('encoded_include_cache', {})
        result = cache.get(path, None)
        if result is not None:
            return result
    subreq = request.blank(path)
    subreq.override_renderer = 'null_renderer'
    result = request.invoke_subrequest(subreq)
    if cache is not None:
        cache[path] = result
    return result


class CollectionViews(object):
    collection = None
    item_type = None
    properties = None
    links = {
        'self': {'href': '/{collection}/{_uuid}', 'templated': True},
        'collection': {'href': '/{collection}/', 'templated': True},
        'profile': {'href': '/profiles/{item_type}', 'templated': True},
        }
    embedded = None

    @classmethod
    def config(cls, **settings):
        settings['_depth'] = settings.get('_depth', 0) + 1

        def decorate(wrapped):
            assert issubclass(wrapped, cls), "Can only configure %s" % cls.__name__
            view_config(route_name=wrapped.collection, request_method='GET', attr='list', **settings)(wrapped)
            view_config(route_name=wrapped.collection, request_method='POST', attr='create', **settings)(wrapped)
            view_config(route_name=wrapped.item_type, request_method='GET', attr='get', **settings)(wrapped)
            return wrapped

        return decorate

    def __init__(self, request):
        self.request = request
        self.collection_uri = request.route_path(self.collection)

    def item_uri(self, name):
        return self.request.route_path(self.item_type, name=name)

    def expand_embedded(self, model, item):
        if self.embedded is None:
            return None
        objects = {}
        for rel, value in self.embedded.items():
            if isinstance(value, basestring):
                value = include(self.request, value.format(
                    collection_uri=self.collection_uri,
                    item_type=self.item_type,
                    collection=self.collection,
                    **item))
            objects[rel] = value
        return objects

    def expand_links(self, model, item):
        # This should probably go on a metaclass
        merged_links = {}
        for cls in reversed(type(self).mro()):
            merged_links.update(vars(cls).get('links', {}))
        links = {}
        for rel, value in merged_links.items():
            if value is None:
                continue
            if isinstance(value, list):
                out = []
                for member in value:
                    if not member.get('templated', False):
                        out.append(member)
                        continue
                    templated = member.copy()
                    del templated['templated']
                    repeat = templated.pop('repeat', None)
                    if repeat:
                        ns = item.copy()
                        repeat_name, repeater = repeat.split()
                        for repeat_value in item[repeater]:
                            ns[repeat_name] = repeat_value
                            templated = templated.copy()
                            templated['href'] = member['href'].format(
                                collection_uri=self.collection_uri,
                                item_type=self.item_type,
                                collection=self.collection,
                                **ns)
                            out.append(templated)
                    else:
                        ns = item
                        ns[repeat_name] = repeat_value
                        templated['href'] = member['href'].format(
                            collection_uri=self.collection_uri,
                            item_type=self.item_type,
                            collection=self.collection,
                            **ns)
                        out.append(templated)
                value = out
            elif value.get('templated', False):
                value = value.copy()
                del value['templated']
                assert not value.get('repeat')
                value['href'] = value['href'].format(
                    collection_uri=self.collection_uri,
{'fraction_non_alphanumeric': 0.10919197935278936, 'fraction_numerical': 0.001786777843954735, 'mean_word_length': 1.7266576454668472, 'pattern_counts': {'":': 0, '<': 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': '1179269', 'n_tokens_mistral': 2650, 'n_tokens_neox': 2549, 'n_words': 589}