Added support for custom properties per repository + added doc in the readme for this (config.py PROPERTY_LIST entry has changed a bit)
authordurandn
Tue, 07 Apr 2015 20:03:04 +0200
changeset 62 746d486f7c42
parent 61 018094c40453
child 63 9494a2d66aea
Added support for custom properties per repository + added doc in the readme for this (config.py PROPERTY_LIST entry has changed a bit)
Readme.md
src/catedit/config.py.tmpl
src/catedit/models.py
src/catedit/resources.py
src/catedit/settings.py
src/catedit/templates/categories/editor.html
src/catedit/templates/macros.html
src/catedit/templates/social/changeset.html
src/catedit/utils.py
src/catedit/views/categories.py
src/catedit/views/home.py
src/catedit/views/social.py
--- a/Readme.md	Tue Mar 31 15:32:56 2015 +0200
+++ b/Readme.md	Tue Apr 07 20:03:04 2015 +0200
@@ -48,23 +48,32 @@
 
 ## Additional/Advanced informations ##
 
-** Changing the property list : ** If you want to change the property list available to users editing/creating categories, you have to edit the following entry in config.py
+** Changing the property list : ** If you want to change the default property list available to users editing/creating categories, you have to edit the following entry in config.py
 
 * PROPERTY_LIST : My list of properties ...
 
 The list of property has a fixed structure. The property list is a dict of python dicts, each following the fixed structure:
 
-    "propertyKey" : {
+    "propertyURI" : {
         "descriptive_label_fr" : "mylabelfr",
         "descriptive_label_en" : "mylabelen",
         "object_type": "my-object-type",
         "rdflib_class": some-RDFLib-concept,
-        "object_rdflib_class": some-RDFLib-class,
+        "usable_in_editor: boolean so the property appears or not in the editor
     }
 
+* "propertyURI" is the complete URI of the property, for a rdflib property that will be the string you get when calling NAMESPACE.property.toPython()
 * "object_type" : "my-object-type",  -> either "literal", "uriref-category" or "uriref-link" at the moment
-* "rdflib_class" : some-RDFLib-concept, -> a rdflib class of some sort with its namespace, examples: SKOS.related or RDF.Type representing the predicate
-* "object_rdflib_class" : some-RDFLib-class:  -> a rdflib class representing the object, either Literal or URIRef
+* "usable_in_editor": if true, the property will appear in the editor and users will be able to apply it to categories, if false they won't be able to.
+* "rdflib_class" : some-RDFLib-concept, -> a rdflib namespaced property with its namespace, examples: SKOS.related or RDF.Type representing the predicate
+
+** Custom property list **
+
+To setup a custom set of property you need to add a properties/properties.json file in the repository that has 2 values:
+* namespace_title is the string that defines the namespace of your custom properties for this repository (not really used right now but will be useful in the future)
+* property_list is a dict that follows the exact same format as the config.py property list, of course in json format, so the propertyURI that is used as a key must be written explicitely
+
+If you make the property list evolve, don't forget to keep the old properties you don't want your users to use anymore to ensure backward compatibility. You just need to set the "usable_in_editor" key to false in the property you don't want your users to have access to. Note this won't affect existing categories with this property, but only ensure that they will be readable. Then it's up to the users to "clean up" if a deprecated property is still used.
 
 ## Testing Protocol for CatEdit (development) ##
 
--- a/src/catedit/config.py.tmpl	Tue Mar 31 15:32:56 2015 +0200
+++ b/src/catedit/config.py.tmpl	Tue Apr 07 20:03:04 2015 +0200
@@ -72,34 +72,34 @@
         "GITHUB_CLIENT_ID" : "github-client-placeholder",
         "GITHUB_CLIENT_SECRET" : "github-secret-placeholder",
     }
