Commit 498bb740 authored by Flavio TARSETTI's avatar Flavio TARSETTI
Browse files

Merge branch 'refactor_update_creation_api' into 'master'

Refactor update creation api

See merge request !327
parents e47d4ede 91188f67
Pipeline #39733 passed with stages
in 16 minutes and 5 seconds
......@@ -21,4 +21,4 @@ repos:
rev: 'master' # Update me!
hooks:
- id: bandit
exclude: beat/editor/test
exclude: (beat/web/.*/tests|eggs/)
......@@ -25,62 +25,50 @@
# #
###############################################################################
from django.conf.urls import *
from django.conf.urls import url
from . import api
urlpatterns = [
url(r"^$", api.SupervisorListView.as_view(), name="list_supervisee"),
url(
r'^$',
api.SupervisorListView.as_view(),
name='list_supervisee'
),
url(
r'^(?P<supervisee_name>[\w\W]+)/validate/$',
r"^(?P<supervisee_name>[\w\W]+)/validate/$",
api.SupervisorAddSuperviseeView.as_view(),
name='validate_supervisee'
name="validate_supervisee",
),
url(
r'^(?P<supervisee_name>[\w\W]+)/remove/$',
r"^(?P<supervisee_name>[\w\W]+)/remove/$",
api.SupervisorRemoveSuperviseeView.as_view(),
name='remove_supervisee'
name="remove_supervisee",
),
url(
r'^(?P<supervisor_name>[\w\W]+)/add/$',
r"^(?P<supervisor_name>[\w\W]+)/add/$",
api.SuperviseeAddSupervisorView.as_view(),
name='add_supervisor'
name="add_supervisor",
),
url(
r'^revalidate/$',
r"^revalidate/$",
api.SuperviseeReValidationView.as_view(),
name='revalidate_account'
name="revalidate_account",
),
url(
r'^set_supervisor_mode/$',
r"^set_supervisor_mode/$",
api.SetSupervisorModeView.as_view(),
name='set_supervisor_mode'
name="set_supervisor_mode",
),
url(
r'^remove_supervisor_mode/$',
r"^remove_supervisor_mode/$",
api.RemoveSupervisorModeView.as_view(),
name='remove_supervisor_mode'
name="remove_supervisor_mode",
),
url(
r'^list_supervisor_candidates/$',
r"^list_supervisor_candidates/$",
api.ListSupervisorCandidatesView.as_view(),
name='list_supervisor_candidates'
name="list_supervisor_candidates",
),
url(
r'^grant_supervisor_access/$',
r"^grant_supervisor_access/$",
api.UpdateSupervisorCandidateView.as_view(),
name='update_supervisor_candidate'
name="update_supervisor_candidate",
),
]
......@@ -25,20 +25,13 @@
# #
###############################################################################
from django.contrib.auth.models import User, AnonymousUser
from django.contrib.auth.models import User
from rest_framework import serializers
from .models import Profile, SupervisionTrack
from ..common.models import Contribution
from ..common.fields import JSONSerializerField
from ..ui.templatetags.markup import restructuredtext
from ..common.utils import validate_restructuredtext
import simplejson as json
from .models import SupervisionTrack
#----------------------------------------------------------
# ----------------------------------------------------------
class UserSerializer(serializers.ModelSerializer):
......@@ -47,7 +40,7 @@ class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['username', 'email']
fields = ["username", "email"]
def get_username(self, obj):
return obj.username
......@@ -56,7 +49,7 @@ class UserSerializer(serializers.ModelSerializer):
return obj.email
#----------------------------------------------------------
# ----------------------------------------------------------
class BasicSupervisionTrackSerializer(serializers.ModelSerializer):
......@@ -70,12 +63,12 @@ class BasicSupervisionTrackSerializer(serializers.ModelSerializer):
class Meta:
model = SupervisionTrack
fields = ['is_valid']
fields = ["is_valid"]
#def get_supervisee(self, obj):
# def get_supervisee(self, obj):
# return obj.supervisee
#def get_supervisor(self, obj):
# def get_supervisor(self, obj):
# return obj.supervisor
def get_is_valid(self, obj):
......@@ -94,20 +87,27 @@ class BasicSupervisionTrackSerializer(serializers.ModelSerializer):
return obj.supervision_key
#----------------------------------------------------------
# ----------------------------------------------------------
class FullSupervisionTrackSerializer(BasicSupervisionTrackSerializer):
class Meta(BasicSupervisionTrackSerializer.Meta):
fields = ['supervisee', 'supervisor', 'is_valid', 'start_date', 'expiration_date','last_validation_date', 'supervision_key']
fields = [
"supervisee",
"supervisor",
"is_valid",
"start_date",
"expiration_date",
"last_validation_date",
"supervision_key",
]
#----------------------------------------------------------
# ----------------------------------------------------------
class SupervisionTrackUpdateSerializer(BasicSupervisionTrackSerializer):
pass
#----------------------------------------------------------
# ----------------------------------------------------------
......@@ -29,26 +29,28 @@ from django.http import Http404
from django.http import HttpResponse
from django.http import HttpResponseForbidden
from django.http import HttpResponseBadRequest
from django.http import HttpResponseNotAllowed
from django.shortcuts import get_object_or_404
from django.conf import settings
import os
from .models import Algorithm
from .serializers import AlgorithmSerializer
from .serializers import FullAlgorithmSerializer
from .serializers import AlgorithmCreationSerializer
from .serializers import AlgorithmModSerializer
from ..code.api import ShareCodeView, RetrieveUpdateDestroyCodeView
from ..code.serializers import CodeDiffSerializer
from ..common.api import (CheckContributionNameView, ListContributionView,
ListCreateContributionView)
from ..common.api import (
CheckContributionNameView,
ListContributionView,
ListCreateContributionView,
)
from ..code.api import DiffView
#----------------------------------------------------------
# ----------------------------------------------------------
class CheckAlgorithmNameView(CheckContributionNameView):
......@@ -56,10 +58,11 @@ class CheckAlgorithmNameView(CheckContributionNameView):
This view sanitizes an algorithm name and
checks whether it is already used.
"""
model = Algorithm
#----------------------------------------------------------
# ----------------------------------------------------------
class ShareAlgorithmView(ShareCodeView):
......@@ -67,21 +70,23 @@ class ShareAlgorithmView(ShareCodeView):
This view allows to share an algorithm with
other users and/or teams
"""
model = Algorithm
#----------------------------------------------------------
# ----------------------------------------------------------
class ListAlgorithmsView(ListContributionView):
"""
List all available algorithms
"""
model = Algorithm
serializer_class = AlgorithmSerializer
#----------------------------------------------------------
# ----------------------------------------------------------
class ListCreateAlgorithmsView(ListCreateContributionView):
......@@ -89,13 +94,14 @@ class ListCreateAlgorithmsView(ListCreateContributionView):
Read/Write end point that list the algorithms available
from a given author and allows the creation of new algorithms
"""
model = Algorithm
serializer_class = AlgorithmSerializer
writing_serializer_class = AlgorithmCreationSerializer
namespace = 'api_algorithms'
namespace = "api_algorithms"
#----------------------------------------------------------
# ----------------------------------------------------------
class RetrieveUpdateDestroyAlgorithmsView(RetrieveUpdateDestroyCodeView):
......@@ -105,39 +111,30 @@ class RetrieveUpdateDestroyAlgorithmsView(RetrieveUpdateDestroyCodeView):
model = Algorithm
serializer_class = FullAlgorithmSerializer
writing_serializer_class = AlgorithmModSerializer
def do_update(self, request, author_name, object_name, version=None):
modified, algorithm = super(RetrieveUpdateDestroyAlgorithmsView, self).do_update(request, author_name, object_name, version)
if modified:
# Delete existing experiments using the algorithm (code changed)
experiments = list(set(map(lambda x: x.experiment,
algorithm.blocks.iterator())))
for experiment in experiments: experiment.delete()
return modified, algorithm
#----------------------------------------------------------
# ----------------------------------------------------------
class DiffAlgorithmView(DiffView):
"""
This view shows the differences between two algorithms
"""
model = Algorithm
serializer_class = CodeDiffSerializer
#----------------------------------------------------------
# ----------------------------------------------------------
def binary(request, author_name, object_name, version=None):
"""Returns the shared library of a binary algorithm
"""
if request.method not in ['GET', 'POST']:
return HttpResponseNotAllowed(['GET', 'POST'])
if request.method not in ["GET", "POST"]:
return HttpResponseNotAllowed(["GET", "POST"])
# Retrieves the algorithm
if version:
......@@ -148,8 +145,9 @@ def binary(request, author_name, object_name, version=None):
version=int(version),
)
else:
algorithm = Algorithm.objects.filter(author__username__iexact=author_name,
name__iexact=object_name).order_by('-version')
algorithm = Algorithm.objects.filter(
author__username__iexact=author_name, name__iexact=object_name
).order_by("-version")
if not algorithm:
raise Http404()
else:
......@@ -158,18 +156,22 @@ def binary(request, author_name, object_name, version=None):
if not algorithm.is_binary():
raise Http404()
if request.method == 'GET':
(has_access, _, accessibility) = algorithm.accessibility_for(request.user, without_usable=True)
if request.method == "GET":
(has_access, _, accessibility) = algorithm.accessibility_for(
request.user, without_usable=True
)
if not has_access:
raise Http404()
binary_data = algorithm.source_code
response = HttpResponse(binary_data, content_type='application/octet-stream')
response = HttpResponse(binary_data, content_type="application/octet-stream")
response['Content-Length'] = len(binary_data)
response['Content-Disposition'] = 'attachment; filename=%d.so' % algorithm.version
response["Content-Length"] = len(binary_data)
response["Content-Disposition"] = (
"attachment; filename=%d.so" % algorithm.version
)
return response
......@@ -177,12 +179,12 @@ def binary(request, author_name, object_name, version=None):
if request.user.is_anonymous() or (request.user.username != author_name):
return HttpResponseForbidden()
if 'binary' not in request.FILES:
if "binary" not in request.FILES:
return HttpResponseBadRequest()
file = request.FILES['binary']
file = request.FILES["binary"]
binary_data = b''
binary_data = b""
for chunk in file.chunks():
binary_data += chunk
......
......@@ -29,51 +29,33 @@ from django.conf.urls import url
from . import api
urlpatterns = [
url(r'^$',
api.ListAlgorithmsView.as_view(),
name='all',
),
url(r'^check_name/$',
api.CheckAlgorithmNameView.as_view(),
name='check_name',
),
url(r'^diff/(?P<author1>\w+)/(?P<name1>[-\w]+)/(?P<version1>\d+)/(?P<author2>\w+)/(?P<name2>[-\w]+)/(?P<version2>\d+)/$',
urlpatterns = [
url(r"^$", api.ListAlgorithmsView.as_view(), name="all"),
url(r"^check_name/$", api.CheckAlgorithmNameView.as_view(), name="check_name"),
url(
r"^diff/(?P<author1>\w+)/(?P<name1>[-\w]+)/(?P<version1>\d+)/(?P<author2>\w+)/(?P<name2>[-\w]+)/(?P<version2>\d+)/$",
api.DiffAlgorithmView.as_view(),
name='diff',
),
url(r'^(?P<author_name>\w+)/(?P<object_name>[-\w]+)/(?P<version>\d+)/share/$',
name="diff",
),
url(
r"^(?P<author_name>\w+)/(?P<object_name>[-\w]+)/(?P<version>\d+)/share/$",
api.ShareAlgorithmView.as_view(),
name='share',
),
url(r'^(?P<author_name>\w+)/$',
name="share",
),
url(
r"^(?P<author_name>\w+)/$",
api.ListCreateAlgorithmsView.as_view(),
name='list_create',
),
url(r'^(?P<author_name>\w+)/(?P<object_name>[-\w]+)/(?P<version>\d+)/$',
name="list_create",
),
url(
r"^(?P<author_name>\w+)/(?P<object_name>[-\w]+)/(?P<version>\d+)/$",
api.RetrieveUpdateDestroyAlgorithmsView.as_view(),
name='object',
),
url(r'^(?P<author_name>\w+)/(?P<object_name>[-\w]+)/$',
api.RetrieveUpdateDestroyAlgorithmsView.as_view(),
name='object',
),
url(r'^(?P<author_name>\w+)/(?P<object_name>[-\w]+)/(?P<version>\d+)/binary/$',
name="object",
),
url(
r"^(?P<author_name>\w+)/(?P<object_name>[-\w]+)/(?P<version>\d+)/binary/$",
api.binary,
name='binary',
),
url(r'^(?P<author_name>\w+)/(?P<object_name>[-\w]+)/binary/$',
api.binary,
name='binary',
),
name="binary",
),
]
......@@ -32,7 +32,7 @@ import beat.core.algorithm
from rest_framework import serializers
from operator import itemgetter
from ..code.serializers import CodeSerializer, CodeCreationSerializer
from ..code.serializers import CodeSerializer, CodeCreationSerializer, CodeModSerializer
from ..libraries.serializers import LibraryReferenceSerializer
from ..dataformats.serializers import ReferencedDataFormatSerializer
from ..attestations.serializers import AttestationSerializer
......@@ -49,7 +49,13 @@ from .models import Algorithm
class AlgorithmCreationSerializer(CodeCreationSerializer):
class Meta(CodeCreationSerializer.Meta):
model = Algorithm
beat_core_class = beat.core.algorithm
beat_core_class = beat.core.algorithm.Algorithm
class AlgorithmModSerializer(CodeModSerializer):
class Meta(CodeModSerializer.Meta):
model = Algorithm
beat_core_class = beat.core.algorithm.Algorithm
# ----------------------------------------------------------
......
......@@ -329,13 +329,14 @@ function setupEditor(algorithm, dataformats, libraries)
var data = {
{% if not edition %}
{% if algorithm_version > 1 and not fork_of %}
name: '{{ algorithm_name }}',
version: '{{ algorithm_version }}',
previous_version:'{{ algorithm_author }}/{{ algorithm_name }}/{{ algorithm_version|add:-1 }}',
{% else %}
name: $('#algorithm_name')[0].value.trim(),
{% endif %}
{% if algorithm_version > 1 and not fork_of %}
name: '{{ algorithm_name }}',
version: {{ algorithm_version }},
previous_version:'{{ algorithm_author }}/{{ algorithm_name }}/{{ algorithm_version|add:-1 }}',
{% else %}
name: $('#algorithm_name')[0].value.trim(),
version: 1,
{% endif %}
description: (algorithm && algorithm.description) || '',
{% endif %}
short_description: (algorithm && algorithm.short_description) || '',
......@@ -710,10 +711,7 @@ jQuery(document).ready(function() {
});
{% if original_author %}
var url = '{% url 'api_algorithms:object' original_author algorithm_name %}'
{% if algorithm_version %}
url += '{{ algorithm_version }}/';
{% endif %}
var url = '{% url 'api_algorithms:object' original_author algorithm_name algorithm_version %}'
var query = '?fields=html_description,description,short_description';
......
This diff is collapsed.
......@@ -26,30 +26,15 @@
###############################################################################
from django.conf.urls import url
from . import api
urlpatterns = [
url(
r'^$',
api.CreateAttestationView.as_view(),
name="create"
),
url(
r'^unlock/(?P<number>\d+)/$',
api.UnlockAttestationView.as_view(),
name="unlock"
),
from . import api
url(
r'^(?P<number>\d+)/$',
api.DeleteAttestationView.as_view(),
name="delete"
),
urlpatterns = [
url(r"^$", api.CreateAttestationView.as_view(), name="create"),
url(
r'^(?P<username>\w+)/$',
api.ListUserAttestationView.as_view(),
name="all"
r"^unlock/(?P<number>\d+)/$", api.UnlockAttestationView.as_view(), name="unlock"
),
url(r"^(?P<number>\d+)/$", api.DeleteAttestationView.as_view(), name="delete"),
url(r"^(?P<username>\w+)/$", api.ListUserAttestationView.as_view(), name="all"),
]
......@@ -26,26 +26,24 @@
###############################################################################
from django.conf.urls import url
from . import api
urlpatterns = [
urlpatterns = [
url(
r'^environments/$',
r"^environments/$",
api.accessible_environments_list,
name='backend-api-environments',
name="backend-api-environments",
),
url(
r'^local_scheduler/start/$',
r"^local_scheduler/start/$",
api.start_local_scheduler,
name='local_scheduler-start',
name="local_scheduler-start",
),
url(
r'^local_scheduler/stop/$',
r"^local_scheduler/stop/$",
api.stop_local_scheduler,
name='local_scheduler-stop',
name="local_scheduler-stop",
),
]
......@@ -25,33 +25,26 @@
# #
###############################################################################
from django.utils import six
from django.shortcuts import get_object_or_404
from django.core.exceptions import ValidationError
from rest_framework import generics
from rest_framework import permissions
from rest_framework.response import Response
from rest_framework.exceptions import PermissionDenied, ParseError
from rest_framework import serializers
from rest_framework import exceptions as drf_exceptions
from ..common.responses import ForbiddenResponse
from ..common.api import ShareView, RetrieveUpdateDestroyContributionView
from ..common.utils import validate_restructuredtext, ensure_html
from ..common.serializers import DiffSerializer
from ..code.models import Code
from .serializers import CodeSharingSerializer, CodeSerializer
import simplejson as json
class ShareCodeView(ShareView):
serializer_class = CodeSharingSerializer
def do_share(self, obj, data):
users = data.get('users', None)
teams = data.get('teams', None)
public = data.get('status') == 'public'
users = data.get("users", None)
teams = data.get("teams", None)
public = data.get("status") == "public"
obj.share(public=public, users=users, teams=teams)
......@@ -62,35 +55,36 @@ class DiffView(generics.RetrieveAPIView):