From ba8ba8635325b4d7bdd6b02c2e444431de9a8444 Mon Sep 17 00:00:00 2001
From: Philip ABBET <philip.abbet@idiap.ch>
Date: Wed, 16 Nov 2016 15:58:54 +0100
Subject: [PATCH] [website] Allow the creation of a new binary algorithm

---
 beat/web/algorithms/models.py                 |  6 +-
 .../templates/algorithms/edition.html         | 80 ++++++++++++++-----
 .../templates/algorithms/panels/editor.html   |  4 +-
 beat/web/algorithms/tests/tests_api.py        | 32 +-------
 beat/web/code/models.py                       | 14 ++--
 beat/web/code/serializers.py                  |  8 --
 6 files changed, 72 insertions(+), 72 deletions(-)

diff --git a/beat/web/algorithms/models.py b/beat/web/algorithms/models.py
index 9e9b90648..dbd68887b 100755
--- 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, language=None, code=None,
-                         version=1, previous_version=None, fork_of=None):
+                         description='', declaration=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, language, code, version,
+                                description, declaration, code, version,
                                 previous_version, fork_of)
 
 
diff --git a/beat/web/algorithms/templates/algorithms/edition.html b/beat/web/algorithms/templates/algorithms/edition.html
index 21a91d308..1af55e4be 100644
--- a/beat/web/algorithms/templates/algorithms/edition.html
+++ b/beat/web/algorithms/templates/algorithms/edition.html
@@ -177,6 +177,22 @@ function setupEditor(algorithm, dataformats, libraries)
   });
 
 
