Removed references to REPOSITORY_NAME + some refactoring of cat_editor in views.py (wtforms)
authorNicolas DURAND <nicolas.durand@iri.centrepompidou.fr>
Tue, 06 Jan 2015 15:01:45 +0100
changeset 23 877c3b66313a
parent 22 0ba28595fd4d
child 24 612f669ce3d0
Removed references to REPOSITORY_NAME + some refactoring of cat_editor in views.py (wtforms)
src/catedit/config.py.tmpl
src/catedit/resources.py
src/catedit/static/js/property_functions.js
src/catedit/templates/cateditor.html
src/catedit/views.py
--- a/src/catedit/config.py.tmpl	Mon Jan 05 18:03:55 2015 +0100
+++ b/src/catedit/config.py.tmpl	Tue Jan 06 15:01:45 2015 +0100
@@ -27,7 +27,10 @@
 
     # Github repository config
 
-    REPOSITORY_NAME = "catedit-dev-testing"
+    REPOSITORY_LIST = [
+      "catedit-dev-testing",
+      "habitabilite-prototype"
+    ]
     REPOSITORY_OWNER = "catedit-system"
     CATEGORIES_PATH = "categories/"
 
--- a/src/catedit/resources.py	Mon Jan 05 18:03:55 2015 +0100
+++ b/src/catedit/resources.py	Tue Jan 06 15:01:45 2015 +0100
@@ -19,10 +19,11 @@
 cat_parser = reqparse.RequestParser()
 cat_parser.add_argument('label', type=str)
 cat_parser.add_argument('description', type=str)
-cat_parser.add_argument('commit_message', type=str)
 cat_parser.add_argument('property_predicate', type=str, action="append")
 cat_parser.add_argument('property_object', type=str, action="append")
 
+cat_parser.add_argument('commit_message', type=str)
+
 
 class CategoryAPI(Resource):
     """
@@ -49,14 +50,16 @@
             for cat in cat_manager_instance.list_categories():
                 response.append(cat.cat_graph.serialize(format='turtle')
                                              .decode("utf-8"))
+            if response == []:
+                return 404
             return response
 
     # update category cat_id
     def put(self, repository, cat_id=None):
         """
-            API to edit the category of id cat_id
-            * If None and persistence support change sets, will submit all
-            changes to category list
+            API to edit an existing category
+            * If cat_id is None and persistence support change sets, will
+            submit all changes to category list
         """
         cat_manager_instance = CategoryManager(
             getattr(
@@ -349,7 +352,10 @@
                                                 [modified_cat_id]
                     }
                 }, 201
-            return 404
+            return {
+                "type": "untouched",
+                "category": modified_cat_id
+            }, 201
 
     def delete(self, repository, modified_cat_id=None):
         """
--- a/src/catedit/static/js/property_functions.js	Mon Jan 05 18:03:55 2015 +0100
+++ b/src/catedit/static/js/property_functions.js	Tue Jan 06 15:01:45 2015 +0100
@@ -52,7 +52,7 @@
                                    <td id="object_td'+(createdProperties+1)+'">'
                                      +propertyObjectText+
                                   '</td> \
-                                   <td id="delete_button'+(createdProperties+1)+'"> \
+                                   <td id="delete_button'+(createdProperties+1)+'" class="text-center"> \
                                     <input type="button" id="property_delete_button'+(createdProperties+1)+'" class="btn btn-default property-delete-button" onClick="CatEditScripts.removeProperty('+(createdProperties+1)+',properties)" value="Supprimer"> \
                                    </td>';
 
--- a/src/catedit/templates/cateditor.html	Mon Jan 05 18:03:55 2015 +0100
+++ b/src/catedit/templates/cateditor.html	Tue Jan 06 15:01:45 2015 +0100
@@ -85,7 +85,7 @@
     </div>
     <div class="alert alert-warning hidden" role="alert" id="uriref-category-field-text">
     </div>
-    <div id="properties" class="row">
+    <div id="properties">
       <div class="row">
         <div class="col-md-6">
           <br>
@@ -125,7 +125,7 @@
                         {{ object }}
                       {% endif %}
                     </td>