-
+	
     PROPERTY_LIST = {
-        "subClassOf": {
+        RDFS.subClassOf.toPython(): {
             "descriptive_label_fr": "Sous-classe de",
             "descriptive_label_en": "Subclass of",
             "object_type": "uriref-category",
+            "usable_in_editor": True,
             "rdflib_class": RDFS.subClassOf,
-            "object_rdflib_class": URIRef,
         },
-        "comment": {
+        RDFS.comment.toPython(): {
             "descriptive_label_fr": "Commentaire",
             "descriptive_label_en": "Comment",
             "object_type": "literal",
+            "usable_in_editor": True,
             "rdflib_class": RDFS.comment,
-            "object_rdflib_class": Literal,
         },
-        "resource": {
+        RDFS.Resource.toPython(): {
             "descriptive_label_fr": "Ressource",
             "descriptive_label_en": "Resource",
             "object_type": "uriref-link",
+            "usable_in_editor": True,
             "rdflib_class": RDFS.Resource,
-            "object_rdflib_class": URIRef,
         },
-        "related": {
+        SKOS.related.toPython(): {
             "descriptive_label_fr": "En relation avec",
             "descriptive_label_en": "Related to",
             "object_type": "uriref-category",
+            "usable_in_editor": True,
             "rdflib_class": SKOS.related,
-            "object_rdflib_class": URIRef,
         }
     }
--- a/src/catedit/models.py	Tue Mar 31 15:32:56 2015 +0200
+++ b/src/catedit/models.py	Tue Apr 07 20:03:04 2015 +0200
@@ -5,13 +5,15 @@
 * helper classes to manage category life cycle
 """
 
+from catedit import app
+from io import StringIO
+import logging
+from uuid import uuid4
+
 from rdflib import Graph, RDF, RDFS, Literal, URIRef
 from rdflib.compare import to_isomorphic, graph_diff
-from uuid import uuid4
-from io import StringIO
 from slugify import slugify
-import logging
-from catedit import app
+
 
 logger = logging.getLogger(__name__)
 
@@ -38,8 +40,7 @@
             # cat_id = .hex - Alternate method of generating ids
             cat_id = slugify(label)+"_"+str(uuid4())[:8]
             self.cat_graph = Graph()
-            self.this_category = URIRef(app.config["CATEGORY_NAMESPACE"] +
-                                        cat_id)
+            self.this_category = app.config["CATEGORY_NAMESPACE"][cat_id]
             self.cat_graph.add((self.this_category, RDF.ID, Literal(cat_id)))
 
             if label:
@@ -53,27 +54,12 @@
 
             if other_properties:
                 for (predicate, obj) in other_properties:
-                    rdf_obj = ""
-                    if (app.config["PROPERTY_LIST"]
-                                  [predicate]
-                                  ["object_type"] == "uriref-category"):
-                        rdf_obj = app.config["CATEGORY_NAMESPACE"] + obj
-                    else:
-                        rdf_obj = obj
-                    self.cat_graph.add((self.this_category,
-                                       app.config["PROPERTY_LIST"]
-                                                 [predicate]
-                                                 ["rdflib_class"],
-                                       app.config["PROPERTY_LIST"]
-                                                 [predicate]
-                                                 ["object_rdflib_class"]
-                                       (rdf_obj)))
+                    self.cat_graph.add((self.this_category, predicate, obj))
 
         else:
             self.cat_graph = graph
-            # Warning: not foolproof
-            self.this_category = next(self.cat_graph
-                                          .subjects(predicate=RDF.ID))
+            # Warning: not foolproof, if loading a Graph with multiple IDs (should not happen)
+            self.this_category = next(self.cat_graph.subjects(predicate=RDF.ID))
 
     @property
     def label(self):
@@ -110,16 +96,25 @@
         """
             Returns category property list
         """
-        property_list = []
-        for key in app.config["PROPERTY_LIST"]:
-            for obj in self.cat_graph \
-                           .objects(subject=self.this_category,
-                                    predicate=app.config["PROPERTY_LIST"]
-                                                        [key]
-                                                        ["rdflib_class"]):
-                property_list.append((key, obj.toPython()))
-        return property_list
-
+        print(str(
+            [
+                predicate_object_tuple for predicate_object_tuple in self.cat_graph.predicate_objects() 
+                if (
+                    predicate_object_tuple[0]!=RDF.ID and 
+                    predicate_object_tuple[0]!=RDFS.label and
+                    predicate_object_tuple[0]!=RDF.Description
+                )
+            ]
+        ))
+        return [
+            predicate_object_tuple for predicate_object_tuple in self.cat_graph.predicate_objects() 
+            if (
+                predicate_object_tuple[0]!=RDF.ID and 
+                predicate_object_tuple[0]!=RDFS.label and
+                predicate_object_tuple[0]!=RDF.Description
+            )
+        ]
+        
     def edit_category(self, new_label="",
                       new_description="",
                       new_other_properties=None):
@@ -159,28 +154,15 @@
 
         if new_other_properties is not None and \
            (new_other_properties != self.properties):
-            for key in app.config["PROPERTY_LIST"]:
-                self.cat_graph.remove((self.this_category,
-                                       app.config["PROPERTY_LIST"]
-                                                 [key]
-                                                 ["rdflib_class"],
-                                       None))
+            for (predicate, object) in self.cat_graph.predicate_objects():
+                if predicate not in [RDF.ID, RDF.Description, RDFS.label]:
+                    self.cat_graph.remove(
+                        (self.this_category, predicate, None)
+                    )
             for (predicate, obj) in new_other_properties:
-                rdf_obj = ""
-                if (app.config["PROPERTY_LIST"]
-                              [predicate]
-                              ["object_type"] == "uriref-category"):
-                    rdf_obj = app.config["CATEGORY_NAMESPACE"] + obj
-                else:
-                    rdf_obj = obj
-                self.cat_graph.add((self.this_category,
-                                   app.config["PROPERTY_LIST"]
-                                             [predicate]
-                                             ["rdflib_class"],
-                                   app.config["PROPERTY_LIST"]
-                                             [predicate]
-                                             ["object_rdflib_class"]
-                                   (rdf_obj)))
+                self.cat_graph.add(
+                    (self.this_category, predicate, obj)
+                )
 
 
 class CategoryManager(object):
--- a/src/catedit/resources.py	Tue Mar 31 15:32:56 2015 +0200
+++ b/src/catedit/resources.py	Tue Apr 07 20:03:04 2015 +0200
@@ -6,14 +6,17 @@
 """
 
 
-from rdflib import Graph
-from flask.ext.restful import Resource, reqparse
-from flask import session
 from catedit import app, cache, github
 from catedit.models import Category, CategoryManager
 import catedit.persistence
 from io import StringIO
 
+from flask import session
+from rdflib import Graph, URIRef, Literal
+
+from flask.ext.restful import Resource, reqparse
+
+
 logger = app.logger
 
 cat_parser = reqparse.RequestParser()
@@ -135,10 +138,25 @@
                 cat = Category(graph=cat_graph)
             else:
                 cat = cat_manager_instance.load_category(cat_id)
-
+            
+            new_property_list=[]
+            for (predicate, obj) in cat_data["properties"]:
+                if session["properties"][repository][predicate]["object_type"] == "uriref-category":
+                    new_property_list.append(
+                        (URIRef(session["properties"][repository][predicate]["rdflib_class"]), app.config["CATEGORY_NAMESPACE"][obj])
+                    )
+                elif session["properties"][repository][predicate]["object_type"] == "uriref-link":
+                    new_property_list.append(
+                        (URIRef(session["properties"][repository][predicate]["rdflib_class"]), URIRef(obj))
+                    )
+                else:
+                    new_property_list.append(
+                        (URIRef(session["properties"][repository][predicate]["rdflib_class"]), Literal(obj))
+                    )
+            
             cat.edit_category(new_description=cat_data["description"],
                               new_label=cat_data["label"],
-                              new_other_properties=cat_data["properties"])
+                              new_other_properties=new_property_list)
 
             session["modified_categories"][repository][cat.cat_id] = str(
                 cat.cat_graph.serialize(format="turtle"), "utf-8"
@@ -168,12 +186,29 @@
             }
             List of predicate is available in config.py, key PROPERTY_LIST
         """
+        property_list = []
+        for (predicate, obj) in cat_data["properties"]:
+            if session["properties"][repository][predicate]["object_type"] == "uriref-category":
+                property_list.append(
+                    (URIRef(session["properties"][repository][predicate]["rdflib_class"]), app.config["CATEGORY_NAMESPACE"][obj])
+                )
+            elif session["properties"][repository][predicate]["object_type"] == "uriref-link":
+                property_list.append(
+                    (URIRef(session["properties"][repository][predicate]["rdflib_class"]), URIRef(obj))
+                )
+            else:
+                property_list.append(
+                    (URIRef(session["properties"][repository][predicate]["rdflib_class"]), Literal(obj))
+                )
+        
         cat = Category(
             label=cat_data["label"],
             description=cat_data["description"],
-            other_properties=cat_data["properties"]
+            other_properties=property_list
         )
-
+        
+        
+        
         if cat.cat_id not in session["modified_categories"][repository].keys():
             session["modified_categories"][repository][cat.cat_id] = str(
                 cat.cat_graph.serialize(format="turtle"), "utf-8"
@@ -249,21 +284,16 @@
                         format="turtle"
                     )
                     modified_cat = Category(graph=modified_cat_graph)
-                    if (modified_cat.cat_id !=
-                            app.config["CATEGORY_NAMESPACE"] + deleted_cat_id):
+                    if (modified_cat.cat_id != app.config["CATEGORY_NAMESPACE"][deleted_cat_id]):
                         new_property_list = []
                         for (predicate, obj) in modified_cat.properties:
                             if not (
-                                    app.config["PROPERTY_LIST"]
-                                    [predicate]
-                                    ["object_type"]
+                                    session["properties"]
+                                           [repository]
+                                           [predicate.toPython()]
+                                           ["object_type"]
                                     == "uriref-category"
-                                    and (
-                                        obj == (
-                                            app.config["CATEGORY_NAMESPACE"]
-                                            + deleted_cat_id
-                                        )
-                                    )
+                                    and (obj == app.config["CATEGORY_NAMESPACE"][deleted_cat_id])
                             ):
                                 new_property_list.append((predicate, obj))
 
@@ -292,15 +322,12 @@
                         new_property_list = []
                         for (predicate, obj) in cat.properties:
                             if not (
-                                    app.config["PROPERTY_LIST"]
-                                              [predicate]
-                                              ["object_type"]
+                                    session["properties"]
+                                           [repository]
+                                           [predicate.toPython()]
+                                           ["object_type"]
                                     == "uriref-category"
-                                    and (
-                                        obj ==
-                                        app.config["CATEGORY_NAMESPACE"]
-                                        + deleted_cat_id
-                                    )
+                                    and (obj == app.config["CATEGORY_NAMESPACE"][deleted_cat_id])
                             ):
                                 new_property_list.append((predicate, obj))
 
--- a/src/catedit/settings.py	Tue Mar 31 15:32:56 2015 +0200
+++ b/src/catedit/settings.py	Tue Apr 07 20:03:04 2015 +0200
@@ -2,6 +2,8 @@
 settings.py:
 Contains all settings that are needed but are not to be changed
 """
+from rdflib import Namespace
+
 
 class AppSettings(object):
 
@@ -11,5 +13,5 @@
 
     # RDF Namespace and prefixes - Must end with #
 
-    ONTOLOGY_NAMESPACE = "http://ld.iri-research.org/ontology/categorisation#"
-    CATEGORY_NAMESPACE = "http://ld.iri-research.org/ontology/categorisation/category#"
+    BASE_NAMESPACE = "http://ld.iri-research.org/ontology/categorisation"
+    CATEGORY_NAMESPACE = Namespace("http://ld.iri-research.org/ontology/categorisation/category#")
\ No newline at end of file
--- a/src/catedit/templates/categories/editor.html	Tue Mar 31 15:32:56 2015 +0200
+++ b/src/catedit/templates/categories/editor.html	Tue Apr 07 20:03:04 2015 +0200
@@ -63,8 +63,10 @@
         <option id="property_type_default" label="Liste des propriétés ..." selected="selected">
           Liste des propriétés ...
         </option>
-        {% for predicate in config["PROPERTY_LIST"] %}
-        <option value='{{ predicate }}' label="{{ config['PROPERTY_LIST'][predicate]['descriptive_label_fr'] }}" class="{{ config['PROPERTY_LIST'][predicate]['object_type'] }}">{{ config["PROPERTY_LIST"][predicate]["descriptive_label_fr"] }}</option>
+        {% for predicate in session["properties"][current_repository] %}
+          {% if session["properties"][current_repository][predicate]["usable_in_editor"] %}
+            <option value='{{ predicate }}' label="{{ session['properties'][current_repository][predicate]['descriptive_label_fr'] }}" class="{{ session['properties'][current_repository][predicate]['object_type'] }}">{{ session["properties"][current_repository][predicate]["descriptive_label_fr"] }}</option>
+          {% endif %}
         {% endfor %}
       </select>
       <input type="text" id="literal-field" class="hidden form-control">
@@ -89,14 +91,14 @@
             {% for property in form.properties %}
                 <tr id="properties-{{property_count}}">
                   <input id="properties-{{property_count}}-csrf_token" name="properties-{{property_count}}-csrf_token" value="{{ csrf_token() }}" type="hidden">
-                  {% if config["PROPERTY_LIST"][property.property_predicate.data]["object_type"]=="uriref-category" %}
+                  {% if session["properties"][current_repository][property.property_predicate.data]["object_type"]=="uriref-category" %}
                     {% for cat in cat_list %}
                       {% if property.property_object.data == cat.cat_id %}
                         {% if cat.cat_id not in deleted_cat_list %}
                           {{ property.property_predicate() }}
                           {{ property.property_object() }}
                           <td id="predicate_td{{ property_count }}">
-                            <strong>{{ config["PROPERTY_LIST"][property.property_predicate.data]["descriptive_label_fr"] }}</strong>
+                            <strong>{{ session["properties"][current_repository][property.property_predicate.data]["descriptive_label_fr"] }}</strong>
                           </td>
                           <td id="object_td{{property_count-1}}">
                             {{ cat.cat_label }}
@@ -111,10 +113,10 @@
                       {{ property.property_predicate() }}
                       {{ property.property_object() }}
                     <td id="predicate_td{{ property_count }}">
-                      <strong>{{ config["PROPERTY_LIST"][property.property_predicate.data]["descriptive_label_fr"] }}</strong>
+                      <strong>{{ session["properties"][current_repository][property.property_predicate.data]["descriptive_label_fr"] }}</strong>
                     </td>
                     <td id="object_td{{ property_count }}">
-                      {% if config["PROPERTY_LIST"][property.property_predicate.data]["object_type"]=="uriref-link" %}
+                      {% if session["properties"][current_repository][property.property_predicate.data]["object_type"]=="uriref-link" %}
                         <a href="{{ property.property_object.data }}">{{ property.property_object.data }}</a>
                       {% else %}
                         {{ property.property_object.data }}
--- a/src/catedit/templates/macros.html	Tue Mar 31 15:32:56 2015 +0200
+++ b/src/catedit/templates/macros.html	Tue Apr 07 20:03:04 2015 +0200
@@ -72,15 +72,15 @@
             {% if cat.cat_properties|length == 0 %} <dt></dt><dd>Aucune autre propriété</dd>
             {% else %}
               {% for (predicate, object) in cat.cat_properties %}
-                <dt>{{ config["PROPERTY_LIST"][predicate]["descriptive_label_fr"] }}</dt>
+                <dt>{{ session["properties"][current_repository][predicate.toPython()]["descriptive_label_fr"] }}</dt>
                 <dd>
-                  {% if config["PROPERTY_LIST"][predicate]["object_type"]=="uriref-category" %}
+                  {% if session["properties"][current_repository][predicate.toPython()]["object_type"]=="uriref-category" %}
                     {% for cat in cat_list %}
-                      {% if object == config["CATEGORY_NAMESPACE"]+cat.cat_id %}
+                      {% if object == config["CATEGORY_NAMESPACE"][cat.cat_id] %}
                         {{ cat.cat_label }}
                       {% endif %}
                     {% endfor %}
-                  {% elif config["PROPERTY_LIST"][predicate]["object_type"]=="uriref-link" %}
+                  {% elif session["properties"][current_repository][predicate.toPython()]["object_type"]=="uriref-link" %}
                     <a href="{{ object }}">{{ object }}</a>
                   {% else %}
                     {{ object }}
--- a/src/catedit/templates/social/changeset.html	Tue Mar 31 15:32:56 2015 +0200
+++ b/src/catedit/templates/social/changeset.html	Tue Apr 07 20:03:04 2015 +0200
@@ -203,15 +203,15 @@
                   <dt>Label</dt>
                   <dd>{{ change[1] }}</dd>
                 {% else %}
-                  <dt>{{ config["PROPERTY_LIST"][change[0]]["descriptive_label_fr"] }}</dt>
+                  <dt>{{ session["properties"][current_repository][change[0]]["descriptive_label_fr"] }}</dt>
                   <dd>
-                  {% if config["PROPERTY_LIST"][change[0]]["object_type"]=="uriref-category" %}
+                  {% if session["properties"][current_repository][change[0]]["object_type"]=="uriref-category" %}
                     {% for old_cat in old_cat_list %}
                       {% if change[1] == old_cat.cat_id %}
                         {{ old_cat.cat_label }}
                       {% endif %}
                     {% endfor %}
-                  {% elif config["PROPERTY_LIST"][change[0]]["object_type"]=="uriref-link" %}
+                  {% elif session["properties"][current_repository][change[0]]["object_type"]=="uriref-link" %}
                     <a href="{{ change[1] }}">{{ change[1] }}</a>
                   {% else %}
                     {{ change[1] }}
@@ -233,15 +233,15 @@
                   <dt>Label</dt>
                   <dd>{{ change[1] }}</dd>
                 {% else %}
-                  <dt>{{ config["PROPERTY_LIST"][change[0]]["descriptive_label_fr"] }}</dt>
+                  <dt>{{ session["properties"][current_repository][change[0]]["descriptive_label_fr"] }}</dt>
                   <dd>
-                  {% if config["PROPERTY_LIST"][change[0]]["object_type"]=="uriref-category" %}
+                  {% if session["properties"][current_repository][change[0]]["object_type"]=="uriref-category" %}
                     {% for new_cat in new_cat_list %}
                       {% if change[1] == new_cat.cat_id %}
                         {{ new_cat.cat_label }}
                       {% endif %}
                     {% endfor %}
-                  {% elif config["PROPERTY_LIST"][change[0]]["object_type"]=="uriref-link" %}
+                  {% elif session["properties"][current_repository][change[0]]["object_type"]=="uriref-link" %}
                     <a href="{{ change[1] }}">{{ change[1] }}</a>
                   {% else %}
                     {{ change[1] }}
--- a/src/catedit/utils.py	Tue Mar 31 15:32:56 2015 +0200
+++ b/src/catedit/utils.py	Tue Apr 07 20:03:04 2015 +0200
@@ -3,11 +3,16 @@
     Module that lists utility functions used through the app
 """
 from catedit import app
-from rdflib import RDF, RDFS
+import logging
+
+from flask import session
+from rdflib import RDF, RDFS, URIRef
 from rdflib.compare import to_isomorphic, graph_diff
 
 
-def compare_categories(first_category, second_category, with_details=True):
+logger = logging.getLogger(__name__)
+
+def compare_categories(first_category, second_category, repository, with_details=True):
     """
         Compares 2 categories and generate a dict with 3 lists of
         differences:
@@ -51,6 +56,9 @@
         in_first = []
         in_both = []
         in_second = []
+        logger.debug(rdf_in_both)
+        logger.debug(rdf_only_in_first)
+        logger.debug(rdf_only_in_second)
         for (final_list, diff_list) in [
                 (in_both, rdf_in_both),
                 (in_first, rdf_only_in_first),
@@ -62,15 +70,17 @@
                 elif triple[1] == RDF.Description:
                     final_list.append(("description", triple[2].toPython()))
                 else:
-                    for predicate in app.config["PROPERTY_LIST"].keys():
+                    for predicate in session["properties"][repository].keys():
                         if triple[1] == \
-                        app.config["PROPERTY_LIST"][predicate]["rdflib_class"]:
-                            if (app.config["PROPERTY_LIST"]
-                                          [predicate]
-                                          ["object_type"] == "uriref-link"
-                            or app.config["PROPERTY_LIST"]
-                                         [predicate]
-                                         ["object_type"] == "literal"):
+                        URIRef(session["properties"][repository][predicate]["rdflib_class"]):
+                            if (session["properties"]
+                                       [repository]
+                                       [predicate]
+                                       ["object_type"] == "uriref-link"
+                            or session["properties"]
+                                      [repository]
+                                      [predicate]
+                                      ["object_type"] == "literal"):
                                 final_list.append(
                                     (
                                         predicate,
@@ -91,7 +101,7 @@
 
 
 
-def make_differences_list(first_category_list, second_category_list):
+def make_differences_list(first_category_list, second_category_list, repository):
     """
         Compares 2 category lists and generates a dict that lists addition,
         modification and deletions from first_category_list to
@@ -116,6 +126,7 @@
                     if not(compare_categories(
                             first_list_category,
                             second_list_category,
+                            repository,
                             with_details=False
                     )["same_content"]):
                         modified_categories.append(
--- a/src/catedit/views/categories.py	Tue Mar 31 15:32:56 2015 +0200
+++ b/src/catedit/views/categories.py	Tue Apr 07 20:03:04 2015 +0200
@@ -5,17 +5,19 @@
 
 from catedit import app
 from catedit.models import Category
+from catedit.resources import CategoryAPI, CategoryChangesAPI
 from catedit.views.utils import check_user_status_and_repo_access, \
                                 get_current_category_list, get_commits, \
                                 get_issues
-from flask import render_template, request, redirect, url_for, abort, Blueprint
+from io import StringIO
+
+from flask import render_template, request, redirect, url_for, abort, Blueprint, session
 from flask_wtf import Form
-from catedit.resources import CategoryAPI, CategoryChangesAPI
+from rdflib import Graph
 from wtforms import StringField, TextAreaField, FormField, \
                     FieldList, HiddenField
 from wtforms.validators import DataRequired, Optional, AnyOf
-from rdflib import Graph
-from io import StringIO
+
 
 module = Blueprint('categories', __name__)
 logger = app.logger
@@ -87,6 +89,7 @@
             5,
             1
         )[0]
+        logger.debug(cat_list)
         return render_template(
             'categories/workshop.html',
             cat_list=cat_list,
@@ -216,9 +219,7 @@
         Form of a given property, each one is a couple of hidden fields that
         can be Javascript-generated in the template
     """
-    property_predicate = HiddenField(
-        validators=[AnyOf(values=app.config["PROPERTY_LIST"].keys())]
-    )
+    property_predicate = HiddenField()
     property_object = HiddenField(
         validators=[DataRequired()]
     )
@@ -353,14 +354,15 @@
             cat_form.label.data = current_cat.label
             cat_form.description.data = current_cat.description
             for (cat_predicate, cat_object) in current_cat_properties:
-                if app.config["PROPERTY_LIST"] \
-                             [cat_predicate] \
-                             ["object_type"] == "uriref-category":
+                if session["properties"] \
+                          [repository] \
+                          [cat_predicate.toPython()] \
+                          ["object_type"] == "uriref-category":
                     namespace, object_id = cat_object.split("#", 1)
                 else:
                     object_id = cat_object
                 cat_form.properties.append_entry({
-                    "property_predicate": cat_predicate,
+                    "property_predicate": cat_predicate.toPython(),
                     "property_object": object_id
                 })
         # list of category that will be used in property editor, list of dict
--- a/src/catedit/views/home.py	Tue Mar 31 15:32:56 2015 +0200
+++ b/src/catedit/views/home.py	Tue Apr 07 20:03:04 2015 +0200
@@ -2,11 +2,12 @@
 home.py:
 The views functions that handle authentication and index pages
 """
-
+import json
 from catedit import app, github, log_api_rate
 from flask import render_template, redirect, url_for, \
                   session, Blueprint
 from flask.ext.github import GitHubError
+from base64 import b64decode
 
 module = Blueprint('home', __name__)
 logger = app.logger
@@ -49,6 +50,20 @@
     logger.debug(session["user_code"])
     session["user_logged"] = True
     session["user_login"] = "auth-error"
+    
+    session["properties"] = {
+        repo: {} for repo
+        in app.config["PERSISTENCE_CONFIG"]["REPOSITORY_LIST"]
+    }
+    session["modified_categories"] = {
+        repo: {} for
+        repo in app.config["PERSISTENCE_CONFIG"]["REPOSITORY_LIST"]
+    }
+    session["deleted_categories"] = {
+        repo: {} for repo
+        in app.config["PERSISTENCE_CONFIG"]["REPOSITORY_LIST"]
+    }
+    
     try:
         session["user_login"] = github.get(
             "user",
@@ -63,13 +78,7 @@
         repo_list = []
         repo_list = github.get("user/repos")
 
-        for repo in repo_list:
-            logger.debug(repo["name"])
         user_repos_name = [repo["name"] for repo in repo_list]
-        logger.debug(
-            str(user_repos_name) + " "
-            + str(app.config["PERSISTENCE_CONFIG"]["REPOSITORY_LIST"])
-        )
         session["user_repositories"] = list(
             set(user_repos_name).intersection(
                 app.config["PERSISTENCE_CONFIG"]["REPOSITORY_LIST"]
@@ -77,24 +86,29 @@
         )
         session["user_can_edit"] = {}
         for repo in session["user_repositories"]:
-            if repo in app.config["PERSISTENCE_CONFIG"]["REPOSITORY_LIST"]:
-                session["user_can_edit"][repo] = True
-        logger.debug(session["user_can_edit"])
+            try:
+                json_file=github.get(
+                    "repos/"
+                    + app.config["PERSISTENCE_CONFIG"]["REPOSITORY_OWNER"] + "/"
+                    + repo + "/contents/properties/properties.json",
+                    hooks=dict(response=log_api_rate)
+                )
+                logger.debug("repo: "+repo+" - properties: "+str(json.loads(str(b64decode(json_file["content"]), "utf-8"))))
+                session["properties"][repo] = json.loads(str(b64decode(json_file["content"]), "utf-8"))["property_list"]
+            except GitHubError as ghe:
+                logger.debug(
+                    "GitHub Error trying to get the property list. We'll assume " +
+                    "there is none and use default list as defined in config.py"
+                )
+                session["properties"][repo] = app.config["PROPERTY_LIST"]
+            session["user_can_edit"][repo] = True
+        logger.debug("User can edit: "+str(session["user_can_edit"]))
     except GitHubError as ghe:
         logger.error(
             "GitHubError trying to get the list of repository for user "
             + session["user_login"]
         )
         logger.error(ghe.response.text)
-    
-    session["modified_categories"] = {
-        repo: {} for
-        repo in app.config["PERSISTENCE_CONFIG"]["REPOSITORY_LIST"]
-    }
-    session["deleted_categories"] = {
-        repo: {} for repo
-        in app.config["PERSISTENCE_CONFIG"]["REPOSITORY_LIST"]
-    }
     return redirect(url_for('home.index'))
 
 
@@ -119,4 +133,8 @@
         repo: {} for repo
         in app.config["PERSISTENCE_CONFIG"]["REPOSITORY_LIST"]
     }
+    session["properties"] = {
+        repo: {} for repo
+        in app.config["PERSISTENCE_CONFIG"]["REPOSITORY_LIST"]
+    }
     return redirect(url_for('home.index'))
--- a/src/catedit/views/social.py	Tue Mar 31 15:32:56 2015 +0200
+++ b/src/catedit/views/social.py	Tue Apr 07 20:03:04 2015 +0200
@@ -4,16 +4,18 @@
 """
 
 from catedit import app
+from catedit.utils import make_differences_list, compare_categories
 from catedit.views.utils import check_user_status_and_repo_access, \
                                 get_comments, post_comment, get_commits, \
                                 get_issues, get_category_list_for_commit
-from catedit.utils import make_differences_list, compare_categories
+
 from flask import render_template, request, redirect, url_for, \
                   abort, Blueprint, session
 from flask_wtf import Form
 from wtforms import TextAreaField, StringField
 from wtforms.validators import DataRequired
 
+
 module = Blueprint('social', __name__)
 logger = app.logger
 
@@ -164,6 +166,7 @@
         for list_type, diff_list in make_differences_list(
             old_category_list,
             new_category_list,
+            repository
         ).items()
     }
 
@@ -189,7 +192,7 @@
                 for category in new_category_list
                 if category.cat_id == details_cat_id
             )
-            changes_details = compare_categories(old_category, new_category)
+            changes_details = compare_categories(old_category, new_category, repository)
             changes_details["cat_id"] = details_cat_id
 
     old_category_list_template = []