diff --git a/beat/web/common/serializers.py b/beat/web/common/serializers.py index d3e6b3bcaf6b0e6b5c79b910e884bd6aee2db0c9..a829de03a43a91ae69c382db28be1d08a3880ff3 100644 --- a/beat/web/common/serializers.py +++ b/beat/web/common/serializers.py @@ -27,15 +27,13 @@ from django.conf import settings -from django.core.exceptions import ValidationError from django.contrib.auth.models import User from django.utils import six from rest_framework import serializers from ..team.models import Team -from ..ui.templatetags.gravatar import gravatar_url -from ..common.utils import validate_restructuredtext, ensure_html +from ..common.utils import ensure_html from .models import Shareable, Versionable, Contribution from .exceptions import ContributionCreationError @@ -44,24 +42,22 @@ from .fields import JSONSerializerField, StringListField import simplejson as json import difflib -import ast - -#---------------------------------------------------------- +# ---------------------------------------------------------- class DiffSerializer(serializers.Serializer): diff = serializers.SerializerMethodField() def get_diff(self, obj): - source1 = json.dumps(obj['object1'].declaration, indent=4) - source2 = json.dumps(obj['object2'].declaration, indent=4) + source1 = json.dumps(obj["object1"].declaration, indent=4) + source2 = json.dumps(obj["object2"].declaration, indent=4) diff = difflib.ndiff(source1.splitlines(), source2.splitlines()) - return '\n'.join(filter(lambda x: x[0] != '?', list(diff))) + return "\n".join(filter(lambda x: x[0] != "?", list(diff))) -#---------------------------------------------------------- +# ---------------------------------------------------------- class CheckNameSerializer(serializers.Serializer): @@ -72,16 +68,16 @@ class CheckNameSerializer(serializers.Serializer): return Contribution.sanitize_name(name) def get_used(self, obj): - name = obj.get('name') - model = self.context.get('model') - user = self.context.get('user') + name = obj.get("name") + model = self.context.get("model") + user = self.context.get("user") return model.objects.filter(author=user, name=name).exists() def create(self, validated_data): return validated_data -#---------------------------------------------------------- +# ---------------------------------------------------------- class SharingSerializer(serializers.Serializer): @@ -89,22 +85,28 @@ class SharingSerializer(serializers.Serializer): teams = StringListField(required=False) def validate_users(self, users): - user_accounts = User.objects.filter(username__in=users).values_list('username', flat=True) + user_accounts = User.objects.filter(username__in=users).values_list( + "username", flat=True + ) if len(users) != user_accounts.count(): unknown_users = [user for user in users if user not in user_accounts] if len(unknown_users) > 1: - raise serializers.ValidationError(['Unknown usernames: ' + ', '.join(unknown_users)]) + raise serializers.ValidationError( + ["Unknown usernames: " + ", ".join(unknown_users)] + ) else: - raise serializers.ValidationError(['Unknown username: ' + unknown_users[0]]) + raise serializers.ValidationError( + ["Unknown username: " + unknown_users[0]] + ) return users def validate_teams(self, teams): unknown_teams = [] - user = self.context.get('user') + user = self.context.get("user") for team_name in teams: - parts = team_name.split('/') + parts = team_name.split("/") if len(parts) > 2: unknown_teams.append(team_name) @@ -118,14 +120,16 @@ class SharingSerializer(serializers.Serializer): unknown_teams.append(team_name) if len(unknown_teams) > 1: - raise serializers.ValidationError('Unknown teams: ' + ', '.join(unknown_teams)) + raise serializers.ValidationError( + "Unknown teams: " + ", ".join(unknown_teams) + ) elif len(unknown_teams) == 1: - raise serializers.ValidationError('Unknown team: ' + unknown_teams[0]) + raise serializers.ValidationError("Unknown team: " + unknown_teams[0]) return teams -#---------------------------------------------------------- +# ---------------------------------------------------------- class DynamicFieldsSerializer(serializers.ModelSerializer): @@ -134,7 +138,7 @@ class DynamicFieldsSerializer(serializers.ModelSerializer): def __init__(self, *args, **kwargs): # Don't pass the 'fields' arg up to the superclass - fields = kwargs.pop('fields', self.Meta.default_fields) + fields = kwargs.pop("fields", self.Meta.default_fields) # Instantiate the superclass normally super(DynamicFieldsSerializer, self).__init__(*args, **kwargs) @@ -146,7 +150,7 @@ class DynamicFieldsSerializer(serializers.ModelSerializer): self.fields.pop(field_name) -#---------------------------------------------------------- +# ---------------------------------------------------------- class ShareableSerializer(DynamicFieldsSerializer): @@ -158,43 +162,50 @@ class ShareableSerializer(DynamicFieldsSerializer): class Meta(DynamicFieldsSerializer.Meta): model = Shareable - default_fields = DynamicFieldsSerializer.Meta.default_fields + \ - ['is_owner', 'modifiable', 'deletable', 'sharing'] + default_fields = DynamicFieldsSerializer.Meta.default_fields + [ + "is_owner", + "modifiable", + "deletable", + "sharing", + ] def get_accessibility(self, obj): if obj.sharing == Versionable.PUBLIC: - return 'public' + return "public" elif obj.sharing == Versionable.SHARED or obj.sharing == Versionable.USABLE: - return 'confidential' + return "confidential" else: - return 'private' - + return "private" def get_sharing(self, obj): - user = self.context.get('user') + user = self.context.get("user") sharing = None - if hasattr(obj, 'author') and user == obj.author: - sharing = {'status': obj.get_sharing_display().lower()} + if hasattr(obj, "author") and user == obj.author: + sharing = {"status": obj.get_sharing_display().lower()} if obj.shared_with.count() > 0: - sharing['shared_with'] = [user.username for user in obj.shared_with.all()] + sharing["shared_with"] = [ + user.username for user in obj.shared_with.all() + ] if obj.shared_with_team.count() > 0: - sharing['shared_with_team'] = [team.fullname() for team in obj.shared_with_team.all()] + sharing["shared_with_team"] = [ + team.fullname() for team in obj.shared_with_team.all() + ] return sharing def get_is_owner(self, obj): - if hasattr(obj, 'author'): - return obj.author == self.context.get('user') + if hasattr(obj, "author"): + return obj.author == self.context.get("user") return False -#---------------------------------------------------------- +# ---------------------------------------------------------- class VersionableSerializer(ShareableSerializer): - name = serializers.CharField(source='fullname') + name = serializers.CharField(source="fullname") fork_of = serializers.SerializerMethodField() last_version = serializers.SerializerMethodField() previous_version = serializers.SerializerMethodField() @@ -205,28 +216,33 @@ class VersionableSerializer(ShareableSerializer): class Meta(ShareableSerializer.Meta): model = Versionable - default_fields = ShareableSerializer.Meta.default_fields + ['name', 'version', 'last_version', - 'short_description', - 'fork_of', 'previous_version', - 'accessibility', - 'hash', - 'creation_date'] + default_fields = ShareableSerializer.Meta.default_fields + [ + "name", + "version", + "last_version", + "short_description", + "fork_of", + "previous_version", + "accessibility", + "hash", + "creation_date", + ] def get_fork_of(self, obj): - if not(obj.fork_of): + if not (obj.fork_of): return None - accessibility_infos = obj.fork_of.accessibility_for(self.context.get('user')) + accessibility_infos = obj.fork_of.accessibility_for(self.context.get("user")) return obj.fork_of.fullname() if accessibility_infos[0] else None def get_last_version(self, obj): return self.Meta.model.objects.is_last_version(obj) def get_previous_version(self, obj): - if not(obj.previous_version): + if not (obj.previous_version): return None - user = self.context.get('user') + user = self.context.get("user") previous_version = obj.previous_version while previous_version is not None: @@ -240,10 +256,10 @@ class VersionableSerializer(ShareableSerializer): def get_history(self, obj): - return obj.api_history(self.context.get('user')) + return obj.api_history(self.context.get("user")) -#---------------------------------------------------------- +# ---------------------------------------------------------- class ContributionSerializer(VersionableSerializer): @@ -253,18 +269,18 @@ class ContributionSerializer(VersionableSerializer): class Meta(VersionableSerializer.Meta): model = Contribution - extra_fields = ['description', 'declaration'] - exclude = ['description_file', 'declaration_file'] + extra_fields = ["description", "declaration"] + exclude = ["description_file", "declaration_file"] def get_description(self, obj): result = obj.description if six.PY2: - result = result.decode('utf-8') + result = result.decode("utf-8") return result def get_declaration(self, obj): - object_format = self.context.get('object_format') - if object_format == 'string': + object_format = self.context.get("object_format") + if object_format == "string": return json.dumps(obj.declaration, indent=4) else: return obj.declaration @@ -273,10 +289,11 @@ class ContributionSerializer(VersionableSerializer): description = obj.description if len(description) > 0: return ensure_html(description) - return '' + return "" + +# ---------------------------------------------------------- -#---------------------------------------------------------- class MapDot(dict): def __init__(self, *args, **kwargs): @@ -315,50 +332,57 @@ class ContributionCreationSerializer(serializers.ModelSerializer): previous_version = serializers.CharField(required=False) class Meta: - fields = ['name', 'short_description', 'description', - 'declaration', 'previous_version', - 'fork_of'] + fields = [ + "name", + "short_description", + "description", + "declaration", + "previous_version", + "fork_of", + ] beat_core_class = None def validate_description(self, description): - if description.find('\\') >= 0: #was escaped, unescape - description = description.decode('string_escape') + if description.find("\\") >= 0: # was escaped, unescape + description = description.decode("string_escape") return description def validate(self, data): - user = self.context.get('user') - name = self.Meta.model.sanitize_name(data['name']) - data['name'] = name + user = self.context.get("user") + name = self.Meta.model.sanitize_name(data["name"]) + data["name"] = name - if 'previous_version' in data: + if "previous_version" in data: if self.Meta.beat_core_class is not None: - previous_version_id = self.Meta.beat_core_class.Storage(settings.PREFIX, - data['previous_version']) + previous_version_id = self.Meta.beat_core_class.Storage( + settings.PREFIX, data["previous_version"] + ) if previous_version_id.username is None: previous_version_id.username = user.username else: - previous_version_id = MapDot() - previous_version_id["username"] = user.username - previous_version_id["name"] = name - previous_version_id["version"] = data['previous_version'] - data['data'] = json.dumps(data['data']) + previous_version_id = MapDot() + previous_version_id["username"] = user.username + previous_version_id["name"] = name + previous_version_id["version"] = data["previous_version"] + data["data"] = json.dumps(data["data"]) else: previous_version_id = None - if 'fork_of' in data: + if "fork_of" in data: if self.Meta.beat_core_class is not None: - fork_of_id = self.Meta.beat_core_class.Storage(settings.PREFIX, - data['fork_of']) + fork_of_id = self.Meta.beat_core_class.Storage( + settings.PREFIX, data["fork_of"] + ) if fork_of_id.username is None: fork_of_id.username = user.username else: - fork_of_id = MapDot() - fork_elem = data['fork_of'] - fork_of_id["username"] = fork_elem['username'] - fork_of_id["name"] = fork_elem['name'] - fork_of_id["version"] = fork_elem['version'] - data['data'] = json.dumps(data['data']) + fork_of_id = MapDot() + fork_elem = data["fork_of"] + fork_of_id["username"] = fork_elem["username"] + fork_of_id["name"] = fork_elem["name"] + fork_of_id["version"] = fork_elem["version"] + data["data"] = json.dumps(data["data"]) else: fork_of_id = None @@ -369,45 +393,60 @@ class ContributionCreationSerializer(serializers.ModelSerializer): previous_version = self.Meta.model.objects.get( author__username__iexact=previous_version_id.username, name=previous_version_id.name, - version=previous_version_id.version) - except: - raise serializers.ValidationError("{} '{}' not found".format( - self.Meta.model.__name__, - previous_version_id.fullname) - ) + version=previous_version_id.version, + ) + except self.Meta.model.DoesNotExist: + raise serializers.ValidationError( + "{} '{}' not found".format( + self.Meta.model.__name__, previous_version_id.fullname + ) + ) is_accessible = previous_version.accessibility_for(user) if not is_accessible[0]: - raise serializers.ValidationError('No access allowed') - data['previous_version'] = previous_version + raise serializers.ValidationError("No access allowed") + data["previous_version"] = previous_version # Retrieve the forked algorithm (if applicable) if fork_of_id is not None: try: - fork_of = self.Meta.model.objects.get(author__username__iexact=fork_of_id.username, - name=fork_of_id.name, - version=fork_of_id.version) - except: - raise serializers.ValidationError("{} '{}' not found".format(self.Meta.model.__name__, fork_of_id.fullname)) + fork_of = self.Meta.model.objects.get( + author__username__iexact=fork_of_id.username, + name=fork_of_id.name, + version=fork_of_id.version, + ) + except self.Meta.model.DoesNotExist: + raise serializers.ValidationError( + "{} '{}' not found".format( + self.Meta.model.__name__, fork_of_id.fullname + ) + ) is_accessible = fork_of.accessibility_for(user) if not is_accessible[0]: - raise serializers.ValidationError('No access allowed') - data['fork_of'] = fork_of + raise serializers.ValidationError("No access allowed") + data["fork_of"] = fork_of # Determine the version number last_version = None if previous_version_id is not None: - if (previous_version_id.username == user.username) and \ - (previous_version_id.name == name): - last_version = self.Meta.model.objects.filter(author=user, name=name).order_by('-version')[0] + if (previous_version_id.username == user.username) and ( + previous_version_id.name == name + ): + last_version = self.Meta.model.objects.filter( + author=user, name=name + ).order_by("-version")[0] if last_version is None: if self.Meta.model.objects.filter(author=user, name=name).count() > 0: - raise serializers.ValidationError('This {} name already exists on this account'.format(self.Meta.model.__name__.lower())) + raise serializers.ValidationError( + "This {} name already exists on this account".format( + self.Meta.model.__name__.lower() + ) + ) - data['version'] = (last_version.version + 1 if last_version is not None else 1) + data["version"] = last_version.version + 1 if last_version is not None else 1 return data