-                    <td id="delete_button_td{{ property_count }}">
+                    <td id="delete_button_td{{ property_count }}" class="text-center">
                       <input type="button" id="property_delete_button{{ property_count }}" class="btn btn-default property-delete-button" onClick="CatEditScripts.removeProperty({{ property_count }}, 'properties')" value="Supprimer">
                     </td>
                   {% endif %}
@@ -136,7 +136,7 @@
           </table>
         </div>
       </div>
-    </div><br><br>
+    </div><br>
     <input type="submit" value="Sauvegarder" class="btn btn-default">
     <a href="{{ url_for('cat_recap', repository=current_repository)}}"class="btn btn-default">Annuler</a>
   </form>
--- a/src/catedit/views.py	Mon Jan 05 18:03:55 2015 +0100
+++ b/src/catedit/views.py	Tue Jan 06 15:01:45 2015 +0100
@@ -10,15 +10,23 @@
 from flask.ext.github import GitHubError
 from flask_wtf import Form
 from catedit.resources import CategoryAPI, CategoryChangesAPI
-from wtforms import StringField, TextAreaField
-from wtforms.validators import DataRequired
+from wtforms import StringField, TextAreaField, \
+                    FormField, FieldList, HiddenField
+from wtforms.validators import DataRequired, Optional, AnyOf
 from rdflib import Graph
 from io import StringIO
 
 logger = app.logger
 
+class PropertyForm(Form):
+    property_predicate = HiddenField(
+        validators=[AnyOf(values=app.config["PROPERTY_LIST"].keys())]
+    )
+    property_object = HiddenField(
+        validators=[DataRequired()]
+    )
 
-class NewCategoryMinimalForm(Form):
+class CategoryForm(Form):
     """
         Custom form class for creating a category with the absolute minimal
         attributes (label and description)
@@ -31,7 +39,7 @@
         "Description de la categorie (obligatoire)",
         validators=[DataRequired()]
     )
-
+    properties = FieldList(FormField(PropertyForm),validators=[Optional()])
 
 class CommitForm(Form):
     """
@@ -40,7 +48,7 @@
     commit_message = StringField(
         "Message de soumission (obligatoire)",
         validators=[DataRequired()]
-        )
+    )
 
 
 @app.route('/', methods=['GET'])
@@ -310,28 +318,81 @@
     cat_api_instance = CategoryAPI()
     cat_changes_api_instance = CategoryChangesAPI()
 
-    cat_list = []
-    deleted_cat_list = []
-    modified_cat_dict = {}
-    serialized_cat_list = []
-    if session.get("user_logged", None) is not None:
-        serialized_cat_list = cat_api_instance.get(repository)
-        cat_changes = cat_changes_api_instance.get(repository)
-        deleted_cat_list = list(cat_changes[0]["deleted_categories"].keys())
-        modified_cat_dict = cat_changes[0]["modified_categories"]
-    for serialized_cat in serialized_cat_list:
+    specific_serialized_cat = ""
+    # serialization of the category of id cat_id, either from
+    # CategoryChangesAPI (if it was modified) or from CategoryAPI (if it
+    # was not)
+
+    changes_response = None
+    # Changes on the category cat_id we get from CategoryChangesAPI
+
+    current_cat = None
+    current_cat_id = None
+    current_cat_properties = []
+    # Args for the template, if we create a new category they are not used
+
+    if cat_id is not None:
+        if session.get("user_logged", None) is not None:
+            changes_response = cat_changes_api_instance.get(
+                repository=repository,
+                modified_cat_id=cat_id
+            )
+            if changes_response[0]["type"] is "deleted":
+                abort(404)
+            elif changes_response[0]["type"] is "modified":
+                specific_serialized_cat = changes_response[0] \
+                                                          ["category"] \
+                                                          [cat_id]
+            elif changes_response[0]["type"] is "untouched":
+                specific_serialized_cat = cat_api_instance.get(
+                    repository=repository,
+                    cat_id=cat_id
+                )
+        logger.debug(specific_serialized_cat)
+
         cat_rdf_graph = Graph()
