<commit_before>#!/usr/bin/env python3
#
# Copyright 2018 Red Hat, Inc.
#
# Authors:
#     <NAME> <<EMAIL>>
#
# This work is licensed under the MIT License.  Please see the LICENSE file or
# http://opensource.org/licenses/MIT.

from collections import OrderedDict
from django.contrib.auth.models import User
from django.http import Http404
from django.template import loader

from mod import dispatch_module_hook
from .models import Project, Message
from .search import SearchEngine
from rest_framework import (permissions, serializers, viewsets, filters,
    mixins, generics, renderers)
from rest_framework.decorators import detail_route
from rest_framework.fields import SerializerMethodField, CharField, JSONField
from rest_framework.relations import HyperlinkedIdentityField
from rest_framework.response import Response
import rest_framework

SEARCH_PARAM = 'q'

# patchew-specific permission classes

class IsAdminUserOrReadOnly(permissions.BasePermission):
    """
    Allows access only to admin users.
    """
    def has_permission(self, request, view):
        return request.method in permissions.SAFE_METHODS or \
               (request.user and request.user.is_superuser)

class IsMaintainerOrReadOnly(permissions.BasePermission):
    """
    Allows access only to admin users or maintainers.
    """
    def has_object_permission(self, request, view, obj):
        if isinstance(obj, Message):
            obj = obj.project
        return request.method in permissions.SAFE_METHODS or \
               obj.maintained_by(request.user)

# pluggable field for plugin support

class PluginMethodField(SerializerMethodField):
    """
    A read-only field that get its representation from calling a method on
    the plugin class. The method called will be of the form
    "get_{field_name}", and should take a single argument, which is the
    object being serialized.

    For example:

        fields['extra_info'] = api.rest.PluginMethodField(obj=self)

        def get_extra_info(self, obj):
            return ...  # Calculate some data to return.
    """

    def __init__(self, obj=None, method_name=None, **kwargs):
        self.obj = obj
        super(PluginMethodField, self).__init__(method_name=method_name, **kwargs)

    def to_representation(self, value):
        method = getattr(self.obj, self.method_name)
        request = self.context['request']
        format = self.context.get('format', None)
        return method(value, request, format)

# Users

# TODO: include list of projects maintained by the user, login

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('resource_uri', 'username')

class UsersViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all().order_by('id')
    serializer_class = UserSerializer
    permission_classes = (IsAdminUserOrReadOnly,)

# Projects

# TODO: include list of maintainers, connect plugins

class ProjectSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Project
        fields = ('resource_uri', 'name', 'mailing_list', 'prefix_tags', 'url', 'git', \
                  'description', 'display_order', 'logo', 'parent_project', 'results')

    results = HyperlinkedIdentityField(view_name='results-list', lookup_field='pk',
                                       lookup_url_kwarg='projects_pk')

class ProjectsViewSet(viewsets.ModelViewSet):
    queryset = Project.objects.all().order_by('id')
    serializer_class = ProjectSerializer
    permission_classes = (IsMaintainerOrReadOnly,)

# Common classes for series and messages

class HyperlinkedMessageField(HyperlinkedIdentityField):
    lookup_field = 'message_id'
    def get_url(self, obj, view_name, request, format):
        kwargs = {'projects_pk': obj.project_id, self.lookup_field: obj.message_id}<commit_msg>rest: include URI links for all nested views<commit_after>#!/usr/bin/env python3
#
# Copyright 2018 Red Hat, Inc.
#
# Authors:
#     <NAME> <<EMAIL>>
#
# This work is licensed under the MIT License.  Please see the LICENSE file or
# http://opensource.org/licenses/MIT.

from collections import OrderedDict
from django.contrib.auth.models import User
from django.http import Http404
from django.template import loader

from mod import dispatch_module_hook
from .models import Project, Message
from .search import SearchEngine
from rest_framework import (permissions, serializers, viewsets, filters,
    mixins, generics, renderers)
from rest_framework.decorators import detail_route
from rest_framework.fields import SerializerMethodField, CharField, JSONField
from rest_framework.relations import HyperlinkedIdentityField
from rest_framework.response import Response
import rest_framework

SEARCH_PARAM = 'q'

# patchew-specific permission classes

class IsAdminUserOrReadOnly(permissions.BasePermission):
    """
    Allows access only to admin users.
    """
    def has_permission(self, request, view):
        return request.method in permissions.SAFE_METHODS or \
               (request.user and request.user.is_superuser)

class IsMaintainerOrReadOnly(permissions.BasePermission):
    """
    Allows access only to admin users or maintainers.
    """
    def has_object_permission(self, request, view, obj):
        if isinstance(obj, Message):
            obj = obj.project
        return request.method in permissions.SAFE_METHODS or \
               obj.maintained_by(request.user)

# pluggable field for plugin support

class PluginMethodField(SerializerMethodField):
    """
    A read-only field that get its representation from calling a method on
    the plugin class. The method called will be of the form
    "get_{field_name}", and should take a single argument, which is the
    object being serialized.

    For example:

        fields['extra_info'] = api.rest.PluginMethodField(obj=self)

        def get_extra_info(self, obj):
            return ...  # Calculate some data to return.
    """

    def __init__(self, obj=None, method_name=None, **kwargs):
        self.obj = obj
        super(PluginMethodField, self).__init__(method_name=method_name, **kwargs)

    def to_representation(self, value):
        method = getattr(self.obj, self.method_name)
        request = self.context['request']
        format = self.context.get('format', None)
        return method(value, request, format)

# Users

# TODO: include list of projects maintained by the user, login

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('resource_uri', 'username')

class UsersViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all().order_by('id')
    serializer_class = UserSerializer
    permission_classes = (IsAdminUserOrReadOnly,)

# Projects

# TODO: include list of maintainers, connect plugins

class ProjectSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Project
        fields = ('resource_uri', 'name', 'mailing_list', 'prefix_tags', 'url', 'git', \
                  'description', 'display_order', 'logo', 'parent_project', 'messages',
                  'results', 'series')

    messages = HyperlinkedIdentityField(view_name='messages-list', lookup_field='pk',
                                        lookup_url_kwarg='projects_pk')
    results = HyperlinkedIdentityField(view_name='results-list', lookup_field='pk',
                                       lookup_url_kwarg='projects_pk')
    series = HyperlinkedIdentityField(view_name='series-list', lookup_field='pk',
                                       lookup_url_kwarg='projects_pk')

class ProjectsViewSet(viewsets.ModelViewSet):
    queryset = Project.objects.all().order_by('id')
    serializer_class = ProjectSerializer
    permission_classes = (IsMaintainerOrReadOnly,)

# Common classes for series and messages

class HyperlinkedMessageField(HyperlinkedIdentityField):
    lookup_field = 'message_id'
    def get_url(self, obj, view_name, request, format):
        kwargs = {'projects_pk': obj.project_id, self.lookup_field: obj.message_id}
{'fraction_non_alphanumeric': 0.08993072736269174, 'fraction_numerical': 0.0019792182088075212, 'mean_word_length': 3.6653202538949796, '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': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1911226', 'n_tokens_mistral': 2217, 'n_tokens_neox': 2164, 'n_words': 622}