+  // Language radio buttons handling
+  var language_python_selector = $('#language_python');
+  var language_cxx_selector = $('#language_cxx');
+
+  language_python_selector.change(function() {
+    $('#source_code_editor').show();
+    $('#libraries-editor-panel').show();
+    source_code_editor.editor.refresh();
+  });
+
+  language_cxx_selector.change(function() {
+    $('#source_code_editor').hide();
+    $('#libraries-editor-panel').hide();
+  });
+
+
   // Save button checkbox handling
   $('.button_save').click(function() {
 
@@ -196,6 +212,11 @@ function setupEditor(algorithm, dataformats, libraries)
       language: 'python',
     };
 
+    if (language_python_selector[0].checked)
+      declaration.language = 'python';
+    else
+      declaration.language = 'cxx';
+
     if (!checkbox_analyzer[0].checked)
     {
       declaration.splittable = checkbox_splittable[0].checked;
@@ -215,9 +236,33 @@ function setupEditor(algorithm, dataformats, libraries)
     if (declaration.parameters === null)
       return false;
 
-    declaration.uses = libraries_panel.getLibraries(displayErrors);
-    if (declaration.uses === null)
-      return false;
+    if (language_python_selector[0].checked)
+    {
+      declaration.uses = libraries_panel.getLibraries(displayErrors);
+      if (declaration.uses === null)
+        return false;
+    }
+
+
+    var data = {
+      {% if not edition %}
+      {% if algorithm_version > 1 and not fork_of %}
+      name: '{{ algorithm_name }}',
+      previous_version:'{{ algorithm_author }}/{{ algorithm_name }}/{{ algorithm_version|add:-1 }}',
+      {% else %}
+      name: $('#algorithm_name')[0].value.trim(),
+      {% endif %}
+      description: (algorithm && algorithm.description) || '',
+      {% endif %}
+      short_description: (algorithm && algorithm.short_description) || '',
+      declaration: JSON.stringify(declaration),
+      {% if fork_of %}
+      fork_of: '{{ fork_of.fullname }}',
+      {% endif %}
+    };
+
+    if (language_python_selector[0].checked)
+      data.code = source_code_editor.getSourceCode();
 
 
     $.ajax({
@@ -228,23 +273,7 @@ function setupEditor(algorithm, dataformats, libraries)
       type: 'POST',
       url: '{% url 'api_algorithms:list_create' algorithm_author %}',
         {% endif %}
-      data: JSON.stringify({
-        {% if not edition %}
-        {% if algorithm_version > 1 and not fork_of %}
-        name: '{{ algorithm_name }}',
-        previous_version:'{{ algorithm_author }}/{{ algorithm_name }}/{{ algorithm_version|add:-1 }}',
-        {% else %}
-        name: $('#algorithm_name')[0].value.trim(),
-        {% endif %}
-        description: (algorithm && algorithm.description) || '',
-        {% endif %}
-        short_description: (algorithm && algorithm.short_description) || '',
-        declaration: JSON.stringify(declaration),
-        code: source_code_editor.getSourceCode(),
-        {% if fork_of %}
-        fork_of: '{{ fork_of.fullname }}',
-        {% endif %}
-      }),
+      data: JSON.stringify(data),
       contentType: "application/json; charset=utf-8",
       dataType: "json",
       success: function(data) {
@@ -338,6 +367,17 @@ function setupEditor(algorithm, dataformats, libraries)
   </div>
 </div>
 
+{% if not edition %}
+<div class="row">
+  <div class="col-sm-offset-1 col-sm-10 contribution_editor" style="display: none;">
+    <label for="language_python">Language:</label>
+    <input id="language_python" type="radio" name="language" checked /><span class="label">Python</span>
+    <input id="language_cxx" type="radio" name="language" /><span class="label">C++</span>
+    <p class="help">The language you'll use to write this algorithm. Note that this cannot be changed later!</p>
+  </div>
+</div>
+{% endif %}
+
 
 <div class="row">
   <div class="col-sm-offset-1 col-sm-10">
diff --git a/beat/web/algorithms/templates/algorithms/panels/editor.html b/beat/web/algorithms/templates/algorithms/panels/editor.html
index 3a855db0d..711ddd31b 100644
--- a/beat/web/algorithms/templates/algorithms/panels/editor.html
+++ b/beat/web/algorithms/templates/algorithms/panels/editor.html
@@ -228,7 +228,7 @@
     {% endwith %}{# groups, uses or parameters #}
     {% endwith %}{# groups, uses or parameters #}
 
-    {% if open_source %}
+    {% if open_source and not object.is_binary %}
     <textarea class="form-control" id="code-display">{{ object.source_code_file.read }}</textarea>
     <p class="help-block">{{ texts.code|safe }}</p>
     {% else %}
@@ -246,7 +246,7 @@
 
 </div>
 
-{% if open_source %}
+{% if open_source and not object.is_binary %}
 <script type="text/javascript">
 $(document).ready(function() {
   var code_textarea = $('textarea#code-display');
diff --git a/beat/web/algorithms/tests/tests_api.py b/beat/web/algorithms/tests/tests_api.py
index 1bff20107..b9114418c 100755
--- a/beat/web/algorithms/tests/tests_api.py
+++ b/beat/web/algorithms/tests/tests_api.py
@@ -923,7 +923,7 @@ class AlgorithmCreation(AlgorithmsAPIBase):
         self.checkResponse(response, 400, content_type='application/json')
 
 
-    def test_cxx_algorithm_using_declaration(self):
+    def test_cxx_algorithm(self):
         self.client.login(username='jackdoe', password='1234')
 
         response = self.client.post(self.url,
@@ -954,36 +954,6 @@ class AlgorithmCreation(AlgorithmsAPIBase):
         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):
diff --git a/beat/web/code/models.py b/beat/web/code/models.py
index 768e8c542..4ad4eb905 100755
--- a/beat/web/code/models.py
+++ b/beat/web/code/models.py
@@ -51,13 +51,13 @@ import simplejson
 class CodeManager(StoredContributionManager):
 
     def create_object(self, author, name, short_description='', description='',
-                      declaration=None, language=None, code=None, version=1,
-                      previous_version=None, fork_of=None):
+                      declaration=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, language=language,
-                      code=code, version=version, previous_version=previous_version,
+                      description=description, declaration=declaration, code=code,
+                      version=version, previous_version=previous_version,
                       fork_of=fork_of)
 
     def for_user(self, user, add_public=False):
@@ -103,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, language=None, code=None,
-                    version=1, previous_version=None, fork_of=None):
+                    description='', declaration=None, code=None, version=1,
+                    previous_version=None, fork_of=None):
 
         # Create the database representation
         code_db = self.model(
@@ -124,8 +124,6 @@ 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 75569fe62..efcd03240 100755
--- a/beat/web/code/serializers.py
+++ b/beat/web/code/serializers.py
@@ -43,18 +43,10 @@ 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', '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)
-
 
 #----------------------------------------------------------
 
-- 
GitLab