-        cat_rdf_graph.parse(source=StringIO(serialized_cat),
+        cat_rdf_graph.parse(source=StringIO(specific_serialized_cat),
                             format='turtle')
-        cat = Category(graph=cat_rdf_graph)
-        if cat.cat_id not in deleted_cat_list:
-            cat_list.append({"cat_label": cat.label,
-                             "cat_description": cat.description,
-                             "cat_id": cat.cat_id,
-                             "cat_properties": cat.properties})
+
+        current_cat = Category(graph=cat_rdf_graph)
+        current_cat_id = current_cat.cat_id
+        current_cat_properties = current_cat.properties
+
+        cat_form = CategoryForm(request.form, obj=current_cat)
+        cat_form.label.data = current_cat.label
+        cat_form.description.data = current_cat.description
+    else:
+        cat_form = CategoryForm(request.form)
 
-    for modified_cat_name in modified_cat_dict.keys():
-        if modified_cat_name not in [cat["cat_id"] for cat in cat_list]:
+    if request.method == "GET":
+        """
+            GET Method means we will display the editor
+        """
+        deleted_cat_dict = {}
+        # deleted categories we won't append to cat_list
+        modified_cat_dict = {}
+        # modified categories to append to cat_list in case label changed
+        serialized_cat_list = []
+        # existing categories we get from CategoryAPI
+        cat_changes = {}
+        # changes list we get from CategoryChangesAPI
+
+        cat_list = []
+        # list of category that will be used in property editor, list of dict
+        # {"cat_id": cat.cat_id,
+        #  "cat_label": cat.label,
+        #  "cat_description": cat.description,
+        #  "cat_properties": cat.properties}
+
+
+        if session.get("user_logged", None) is not None:
+            serialized_cat_list = cat_api_instance.get(repository)
+            cat_changes = cat_changes_api_instance.get(repository)[0]
+            deleted_cat_dict = cat_changes["deleted_categories"]
+            modified_cat_dict = cat_changes["modified_categories"]
+            logger.debug(changes_response)
+
+        for modified_cat_name in modified_cat_dict.keys():
             modified_cat_rdf_graph = Graph()
             modified_cat_rdf_graph.parse(
                 source=StringIO(modified_cat_dict[modified_cat_name]),
@@ -343,107 +404,58 @@
                              "cat_id": modified_cat.cat_id,
                              "cat_properties": modified_cat.properties})
 
-    if cat_id is not None:
-        specific_serialized_cat = ""
-        changes_response = cat_changes_api_instance.get(
-            repository=repository,
-            modified_cat_id=cat_id
-        )
-        # that means the category was modified or deleted
-        if changes_response != 404:
-            logger.debug(changes_response)
-            if changes_response[0]["type"] is not "deleted":
-                specific_serialized_cat = changes_response[0] \
-                                                          ["category"] \
-                                                          [cat_id]
-        else:
-            specific_serialized_cat = cat_api_instance.get(
-                repository=repository,
-                cat_id=cat_id
-            )
-        logger.debug(specific_serialized_cat)
-        cat_rdf_graph = Graph()
-        cat_rdf_graph.parse(source=StringIO(specific_serialized_cat),
-                            format='turtle')
-        cat = Category(graph=cat_rdf_graph)
+        for serialized_cat in serialized_cat_list:
+            cat_rdf_graph = Graph()
+            cat_rdf_graph.parse(source=StringIO(serialized_cat),
+                                format='turtle')
+            cat = Category(graph=cat_rdf_graph)
+            if cat.cat_id not in deleted_cat_dict.keys() and \
+               cat.cat_id not in modified_cat_dict.keys():
+                cat_list.append({"cat_label": cat.label,
+                                 "cat_description": cat.description,
+                                 "cat_id": cat.cat_id,
+                                 "cat_properties": cat.properties})
 
-        setattr(NewCategoryMinimalForm,
-                'label',
-                StringField("Nom de la categorie",
-                            validators=[DataRequired()],
-                            default=cat.label))
-        setattr(NewCategoryMinimalForm,
-                'description',
-                TextAreaField("Description de la categorie",
-                              validators=[DataRequired()],
-                              default=cat.description))
-        logger.debug("CatForm fields preset to "
-                     + cat.label + " and "
-                     + cat.description)
-
-        cat_form = NewCategoryMinimalForm(request.form)
-
-        # GET + cat_id = Edit cat form
-        if request.method == 'GET':
-            return render_template('cateditor.html',
-                                   cat_id=cat.cat_id,
-                                   cat_properties=cat.properties,
-                                   form=cat_form,
-                                   cat_list=cat_list,
-                                   deleted_cat_list=deleted_cat_list,
-                                   current_repository=repository)
+        deleted_cat_list = list(deleted_cat_dict.keys())
 
