diff --git a/beat/web/algorithms/models.py b/beat/web/algorithms/models.py old mode 100644 new mode 100755 index 28864f02222654f25b90b1e62861c7af1f0b67a4..9e9b906482bb4484d456b3fd5b80ac7f38c3e4ed --- a/beat/web/algorithms/models.py +++ b/beat/web/algorithms/models.py @@ -93,13 +93,13 @@ class AlgorithmStorage(OverwriteStorage): class AlgorithmManager(CodeManager): def create_algorithm(self, author, name, short_description='', - description='', declaration=None, code=None, version=1, - previous_version=None, fork_of=None): + description='', declaration=None, language=None, code=None, + version=1, previous_version=None, fork_of=None): default = beat.core.algorithm.Algorithm(settings.PREFIX, data=None) return self.create_code(author, name, default, short_description, - description, declaration, code, version, + description, declaration, language, code, version, previous_version, fork_of) @@ -307,6 +307,9 @@ class Algorithm(Code): def deletable(self): return (self.experiments.count() == 0) and super(Algorithm, self).deletable() + def valid(self): + return (self.source_code_file.name is not None) and (self.source_code_file.name != '') + def core(self): return validate_algorithm(self.declaration) diff --git a/beat/web/algorithms/tests/core.py b/beat/web/algorithms/tests/core.py index ed684d6646c46f2069583e87bd24cb4f0dc1b986..8bebec3fe64802df39d00b9040674991882533c3 100755 --- a/beat/web/algorithms/tests/core.py +++ b/beat/web/algorithms/tests/core.py @@ -320,10 +320,13 @@ class AlgorithmsTestCase(AlgorithmsBaseTestCase): declaration=declaration, ) assert algorithm, errors + assert not algorithm.valid() algorithm.source_code = binary_data algorithm.save() + assert algorithm.valid() + # Usable by one user (algorithm, errors) = Algorithm.objects.create_algorithm( author=user1, diff --git a/beat/web/algorithms/tests/tests_api.py b/beat/web/algorithms/tests/tests_api.py index 5604c781c24e47a1e559d07b8a76990e065f0161..1bff201072f4872b44c0d8574241d523d1c0c469 100755 --- a/beat/web/algorithms/tests/tests_api.py +++ b/beat/web/algorithms/tests/tests_api.py @@ -35,6 +35,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile from ...dataformats.models import DataFormat from ...common.testutils import tearDownModule +from ...code.models import Code import beat.core.algorithm @@ -561,14 +562,17 @@ class AlgorithmCreation(AlgorithmsAPIBase): "declaration (beyond white spaces): %r != %r" % \ (in_storage, expected) - # set storage language so it can find the code - storage.language = in_storage['language'] + if in_storage['language'] == 'python': + self.assertTrue(algorithm.valid()) - in_storage = storage.code.try_load() - expected = code + # set storage language so it can find the code + storage.language = in_storage['language'] - assert in_storage == expected, "There are differences on the " \ - "code: %r != %r" % (in_storage, expected) + in_storage = storage.code.try_load() + expected = code + + assert in_storage == expected, "There are differences on the " \ + "code: %r != %r" % (in_storage, expected) def test_no_creation_for_anonymous_user(self): @@ -919,6 +923,68 @@ class AlgorithmCreation(AlgorithmsAPIBase): self.checkResponse(response, 400, content_type='application/json') + def test_cxx_algorithm_using_declaration(self): + self.client.login(username='jackdoe', password='1234') + + response = self.client.post(self.url, + json.dumps({ + 'name': 'valid-name1', + 'description': 'blah', + 'declaration':AlgorithmsAPIBase.CXX_DECLARATION, + }), content_type='application/json') + + url = reverse('api_algorithms:object', args=['jackdoe', 'valid-name1', 1]) + content = self.checkResponse(response, 201, + content_type='application/json', + location=url) + + self.assertTrue(isinstance(content, dict)) + self.assertEqual(content['name'], 'valid-name1') + self.assertTrue(content['url'].endswith(url)) + + try: + algorithm = Algorithm.objects.get(author__username='jackdoe', name='valid-name1') + except: + self.assertTrue(False) + + self.assertEqual(algorithm.short_description, '') + self.assertEqual(algorithm.description, 'blah') + self.assertEqual(algorithm.language, Code.CXX) + self.assertFalse(algorithm.valid()) + self.checkAlgorithm(algorithm, declaration=AlgorithmsAPIBase.CXX_DECLARATION, code=None) + + + def test_cxx_algorithm_using_language(self): + self.client.login(username='jackdoe', password='1234') + + response = self.client.post(self.url, + json.dumps({ + 'name': 'valid-name1', + 'description': 'blah', + 'language': 'cxx', + }), content_type='application/json') + + url = reverse('api_algorithms:object', args=['jackdoe', 'valid-name1', 1]) + content = self.checkResponse(response, 201, + content_type='application/json', + location=url) + + self.assertTrue(isinstance(content, dict)) + self.assertEqual(content['name'], 'valid-name1') + self.assertTrue(content['url'].endswith(url)) + + try: + algorithm = Algorithm.objects.get(author__username='jackdoe', name='valid-name1') + except: + self.assertTrue(False) + + self.assertEqual(algorithm.short_description, '') + self.assertEqual(algorithm.description, 'blah') + self.assertEqual(algorithm.language, Code.CXX) + self.assertFalse(algorithm.valid()) + + + class AlgorithmUpdate(AlgorithmsAPIBase): def setUp(self): super(AlgorithmUpdate, self).setUp() diff --git a/beat/web/code/models.py b/beat/web/code/models.py index 8131372e834bda79f8456fe07ffc7069b8f4144e..768e8c5422a07657404a851d542773601146509d 100755 --- a/beat/web/code/models.py +++ b/beat/web/code/models.py @@ -51,12 +51,14 @@ import simplejson class CodeManager(StoredContributionManager): def create_object(self, author, name, short_description='', description='', - declaration=None, code=None, version=1, previous_version=None, - fork_of=None): + declaration=None, language=None, code=None, version=1, + previous_version=None, fork_of=None): create = getattr(self, 'create_{}'.format(self.model.__name__.lower())) - return create(author=author, name=name, short_description=short_description, description=description, - declaration=declaration, code=code, version=version, previous_version=previous_version, fork_of=fork_of) + return create(author=author, name=name, short_description=short_description, + description=description, declaration=declaration, language=language, + code=code, version=version, previous_version=previous_version, + fork_of=fork_of) def for_user(self, user, add_public=False): if user.is_anonymous(): @@ -101,8 +103,8 @@ class CodeManager(StoredContributionManager): return objects_for_user.order_by('author__username', 'name', '-version').select_related() def create_code(self, author, name, default, short_description='', - description='', declaration=None, code=None, version=1, - previous_version=None, fork_of=None): + description='', declaration=None, language=None, code=None, + version=1, previous_version=None, fork_of=None): # Create the database representation code_db = self.model( @@ -122,6 +124,8 @@ class CodeManager(StoredContributionManager): declaration = fork_of.declaration else: declaration = default.data + if language is not None: + declaration['language'] = language elif not(isinstance(declaration, dict)): declaration = simplejson.loads(declaration) diff --git a/beat/web/code/serializers.py b/beat/web/code/serializers.py index b50d101f613ba416e2d711eb2f726f5adfb86df6..75569fe620f333c55b6e94a5ec0c0ac9dea51f46 100755 --- a/beat/web/code/serializers.py +++ b/beat/web/code/serializers.py @@ -43,9 +43,17 @@ import difflib class CodeCreationSerializer(ContributionCreationSerializer): code = serializers.CharField(required=False, allow_blank=True, trim_whitespace=False) + language = serializers.CharField(required=False, allow_blank=True, trim_whitespace=False) class Meta(ContributionCreationSerializer.Meta): - fields = ContributionCreationSerializer.Meta.fields + ['code'] + fields = ContributionCreationSerializer.Meta.fields + ['code', 'language'] + + def validate_language(self, value): + try: + if len(filter(lambda x: x[1].lower() == value, iter(Code.CODE_LANGUAGE))) > 0: + return value + except: + raise serializers.ValidationError('Unsupported language: %s' % value) #----------------------------------------------------------