-        # PUT + cat_id = Submit edited cat, only if cat is not already
-        # in deleted categories
-        if cat_form.validate_on_submit() and cat.cat_id not in \
-                cat_changes[0]["deleted_categories"].keys():
-            if (session.get("user_logged", None) is not None and
-                    session.get("user_can_edit", False) is not False):
-                cat_api_instance.put(repository=repository, cat_id=cat_id)
-            return redirect(url_for('cat_recap', repository=repository))
-        else:
-            # if form doesn't validate we don't want to delete whatever changes
-            # the user did
-            return render_template('cateditor.html',
-                                   cat_id=cat_id,
-                                   cat_properties=cat.properties,
-                                   form=cat_form,
-                                   cat_list=cat_list,
-                                   deleted_cat_list=deleted_cat_list,
-                                   current_repository=repository)
+        return render_template('cateditor.html',
+                               cat_id=current_cat_id,
+                               cat_properties=current_cat_properties,
+                               form=cat_form,
+                               cat_list=cat_list,
+                               deleted_cat_list=deleted_cat_list,
+                               current_repository=repository)
+    elif request.method == "POST":
+        """
+            POST Method means we will compute the form data, call the relevant
+            "POST" and "PUT" method on CategoryAPI, and return to a display
+            page (catrecap for now, ideally the one from whence we came)
+        """
+        if (session.get("user_logged", None) is not None and
+                session.get("user_can_edit", False) is not False):
+            if cat_form.validate_on_submit():
+                logger.debug(cat_form.label.data)
+                logger.debug(cat_form.description.data)
+                logger.debug(cat_form.properties.data)
+                if cat_id is not None:
+                    cat_api_instance.put(repository=repository, cat_id=cat_id)
+                else:
+                    cat_api_instance.post(repository=repository)
+                return redirect(url_for('cat_recap', repository=repository))
+            else:
+                # if form doesn't validate we don't want to delete whatever changes
+                # the user did
+                return render_template('cateditor.html',
+                                       cat_id=cat_id,
+                                       cat_properties=cat.properties,
+                                       form=cat_form,
+                                       cat_list=cat_list,
+                                       deleted_cat_list=deleted_cat_list,
+                                       current_repository=repository)
 
-    else:
-        setattr(NewCategoryMinimalForm,
-                'label',
-                StringField("Nom de la categorie",
-                            validators=[DataRequired()]))
-        setattr(NewCategoryMinimalForm,
-                'description',
-                TextAreaField("Description de la categorie",
-                              validators=[DataRequired()]))
-
-        cat_form = NewCategoryMinimalForm(request.form)
-
-        # GET = Create cat form
-        if request.method == 'GET':
-            return render_template('cateditor.html',
-                                   form=cat_form,
-                                   cat_list=cat_list,
-                                   deleted_cat_list=deleted_cat_list,
-                                   current_repository=repository)
-
-        # POST seul = Submit created cat
-        if cat_form.validate_on_submit():
-            if (session.get("user_logged", None) is not None and
-                    session.get("user_can_edit", False) is not False):
-                cat_api_instance.post(repository=repository)
-            return redirect(url_for('cat_recap', repository=repository))
         else:
-            return render_template('cateditor.html',
-                                   form=cat_form,
-                                   cat_list=cat_list,
-                                   deleted_cat_list=deleted_cat_list,
-                                   current_repository=repository)
+        # User wasn't logged or couldn't edit but somehow submitted a POST
+            return redirect(url_for('cat_index'))
 
 
 @app.route('/catedit-github-login')
@@ -502,7 +514,7 @@
         for repo in repo_list:
             logger.debug(repo["name"])
         session["user_can_edit"] = True
-        if not any(repo["name"] == app.config["REPOSITORY_NAME"]
+        if not any(repo["name"] not in app.config["REPOSITORY_LIST"]
                    for repo in repo_list):
             session["user_can_edit"] = False
         logger.debug(session["user_can_edit"])