Added support for multiple repositories + Started work on template inheritance (only created empty base template so far)
authorNicolas DURAND <nicolas.durand@iri.centrepompidou.fr>
Sat, 03 Jan 2015 00:15:51 +0100
changeset 21 b1b002c5ff60
parent 20 d47f8f8b3faf
child 22 0ba28595fd4d
Added support for multiple repositories + Started work on template inheritance (only created empty base template so far)
src/catedit/models.py
src/catedit/persistence.py
src/catedit/resources.py
src/catedit/static/css/style.css
src/catedit/templates/catbase.html
src/catedit/templates/cateditor.html
src/catedit/templates/catindex.html
src/catedit/templates/catmodifs.html
src/catedit/templates/catrecap.html
src/catedit/views.py
--- a/src/catedit/models.py	Fri Jan 02 16:46:56 2015 +0100
+++ b/src/catedit/models.py	Sat Jan 03 00:15:51 2015 +0100
@@ -177,7 +177,7 @@
         deleted categories and save the changes using the persistence method
         * delete_category will delete a single category from its id
     """
-    def __init__(self, persistence_method):
+    def __init__(self, persistence_method, repository=""):
         """
             persistence_method is a class that must have 4 methods:
 
--- a/src/catedit/persistence.py	Fri Jan 02 16:46:56 2015 +0100
+++ b/src/catedit/persistence.py	Sat Jan 03 00:15:51 2015 +0100
@@ -143,6 +143,9 @@
         * message : when saving or deleting, commit message to be saved
         to Github
     """
+    def __init__(self, **kwargs):
+        self.repository = kwargs.get("repository", "")
+
     @property
     def session_compliant(self):
         """
@@ -194,28 +197,60 @@
         modification_list = kwargs["modification_list"]
 
         # point 1
-        ref_master = github.get("repos/"
-                                + app.config["REPOSITORY_OWNER"] + "/"
-                                + app.config["REPOSITORY_NAME"]
-                                + "/git/refs/heads/master")
-        logger.debug(str(ref_master))
+        try:
+            ref_master = github.get(
+                "repos/"
+                + app.config["REPOSITORY_OWNER"] + "/"
+                + self.repository
+                + "/git/refs/heads/master"
+            )
+            logger.debug(str(ref_master))
+        except GitHubError as ghe:
+            logger.debug("GitHubError trying to get the reference \
+                         to the master branch")
+            logger.debug(
+                "Endpoint: "
+                + "repos/"
+                + app.config["REPOSITORY_OWNER"] + "/"
+                + self.repository
+                + "/git/refs/heads/master"
+            )
+            logger.debug(ghe.response.text)
+        logger.debug(str(github.get("rate_limit")["resources"]))
 
         # point 2
-        last_commit_master = github.get("repos/"
-                                        + app.config["REPOSITORY_OWNER"] + "/"
-                                        + app.config["REPOSITORY_NAME"]
-                                        + "/git/commits/"
-                                        + ref_master["object"]["sha"])
-        logger.debug(str(last_commit_master))
+        try:
+            last_commit_master = github.get(
+                "repos/"
+                + app.config["REPOSITORY_OWNER"] + "/"
+                + self.repository
+                + "/git/commits/"
+                + ref_master["object"]["sha"]
+            )
+            logger.debug(str(last_commit_master))
+        except GitHubError as ghe:
+            logger.debug("GitHubError trying to get the commit associated \
+                         to the latest reference to the master branch")
+            logger.debug(ghe.response.text)
+        logger.debug(str(github.get("rate_limit")["resources"]))
 
         # Point 3
-        last_commit_tree = github.get("repos/"
-                                      + app.config["REPOSITORY_OWNER"] + "/"
-                                      + app.config["REPOSITORY_NAME"]
-                                      + "/git/trees/"
-                                      + last_commit_master["tree"]["sha"]
-                                      + "?recursive=1")
-        logger.debug(str(last_commit_tree))
+        try:
+            last_commit_tree = github.get(
+                "repos/"
+                + app.config["REPOSITORY_OWNER"] + "/"
+                + self.repository
+                + "/git/trees/"
+                + last_commit_master["tree"]["sha"]
+                + "?recursive=1"
+            )
+            logger.debug(str(last_commit_tree))
+        except GitHubError as ghe:
+            logger.debug("GitHubError trying to get the tree from the commit \
+                         associated to the latest reference to the master \
+                         branch")
+            logger.debug(ghe.response.text)
+        logger.debug(str(github.get("rate_limit")["resources"]))
 
         # Point 4
         new_tree_data = {"tree": []}
@@ -255,15 +290,24 @@
                                     "content": category["content"],
                                     "encoding": "utf-8"
                                 }
-                                new_blob = github.post(
-                                    "repos/"
-                                    + app.config["REPOSITORY_OWNER"] + "/"
-                                    + app.config["REPOSITORY_NAME"]
-                                    + "/git/blobs",
-                                    data=new_blob_data
-                                )
-                                blob_sha = new_blob["sha"]
-                                break
+                                try:
+                                    new_blob = github.post(
+                                        "repos/"
+                                        + app.config["REPOSITORY_OWNER"] + "/"
+                                        + self.repository
+                                        + "/git/blobs",
+                                        data=new_blob_data
+                                    )
+                                    blob_sha = new_blob["sha"]
+                                    break
+                                except GitHubError as ghe:
+                                    logger.debug(
+                                        "GitHubError trying to post a new \
+                                        blob with following data: "
+                                        + str(new_blob_data)
+                                    )
+                                    logger.debug(ghe.response.text)
+                                logger.debug(str(github.get("rate_limit")["resources"]))
 
                     # this means element is an untouched file so we just get
                     # its sha
@@ -287,11 +331,22 @@
                 # 4-1 for added files, creating a new blob
                 new_blob_data = {"content": category["content"],
                                  "encoding": "utf-8"}
-                new_blob = github.post("repos/"
-                                       + app.config["REPOSITORY_OWNER"] + "/"
-                                       + app.config["REPOSITORY_NAME"]
-                                       + "/git/blobs",
-                                       data=new_blob_data)
+                try:
+                    new_blob = github.post(
+                        "repos/"
+                        + app.config["REPOSITORY_OWNER"] + "/"
+                        + self.repository
+                        + "/git/blobs",
+                        data=new_blob_data
+                    )
+                except GitHubError as ghe:
+                    logger.debug(
+                        "GitHubError trying to post a new blob with following \
+                        data: "
+                        + str(new_blob_data)
+                    )
+                    logger.debug(ghe.response.text)
+                logger.debug(str(github.get("rate_limit")["resources"]))
                 new_tree_data["tree"].append({
                     "path": app.config["CATEGORIES_PATH"] + category["name"],
                     "mode": "100644",
@@ -301,33 +356,64 @@
         logger.debug(str(new_tree_data))
 
         # Finally, we post the new tree
-        new_tree_response = github.post("repos/"
-                                        + app.config["REPOSITORY_OWNER"]+"/"
-                                        + app.config["REPOSITORY_NAME"]
-                                        + "/git/trees",
-                                        data=new_tree_data)
+        try:
+            new_tree_response = github.post(
+                "repos/"
+                + app.config["REPOSITORY_OWNER"]+"/"
+                + self.repository
+                + "/git/trees",
+                data=new_tree_data
+            )
+        except GitHubError as ghe:
+            logger.debug(
+                "GitHubError trying to post a new tree with following data: "
+                + str(new_tree_data)
+            )
+            logger.debug(ghe.response.text)
 
         # Point 5
         new_commit_data = {"message": kwargs["message"],
                            "parents": [last_commit_master["sha"]],
                            "tree": new_tree_response["sha"]}
         logger.debug(str(new_commit_data))
-        new_commit = github.post("repos/"
-                                 + app.config["REPOSITORY_OWNER"]+"/"
-                                 + app.config["REPOSITORY_NAME"]
-                                 + "/git/commits",
-                                 data=new_commit_data)
-        logger.debug(str(new_commit))
+        try:
+            new_commit = github.post(
+                "repos/"
+                + app.config["REPOSITORY_OWNER"]+"/"
+                + self.repository
+                + "/git/commits",
+                data=new_commit_data
+            )
+            logger.debug(str(new_commit))
+        except GitHubError as ghe:
+            logger.debug(
+                "GitHubError trying to post a new commit with following data: "
+                + str(new_commit_data)
+            )
+            logger.debug(ghe.response.text)
+        logger.debug(str(github.get("rate_limit")["resources"]))
 
         # Point 6
         new_head_data = {"sha": new_commit["sha"], "force": "true"}
         logger.debug(str(new_head_data))
-        new_head = github.patch("repos/"
-                                + app.config["REPOSITORY_OWNER"] + "/"
-                                + app.config["REPOSITORY_NAME"]
-                                + "/git/refs/heads/master",
-                                data=json.dumps(new_head_data))
-        logger.debug(str(new_head))
+        try:
+            new_head = github.patch(
+                "repos/"
+                + app.config["REPOSITORY_OWNER"] + "/"
+                + self.repository
+                + "/git/refs/heads/master",
+                data=json.dumps(new_head_data)
+            )
+            logger.debug(str(new_head))
+        except GitHubError as ghe:
+            logger.debug(
+                "GitHubError trying to edit the head to the master branch \
+                with the following data: "
+                + str(new_head_data)
+            )
+            logger.debug(ghe.response.text)
+        logger.debug(str(github.get("rate_limit")["resources"]))
+
 
     def load(self, **kwargs):
         """
@@ -336,7 +422,7 @@
         try:
             filedict = github.get("repos/"
                                   + app.config["REPOSITORY_OWNER"]+"/"
-                                  + app.config["REPOSITORY_NAME"]
+                                  + self.repository
                                   + "/contents/"
                                   + app.config["CATEGORIES_PATH"]
                                   + kwargs["name"])
@@ -346,6 +432,7 @@
             logger.debug("Github sent an error, if 404, either you may not \
                          have access to the repository or it doesn't exist ")
             logger.debug(ghe.response.text)
+        logger.debug(str(github.get("rate_limit")["resources"]))
         return file_content
 
     def delete(self, **kwargs):
@@ -367,7 +454,7 @@
         try:
             files_in_repo = github.get("repos/"
                                        + app.config["REPOSITORY_OWNER"]+"/"
-                                       + app.config["REPOSITORY_NAME"]
+                                       + self.repository
                                        + "/contents/"
                                        + app.config["CATEGORIES_PATH"])
             filenames_list = [github_file["name"]
@@ -380,13 +467,14 @@
                          may not have access to the repository or it doesn't \
                          exist or there isn't any files in it")
             logger.debug(ghe.response.text)
+        logger.debug(str(github.get("rate_limit")["resources"]))
 
         file_content_list = []
         for filename in filenames_list:
             try:
                 filedict = github.get("repos/"
                                       + app.config["REPOSITORY_OWNER"]+"/"
-                                      + app.config["REPOSITORY_NAME"]
+                                      + self.repository
                                       + "/contents/"
                                       + app.config["CATEGORIES_PATH"]
                                       + filename)
@@ -395,5 +483,6 @@
             except GitHubError as ghe:
                 logger.debug("Github Error trying to get file: "+filename)
                 logger.debug(ghe.response.text)
+        logger.debug(str(github.get("rate_limit")["resources"]))
         # logger.debug(file_content_list)
         return file_content_list
--- a/src/catedit/resources.py	Fri Jan 02 16:46:56 2015 +0100
+++ b/src/catedit/resources.py	Sat Jan 03 00:15:51 2015 +0100
@@ -33,13 +33,16 @@
         when successful
     """
     @cache.memoize(timeout=3600)
-    def get(self, cat_id=None):
+    def get(self, repository, cat_id=None):
         """
             API to get the category of id cat_id, or if cat_id is None,
             get the list of category
         """
         cat_manager_instance = CategoryManager(
-            getattr(catedit.persistence, app.config["PERSISTENCE_METHOD"])()
+            getattr(
+                catedit.persistence,
+                app.config["PERSISTENCE_METHOD"]
+            )(repository=repository),
         )
         if cat_id is not None:
             cat = cat_manager_instance.load_category(cat_id)
@@ -52,25 +55,28 @@
             return response
 
     # update category cat_id
-    def put(self, cat_id=None):
+    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
         """
         cat_manager_instance = CategoryManager(
-            getattr(catedit.persistence, app.config["PERSISTENCE_METHOD"])()
+            getattr(
+                catedit.persistence,
+                app.config["PERSISTENCE_METHOD"]
+            )(repository=repository),
         )
         args = cat_parser.parse_args()
         if (cat_id is None):
             if (cat_manager_instance.persistence.session_compliant is True):
                 logger.debug("Submitting - deleted categories are:"
-                             + str(session.get("deleted_categories", []))
+                             + str(session.get("deleted_categories", {}).get(repository, []))
                              + " and modified categories are:"
-                             + str(session.get("modified_categories", [])))
+                             + str(session.get("modified_categories", {}).get(repository, [])))
                 cat_manager_instance.save_changes(
-                    deleted_cat_list = session.get("deleted_categories", []),
-                    modified_cat_list = session.get("modified_categories", []),
+                    deleted_cat_list = session.get("deleted_categories", {}).get(repository, []),
+                    modified_cat_list = session.get("modified_categories", {}).get(repository, []),
                     message=args["commit_message"]
                 )
         else:
@@ -98,8 +104,8 @@
 
             # is the edition occuring on an already modified category?
             if cat_id in [category["name"] for category
-                          in session.get("modified_categories", [])]:
-                for element in session.get("modified_categories", []):
+                          in session.get("modified_categories", {}).get(repository, [])]:
+                for element in session.get("modified_categories", {}).get(repository, []):
                     if element["name"] == cat_id:
                         cat_graph = Graph()
                         cat_graph.parse(
@@ -114,11 +120,11 @@
                               new_label=args["label"],
                               new_other_properties=new_property_list)
 
-            session["modified_categories"][:] = [
-                elt for elt in session.get("modified_categories", [])
+            session["modified_categories"][repository][:] = [
+                elt for elt in session.get("modified_categories", {}).get(repository, [])
                 if elt["name"] != cat.cat_id
             ]
-            session["modified_categories"].append(
+            session["modified_categories"][repository].append(
                 {"name": cat.cat_id,
                  "content": str(
                     cat.cat_graph.serialize(format="turtle"), "utf-8"
@@ -127,15 +133,15 @@
 
             # Now we must clean the deleted categories list in case the
             # modified category was deleted before being edited
-            for element in session.get("deleted_categories", []):
+            for element in session.get("deleted_categories", {}).get(repository, []):
                 if element["name"] == cat.cat_id:
-                    session["deleted_categories"].remove(element)
+                    session["deleted_categories"][repository].remove(element)
 
             logger.debug("put id: "+cat.cat_id)
         cache.clear()
         return 204
 
-    def post(self):
+    def post(self, repository):
         """
             API to create a new category
         """
@@ -161,11 +167,11 @@
                        description=args["description"],
                        other_properties=property_list)
 
-        session["modified_categories"][:] = [
-            elt for elt in session.get("modified_categories", [])
+        session["modified_categories"][repository][:] = [
+            elt for elt in session.get("modified_categories", {}).get(repository, [])
             if elt["name"] != cat.cat_id
         ]
-        session["modified_categories"].append(
+        session["modified_categories"][repository].append(
             {"name": cat.cat_id,
              "content": str(
                 cat.cat_graph.serialize(format="turtle"), "utf-8"
@@ -176,39 +182,39 @@
         cache.clear()
         return cat.cat_graph.serialize(format='turtle').decode("utf-8"), 201
 
-    def delete(self, deleted_cat_id):
+    def delete(self, repository, deleted_cat_id):
         """
             API to delete the category of id cat_id or restore it from the
             deletion list
         """
         if (deleted_cat_id in [
-            element["name"] for element in session.get("deleted_categories", [])
+            element["name"] for element in session.get("deleted_categories", {}).get(repository, [])
         ]):
-            session["deleted_categories"].remove({"name": deleted_cat_id})
+            session["deleted_categories"][repository].remove({"name": deleted_cat_id})
             # warning, not safe if 2 files share the same name (or category id)
             # but that shouldn't happen
         else:
-            session["deleted_categories"].append({"name": deleted_cat_id})
+            session["deleted_categories"][repository].append({"name": deleted_cat_id})
             # now we must clean the modified categories list in case the
             # deleted category was modified before
-            for element in session.get("modified_categories", []):
+            for element in session.get("modified_categories", {}).get(repository, []):
                 if element["name"] == deleted_cat_id:
-                    session["modified_categories"].remove(element)
+                    session["modified_categories"][repository].remove(element)
 
             # Now we also have to clean up categories that reference the
             # deleted category
             cat_manager_instance = CategoryManager(
                 getattr(
-                    catedit.persistence, app.config["PERSISTENCE_METHOD"]
-                )()
+                    catedit.persistence,
+                    app.config["PERSISTENCE_METHOD"]
+                )(repository=repository),
             )
             cat_list = cat_manager_instance.list_categories()
             # first we edit what was already modified before the deletion
-            logger.debug(session["modified_categories"])
-            element_list = list(session.get("modified_categories", []))
+            logger.debug(session["modified_categories"][repository])
+            element_list = list(session.get("modified_categories", {}).get(repository, []))
             if deleted_cat_id in [element["name"] for
-                                  element in session.get("deleted_categories",
-                                                         [])]:
+                                  element in session.get("deleted_categories", {}).get(repository, [])]:
                 for element in element_list:
                     logger.debug(str(element))
                     modified_cat_graph = Graph()
@@ -236,13 +242,13 @@
                             modified_cat.edit_category(
                                 new_other_properties=new_property_list
                             )
-                            session["modified_categories"][:] = [
+                            session["modified_categories"][repository][:] = [
                                 elt for elt in session.get(
                                     "modified_categories", []
                                 )
                                 if elt["name"] != modified_cat.cat_id
                             ]
-                            session["modified_categories"].append(
+                            session["modified_categories"][repository].append(
                                 {"name": modified_cat.cat_id,
                                  "content": str(
                                     modified_cat.cat_graph
@@ -255,10 +261,10 @@
                 for cat in cat_list:
                     if cat.cat_id not in [
                             element["name"] for element in
-                            session.get("modified_categories", [])
+                            session.get("modified_categories", {}).get(repository, [])
                     ] and cat.cat_id not in [
                             element["name"] for element in
-                            session.get("deleted_categories", [])
+                            session.get("deleted_categories", {}).get(repository, [])
                     ]:
                         new_property_list = []
                         for (predicate, obj) in cat.properties:
@@ -277,13 +283,13 @@
                             cat.edit_category(
                                 new_other_properties=new_property_list
                             )
-                            session["modified_categories"][:] = [
+                            session["modified_categories"][repository][:] = [
                                 elt for elt in session.get(
-                                    "modified_categories", []
-                                )
+                                    "modified_categories", {}
+                                ).get(repository, [])
                                 if elt["name"] != cat.cat_id
                             ]
-                            session["modified_categories"].append(
+                            session["modified_categories"][repository].append(
                                 {"name": cat.cat_id,
                                  "content": str(
                                     cat.cat_graph.serialize(format="turtle"),
@@ -301,36 +307,51 @@
         succesful if category is a modified one, returns only the cat_id if it
         is a deleted one
 
-        All changes and deletions are saved in session["modified_categories"]
-        and session["deleted_categories"]
+        All changes and deletions are saved in session["modified_categories"][repository]
+        and session["deleted_categories"][repository]
     """
-    def get(self, modified_cat_id=None):
+    def get(self, repository, modified_cat_id=None):
         """
             API to get the pending changes for category cat_id
         """
         logger.debug(modified_cat_id)
-        logger.debug(session.get("modified_categories", []))
+        logger.debug(str(session.get("modified_categories", {})))
+        logger.debug(str(session.get("modified_categories", {}).get(repository, [])))
         if modified_cat_id is None:
             return {
-                "modified_categories": session.get("modified_categories", []),
-                "deleted_categories": session.get("deleted_categories", [])
+                "modified_categories": session.get("modified_categories", {}).get(repository, []),
+                "deleted_categories": session.get("deleted_categories", {}).get(repository, [])
             }, 201
         else:
-            for category in session.get("modified_categories", []):
+            for category in session.get("modified_categories", {}).get(repository, []):
                 logger.debug(category)
                 if category["name"] == modified_cat_id:
                     return { "type": "modified", "category": category }, 201
-            for category in session.get("deleted_categories", []):
+            for category in session.get("deleted_categories", {}).get(repository, []):
                 logger.debug(category)
                 if category["name"] == modified_cat_id:
                     return { "type": "deleted", "category": category }, 201
             return 404
 
-    def delete(self, cat_id=None):
+    def delete(self, repository, modified_cat_id=None):
         """
             API to delete the category cat_id from the changelist or if cat_id
             is None, delete the whole changelist
         """
-        session["modified_categories"] = []
-        session["deleted_categories"] = []
+        if modified_cat_id is not None:
+            session["modified_categories"][repository][:] = [
+                elt for elt in session.get(
+                    "modified_categories", {}
+                ).get(repository, [])
+                if elt["name"] != modified_cat_id
+            ]
+            session["deleted_categories"][repository][:] = [
+                elt for elt in session.get(
+                    "modified_categories", {}
+                ).get(repository, [])
+                if elt["name"] != modified_cat_id
+            ]
+        else:
+            session["modified_categories"][repository] = []
+            session["deleted_categories"][repository] = []
         return 204
--- a/src/catedit/static/css/style.css	Fri Jan 02 16:46:56 2015 +0100
+++ b/src/catedit/static/css/style.css	Sat Jan 03 00:15:51 2015 +0100
@@ -24,3 +24,20 @@
 {
   display: inline;
 }
+
+.navbar-form
+{
+  width: 300px;
+  vertical-align: center;
+  display: inline-block;
+}
+
+.select-repo
+{
+  float:right;
+}
+
+.navbar-decorative,.navbar-decorative:hover
+{
+  color:blue;
+}
--- a/src/catedit/templates/cateditor.html	Fri Jan 02 16:46:56 2015 +0100
+++ b/src/catedit/templates/cateditor.html	Sat Jan 03 00:15:51 2015 +0100
@@ -31,17 +31,28 @@
           <ul class="nav navbar-nav">
             <li><a href="{{ url_for('cat_index') }}">Page d'accueil</a></li>
             {% if session.get("user_logged", None) %}
-            <li><a href="{{ url_for('cat_recap') }}">Atelier</a></li>
+            <li><a href="{{ url_for('cat_recap', repository=current_repository) }}">Atelier</a></li>
             {% endif %}
+            <li class="active"><a>Editeur</a></li>
           </ul>
           <div class="navbar-text navbar-right">
             {% if not session.get("user_logged", None)%} Non authentifié - <a href="{{ url_for('github_login') }}" class="navbar-link">S'authentifier</a>
             {% else %} Authentifié: {{ session["user_login"] }} - <a href="{{ url_for('logout') }}" class="navbar-link">Quitter</a>{% endif %}
           </div>
+          {% if session["user_logged"] %}
+          <form class="navbar-form navbar-right">
+            <select class="form-control select-repo" name="navrepo" onchange="window.location.href=this.form.navrepo.options[this.form.navrepo.selectedIndex].value">
+              {% for repo in config["REPOSITORY_LIST"] %}
+                <option value="{{url_for('cat_recap', repository=repo)}}" {% if repo==current_repository %}selected="selected"{% endif %}>{{repo}}</option>
+              {% endfor %}
+            </select>
+          </form>
+          {% endif %}
         </div>
       </div>
   </div>
   <div class="container">
+    <h2> <b>CatEdit</b> - <small>{{current_repository}}</small></h2>
     {% if session["user_logged"] and not session["user_can_edit"] %}
     <div class="alert alert-warning" role="alert">
       <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
@@ -64,9 +75,9 @@
       Vous n'avez pas rempli certains champs obligatoires.
     </div>
     {% endif %}
-    <h2>{% if cat_id: %} Edition : <small>Catégorie existante</small>{% else %}Création : <small>Nouvelle catégorie</small>{% endif %}</h2>
+    <h3>{% if cat_id: %} Edition : <small>Catégorie existante</small>{% else %}Création : <small>Nouvelle catégorie</small>{% endif %}</h3>
     {% if readonly %} <fieldset disabled> {% endif %}
-    <form method="POST" action="{% if cat_id %}{{ url_for('cat_editor', cat_id=cat_id) }}{% else %}{{ url_for('cat_editor') }}{% endif %}" id="cat_form" role="form">
+    <form method="POST" action="{% if cat_id %}{{ url_for('cat_editor', cat_id=cat_id, repository=current_repository) }}{% else %}{{ url_for('cat_editor', repository=current_repository) }}{% endif %}" id="cat_form" role="form">
         {{ form.hidden_tag() }}
         {% if form.label.errors %}
           {% set label_placeholder="Champ obligatoire" %}
@@ -151,7 +162,7 @@
           </div>
         </div><br>
         <br><input type="submit" value="Sauvegarder" class="btn btn-default">
-        <a href="{{ url_for('cat_recap')}}"class="btn btn-default">Annuler</a>
+        <a href="{{ url_for('cat_recap', repository=current_repository)}}"class="btn btn-default">Annuler</a>
     </form>
     {% if readonly %} </fieldset> {% endif %}
   <script src="{{ url_for('static', filename='js/property_functions.js') }}" language="Javascript" type="text/javascript"></script>
--- a/src/catedit/templates/catindex.html	Fri Jan 02 16:46:56 2015 +0100
+++ b/src/catedit/templates/catindex.html	Sat Jan 03 00:15:51 2015 +0100
@@ -39,14 +39,21 @@
           <div class="collapse navbar-collapse">
             <ul class="nav navbar-nav">
               <li class="active"><a>Page d'accueil</a></li>
-              {% if session.get("user_logged", None) %}
-              <li><a href="{{url_for('cat_recap')}}">Atelier</a></li>
-              {% endif %}
             </ul>
             <div class="navbar-text navbar-right">
               {% if not session.get("user_logged", None)%}Non authentifié - <a href="{{ url_for('github_login') }}" class="navbar-link">S'authentifier</a>
               {% else %} Authentifié: {{ session["user_login"] }} - <a href="{{ url_for('logout') }}" class="navbar-link">Quitter</a>{% endif %}
             </div>
+            {% if session["user_login"] %}
+            <form class="navbar-form navbar-right">
+              <select class="form-control select-repo" name="navrepo" onchange="window.location.href=this.form.navrepo.options[this.form.navrepo.selectedIndex].value">
+                <option value="" selected="selected">Sélectionner ensemble...</option>
+                {% for repo in config["REPOSITORY_LIST"] %}
+                  <option value="{{url_for('cat_recap', repository=repo)}}">{{repo}}</option>
+                {% endfor %}
+              </select>
+            </form>
+            {% endif %}
           </div>
         </div>
     </div>
@@ -60,10 +67,10 @@
           <a href="https://github.com/">s'inscrire sur Github</a>
         </p>
         <p>
-          Une fois authentifié, l'édition se fait en utilisant l'onglet Atelier.
-          Vous pourrez y trouver la liste des catégories existantes (pour l'instant,
-          l'outil ne porte que sur un unique ensemble de catégories) présentée dans
-          un tableau qui initialement ne comprend que les catégories de l'état courant.
+          Une fois authentifié, choisissez un ensemble de catégorie dans la liste se trouvant
+          dans la barre de navigation pour être redirigé vers l'atelier correspondant.
+          Vous pourrez y trouver la liste des catégories existantes pour cet ensemble,
+          présentée dans un tableau qui initialement ne comprend que les catégories de l'état courant.
         </p>
         <p>
           L'état courant de l'ensemble de catégorie est la base à partir de laquelle
--- a/src/catedit/templates/catmodifs.html	Fri Jan 02 16:46:56 2015 +0100
+++ b/src/catedit/templates/catmodifs.html	Sat Jan 03 00:15:51 2015 +0100
@@ -62,18 +62,28 @@
             <ul class="nav navbar-nav">
               <li><a href="{{ url_for('cat_index') }}">Page d'accueil</a></li>
               {% if session.get("user_logged", None) %}
-              <li><a href="{{ url_for('cat_recap') }}">Atelier</a></li>
+              <li><a href="{{ url_for('cat_recap', repository=current_repository) }}">Atelier</a></li>
               {% endif %}
+              <li class="active"><a>Soumission</a></li>
             </ul>
             <div class="navbar-text navbar-right">
               {% if not session.get("user_logged", None)%}Non authentifié - <a href="{{ url_for('github_login') }}" class="navbar-link">S'authentifier</a>
               {% else %} Authentifié: {{ session["user_login"] }} - <a href="{{ url_for('logout') }}" class="navbar-link">Quitter</a>{% endif %}
             </div>
+            {% if session["user_logged"] %}
+            <form class="navbar-form navbar-right">
+              <select class="form-control select-repo" name="navrepo" onchange="window.location.href=this.form.navrepo.options[this.form.navrepo.selectedIndex].value">
+                {% for repo in config["REPOSITORY_LIST"] %}
+                  <option value="{{url_for('cat_recap', repository=repo)}}" {% if repo==current_repository %}selected="selected"{% endif %}>{{repo}}</option>
+                {% endfor %}
+              </select>
+            </form>
+            {% endif %}
           </div>
         </div>
     </div>
     <div class="container">
-      <h2> <b>CatEdit</b> - <small>{{config.get("REPOSITORY_NAME", "Titre-Ensemble-Catégories")}} </small></h2>
+      <h2> <b>CatEdit</b> - <small>{{current_repository}}</small></h2>
       <h3> Catégories existantes </h3>
       <table class="table table-bordered table-condensed">
         <thead>
@@ -94,7 +104,7 @@
         {% else %}
           {% if cat_list|length == 0 %}
             <tr>
-              <td class="col-md-12" colspan="2">Aucune catégorie n'a été créée pour l'instant. {% if not readonly %}<a href="{{ url_for('cat_editor') }}">Créer une catégorie</a>{% endif %}</td>
+              <td class="col-md-12" colspan="2">Aucune catégorie n'a été créée pour l'instant. {% if not readonly %}<a href="{{ url_for('cat_editor', repository=current_repository) }}">Créer une catégorie</a>{% endif %}</td>
             </tr>
           {% else %}
             {% for cat in cat_list %}
@@ -106,11 +116,11 @@
                   </td>
                   {% if cat.cat_id not in deleted_cat_namelist and cat.cat_id not in modified_cat_namelist %}
                   <td class="text-center">
-                    <a href="{{ url_for('cat_editor', cat_id=cat.cat_id)}}" title="Editer catégorie" class="btn btn-default"><span class="glyphicon glyphicon glyphicon-pencil"/></a>
+                    <a href="{{ url_for('cat_editor', cat_id=cat.cat_id, repository=current_repository)}}" title="Editer catégorie" class="btn btn-default"><span class="glyphicon glyphicon glyphicon-pencil"/></a>
                   </td>
                   <td class="text-center">
                     <a title="Supprimer catégorie">
-                      <form method="POST" action="{{ url_for('cat_modifs', deleted_cat_id=cat.cat_id) }}" class="form-inline form-button">
+                      <form method="POST" action="{{ url_for('cat_modifs', deleted_cat_id=cat.cat_id, repository=current_repository) }}" class="form-inline form-button">
                         <fieldset {% if readonly %}disabled{% endif %}>
                           <button type="submit" class="btn btn-default">
                             <span class="glyphicon glyphicon-trash" title="Supprimer catégorie"/>
@@ -191,7 +201,7 @@
                 <td class="col-md-8">{{ cat.cat_description}}</td>
                 <td class="col-md-2 text-center">
                   <a title="Détails catégorie"><button class="btn btn-default" id="info_button_created_{{ cat.cat_id }}"><span class="glyphicon glyphicon-plus-sign"/></button></a>
-                  <a href="{{ url_for('cat_editor', cat_id=cat.cat_id)}}" title="Editer catégorie" class="btn btn-default"><span class="glyphicon glyphicon glyphicon-pencil"/></a>
+                  <a href="{{ url_for('cat_editor', cat_id=cat.cat_id, repository=current_repository)}}" title="Editer catégorie" class="btn btn-default"><span class="glyphicon glyphicon glyphicon-pencil"/></a>
                   <a title="Supprimer modifications"><button class="btn btn-default" id="remove_modifs_created_{{ cat.cat_id }}"><span class="glyphicon glyphicon-remove-sign"/></button></a>
                 </td>
               </tr>
@@ -221,7 +231,7 @@
                     </dl>
                   </div>
                   <div id="delete_created_{{cat.cat_id}}">
-                    <form method="POST" action="{{ url_for('cat_modifs', deleted_modifs_id=cat.cat_id) }}" class="form-inline align-center">
+                    <form method="POST" action="{{ url_for('cat_modifs', deleted_modifs_id=cat.cat_id, repository=current_repository) }}" class="form-inline align-center">
                       <fieldset {% if readonly %}disabled{% endif %}>
                         <div class="input-group">
                           <div class="input-group-addon">
@@ -252,7 +262,7 @@
                 <td class="col-md-8">{{ cat.cat_description}}</td>
                 <td class="col-md-2 text-center">
                   <a title="Détails catégorie"><button class="btn btn-default" id="info_button_modified_{{ cat.cat_id }}"><span class="glyphicon glyphicon-plus-sign"/></button></a>
-                  <a href="{{ url_for('cat_editor', cat_id=cat.cat_id)}}" title="Editer catégorie" class="btn btn-default"><span class="glyphicon glyphicon glyphicon-pencil"/></a>
+                  <a href="{{ url_for('cat_editor', cat_id=cat.cat_id, repository=current_repository)}}" title="Editer catégorie" class="btn btn-default"><span class="glyphicon glyphicon glyphicon-pencil"/></a>
                   <a title="Supprimer modifications"><button class="btn btn-default" id="remove_modifs_modified_{{ cat.cat_id }}"><span class="glyphicon glyphicon-remove-sign"/></button></a>
                 </td>
               </tr>
@@ -282,7 +292,7 @@
                     </dl>
                   </div>
                   <div id="delete_modified_{{cat.cat_id}}">
-                    <form method="POST" action="{{ url_for('cat_modifs', deleted_modifs_id=cat.cat_id) }}" class="form-inline align-center">
+                    <form method="POST" action="{{ url_for('cat_modifs', deleted_modifs_id=cat.cat_id, repository=current_repository) }}" class="form-inline align-center">
                       <fieldset {% if readonly %}disabled{% endif %}>
                         <div class="input-group">
                           <div class="input-group-addon">
@@ -315,7 +325,7 @@
                     <td class="col-md-2">{{ existing_cat.cat_label }}</td>
                     <td class="col-md-8"><i>Cette catégorie va être supprimée quand vous soumettrez vos modifications.</i></td>
                     <td class="col-md-2 text-center">
-                      <form method="POST" action="{{ url_for('cat_modifs', deleted_cat_id=deleted_cat) }}">
+                      <form method="POST" action="{{ url_for('cat_modifs', deleted_cat_id=deleted_cat, repository=current_repository) }}">
                         <fieldset {% if readonly %}disabled{% endif %}>
                           <input type="submit" class="btn btn-default" value="Restaurer">
                         </fieldset>
@@ -331,7 +341,7 @@
       </table>
       <h3> Soumettre mes changements </h3>
       <div class="col-md-12">
-        <form method="POST" action="{{ url_for('cat_modifs')}}">
+        <form method="POST" action="{{ url_for('cat_modifs', repository=current_repository)}}">
           <fieldset {% if readonly %}disabled{% endif %}>
             {{ commit_form.hidden_tag() }}
             <div class="form-group">
@@ -339,7 +349,7 @@
               {{ commit_form.commit_message(size=40, class="form-control", readonly=readonly) }}
             </div>
             <button type="submit" class="btn btn-default">Soumettre modifications</button>
-            <a href="{{ url_for('cat_recap')}}"class="btn btn-default">Retour</a>
+            <a href="{{ url_for('cat_recap', repository=current_repository)}}"class="btn btn-default">Retour</a>
           </fieldset>
         </form><br>
       </div>
--- a/src/catedit/templates/catrecap.html	Fri Jan 02 16:46:56 2015 +0100
+++ b/src/catedit/templates/catrecap.html	Sat Jan 03 00:15:51 2015 +0100
@@ -47,12 +47,21 @@
               {% if not session.get("user_logged", None)%}Non authentifié - <a href="{{ url_for('github_login') }}" class="navbar-link">S'authentifier</a>
               {% else %} Authentifié: {{ session["user_login"] }} - <a href="{{ url_for('logout') }}" class="navbar-link">Quitter</a>{% endif %}
             </div>
+            {% if session["user_logged"] %}
+            <form class="navbar-form navbar-right">
+              <select class="form-control select-repo" name="navrepo" onchange="window.location.href=this.form.navrepo.options[this.form.navrepo.selectedIndex].value">
+                {% for repo in config["REPOSITORY_LIST"] %}
+                  <option value="{{url_for('cat_recap', repository=repo)}}" {% if repo==current_repository %}selected="selected"{% endif %}>{{repo}}</option>
+                {% endfor %}
+              </select>
+            </form>
+            {% endif %}
           </div>
         </div>
     </div>
     <div class="container">
-      <h2> <b>CatEdit</b> - <small>{{config.get("REPOSITORY_NAME", "Titre-Ensemble-Catégories")}} </small></h2>
-      <h3> Créer une catégorie : <a href="{{url_for('cat_editor')}}" title="Créer catégorie" class="btn btn-default {% if readonly %}disabled{% endif %}"><span class="glyphicon glyphicon-plus"/></a></h3>
+      <h2> <b>CatEdit</b> - <small>{{current_repository}}</small></h2>
+      <h3> Créer une catégorie : <a href="{{url_for('cat_editor', repository=current_repository)}}" title="Créer catégorie" class="btn btn-default {% if readonly %}disabled{% endif %}"><span class="glyphicon glyphicon-plus"/></a></h3>
       {% if session["user_logged"] and not session["user_can_edit"] %}
       <div class="alert alert-warning" role="alert">
         <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
@@ -80,7 +89,7 @@
         {% else %}
           {% if cat_list|length == 0 %}
             <tr>
-              <td class="col-md-12" colspan="2">Aucune catégorie n'a été créée pour l'instant. {% if not readonly %}<a href="{{ url_for('cat_editor') }}">Créer une catégorie</a>{% endif %}</td>
+              <td class="col-md-12" colspan="2">Aucune catégorie n'a été créée pour l'instant. {% if not readonly %}<a href="{{ url_for('cat_editor', repository=current_repository) }}">Créer une catégorie</a>{% endif %}</td>
             </tr>
           {% else %}
             {% for cat in cat_list %}
@@ -101,14 +110,14 @@
                 </td>
                 {% if (cat.state != "deleted") %}
                 <td class="col-md-1 text-center">
-                  <a href="{{ url_for('cat_editor', cat_id=cat.cat_id)}}" title="Editer catégorie" class="btn btn-default">
+                  <a href="{{ url_for('cat_editor', cat_id=cat.cat_id, repository=current_repository)}}" title="Editer catégorie" class="btn btn-default">
                     <span class="glyphicon glyphicon glyphicon-pencil"/>
                   </a>
                 </td>
                 {% endif %}
                 {% if (cat.state == "untouched") %}
                 <td class="col-md-1 text-center">
-                  <form method="POST" action="{{url_for('cat_recap', deleted_cat_id=cat.cat_id)}}" class="form-inline">
+                  <form method="POST" action="{{url_for('cat_recap', deleted_cat_id=cat.cat_id, repository=current_repository)}}" class="form-inline">
                     <a title="Supprimer catégorie">
                       <button class="btn btn-default" type="submit"><span class="glyphicon glyphicon-trash"/></button>
                     </a>
@@ -116,7 +125,7 @@
                 </td>
                 {% elif (cat.state == "created" or cat.state == "modified") %}
                 <td class="col-md-1 text-center">
-                  <form method="POST" action="{{url_for('cat_recap', deleted_modifs_id=cat.cat_id)}}" class="form-inline">
+                  <form method="POST" action="{{url_for('cat_recap', deleted_modifs_id=cat.cat_id, repository=current_repository)}}" class="form-inline">
                     <a title="Supprimer changements">
                       <button class="btn btn-default"><span class="glyphicon glyphicon-remove-sign"/></button>
                     </a>
@@ -124,7 +133,7 @@
                 </td>
                 {% else %}
                 <td colspan="2">
-                  <form method="POST" action="{{url_for('cat_recap', deleted_cat_id=cat.cat_id)}}" class="form-inline">
+                  <form method="POST" action="{{url_for('cat_recap', deleted_cat_id=cat.cat_id, repository=current_repository)}}" class="form-inline">
                     <a title="Restaurer catégorie">
                       <button class="btn btn-default" type="submit">Restaurer</button>
                     </a>
@@ -172,7 +181,7 @@
         </tbody>
       </table>
       {% if session.get("user_logged") %}
-      <form method="POST" action="{{url_for('cat_recap')}}" class="form-inline">
+      <form method="POST" action="{{url_for('cat_recap', repository=current_repository)}}" class="form-inline">
         <h4> Annuler tous mes changements actuels :
           <a title="Supprimer changements">
             <button type="submit" class="btn btn-default" {% if readonly %}disabled{% endif %}>
@@ -181,7 +190,7 @@
           </a>
         </h4>
       </form>
-      <h4> Soumettre mes changements actuels : <a href="{{ url_for('cat_modifs')}}" title="Soumettre changements" class="btn btn-default" {% if readonly %}disabled{% endif %}><span class="glyphicon glyphicon-share"/></a>
+      <h4> Soumettre mes changements actuels : <a href="{{ url_for('cat_modifs', repository=current_repository)}}" title="Soumettre changements" class="btn btn-default" {% if readonly %}disabled{% endif %}><span class="glyphicon glyphicon-share"/></a>
       </h4>
       {% endif %}
       <h3> Consulter l'historique des modifications : <a href="https://github.com/{{config['REPOSITORY_OWNER']}}/{{config['REPOSITORY_NAME']}}/commits/master" title="Aller à l'historique des modifications sur Github" class="btn btn-default"><span class="glyphicon glyphicon-list"/></a></h3>
--- a/src/catedit/views.py	Fri Jan 02 16:46:56 2015 +0100
+++ b/src/catedit/views.py	Sat Jan 03 00:15:51 2015 +0100
@@ -6,7 +6,7 @@
 from catedit import app, github
 from catedit.models import Category
 import catedit.persistence
-from flask import render_template, request, redirect, url_for, session
+from flask import render_template, request, redirect, url_for, session, abort
 from flask.ext.github import GitHubError
 from flask_wtf import Form
 from catedit.resources import CategoryAPI, CategoryChangesAPI
@@ -26,11 +26,11 @@
     label = StringField(
         "Nom de la categorie (obligatoire)",
         validators=[DataRequired()]
-        )
+    )
     description = TextAreaField(
         "Description de la categorie (obligatoire)",
         validators=[DataRequired()]
-        )
+    )
 
 
 class CommitForm(Form):
@@ -44,27 +44,29 @@
 
 
 @app.route('/', methods=['GET'])
-@app.route('/index', methods=['GER'])
+@app.route('/index', methods=['GET'])
 def cat_index():
     return render_template("catindex.html")
 
-
-@app.route('/catrecap/delete-modifs-<deleted_modifs_id>',
+@app.route('/<string:repository>/catrecap',
+           defaults={'deleted_cat_id': None, 'deleted_modifs_id': None},
+           methods=['GET', 'POST'])
+@app.route('/<string:repository>/catrecap/delete-modifs-<deleted_modifs_id>',
            defaults={'deleted_cat_id': None},
            methods=['POST'])
-@app.route('/catrecap/delete-<deleted_cat_id>',
+@app.route('/<string:repository>/catrecap/delete-<deleted_cat_id>',
            defaults={'deleted_modifs_id': None},
            methods=['POST'])
-@app.route('/catrecap',
-           defaults={'deleted_cat_id': None, 'deleted_modifs_id': None},
-           methods=['GET', 'POST'])
-def cat_recap(deleted_cat_id, deleted_modifs_id):
+def cat_recap(repository, deleted_cat_id, deleted_modifs_id):
     """
         View that has a list of all categories available. Template is
         catrecap.html, located in src/templates/
 
         Note: it also handles category deletion from the same page.
     """
+    if repository not in app.config["REPOSITORY_LIST"]:
+        abort(404)
+
     cat_api_instance = CategoryAPI()
     cat_changes_api_instance = CategoryChangesAPI()
 
@@ -72,91 +74,101 @@
         if (session.get("user_logged", None) is not None and
                 session.get("user_can_edit", False) is not False):
             if (deleted_modifs_id is None and deleted_cat_id is None):
-                cat_changes_api_instance.delete()
+                cat_changes_api_instance.delete(repository=repository)
             elif deleted_modifs_id is not None:
                 logger.debug("Changes for category "
                              + deleted_modifs_id
                              + " will be deleted.")
-                cat_changes_api_instance.delete(deleted_modifs_id)
+                cat_changes_api_instance.delete(repository=repository, modified_cat_id=deleted_modifs_id)
             # We identify if we want to delete a category
             elif deleted_cat_id is not None:
                 logger.debug("Category "
                              + deleted_cat_id
                              + " will be deleted.")
-                cat_api_instance.delete(deleted_cat_id)
-        return redirect(url_for('cat_recap'))
+                cat_api_instance.delete(repository=repository, deleted_cat_id=deleted_cat_id)
+        return redirect(url_for('cat_recap',repository=repository))
     elif request.method == "GET":
 
         deleted_cat_list = []
         modified_cat_list = []
         serialized_cat_list = []
         if session.get("user_logged", None) is not None:
-            serialized_cat_list = cat_api_instance.get()
-            cat_changes = cat_changes_api_instance.get()[0]
-            modified_cat_list = cat_changes["modified_categories"]
-            logger.debug(modified_cat_list)
-            deleted_cat_list = cat_changes["deleted_categories"]
-            logger.debug(deleted_cat_list)
+            serialized_cat_list = cat_api_instance.get(repository=repository)
+            cat_changes = cat_changes_api_instance.get(repository=repository)
+            modified_cat_list = cat_changes[0]["modified_categories"]
+            deleted_cat_list = cat_changes[0]["deleted_categories"]
         # logger.debug(serialized_cat_list)
         cat_list = []
-
-        # first we find the untouched, edited and deleted categories
+        original_cat_list = []
         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)
-
-            logger.debug(str([cat["name"] for cat in modified_cat_list]))
-            logger.debug(str([cat["name"] for cat in deleted_cat_list]))
+            original_cat_list.append(Category(graph=cat_rdf_graph))
 
-            if cat.cat_id in [cat["name"] for cat in modified_cat_list]:
-                cat_state = "modified"
-            elif cat.cat_id in [cat["name"] for cat in deleted_cat_list]:
-                cat_state = "deleted"
-            else:
-                cat_state = "untouched"
+        edited_cat_list = []
+        for modified_cat in modified_cat_list:
+            new_cat_rdf_graph = Graph()
+            new_cat_rdf_graph.parse(source=StringIO(
+                                        modified_cat["content"]
+                                    ),
+                                    format='turtle')
+            edited_cat_list.append(Category(graph=new_cat_rdf_graph))
+        # first we find the untouched, edited and deleted categories
+        cat_state=""
+        for category in original_cat_list:
+            if category.cat_id not in [category["name"] for category in modified_cat_list]:
+                if category.cat_id in [cat["name"] for cat in deleted_cat_list]:
+                    cat_state = "deleted"
+                else:
+                    cat_state = "untouched"
 
-            cat_list.append({"cat_label": cat.label,
-                             "cat_description": cat.description,
-                             "cat_id": cat.cat_id,
-                             "cat_properties": cat.properties,
-                             "state": cat_state})
+                cat_list.append({"cat_label": category.label,
+                                 "cat_description": category.description,
+                                 "cat_id": category.cat_id,
+                                 "cat_properties": category.properties,
+                                 "state": cat_state})
 
         # now we must find the not yet submitted categories that were created
-        for modified_cat in modified_cat_list:
-            if modified_cat["name"] not in [cat["cat_id"] for cat in cat_list]:
-                new_cat_rdf_graph = Graph()
-                new_cat_rdf_graph.parse(source=StringIO(
-                                            modified_cat["content"]
-                                        ),
-                                        format='turtle')
-                new_cat = Category(graph=new_cat_rdf_graph)
-                cat_list.append({"cat_label": new_cat.label,
-                                 "cat_description": new_cat.description,
-                                 "cat_id": new_cat.cat_id,
-                                 "cat_properties": new_cat.properties,
-                                 "state": "created"})
+        cat_state=""
+        logger.debug("Edited cat list: "+str(edited_cat_list)+" - Original cat list: "+str(original_cat_list))
+        for category in edited_cat_list:
+            if category.cat_id not in [cat.cat_id for cat in original_cat_list]:
+                cat_state="created"
+            else:
+                cat_state="modified"
+            cat_list.append({"cat_label": category.label,
+                             "cat_description": category.description,
+                             "cat_id": category.cat_id,
+                             "cat_properties": category.properties,
+                             "state": cat_state})
 
             # logger.debug(c.properties)
+        cat_list = sorted(cat_list, key=lambda cat: cat['cat_id']) 
         return render_template('catrecap.html',
-                               cat_list=cat_list)
+                               cat_list=cat_list,
+                               current_repository=repository)
 
-@app.route('/catmodifs/delete-modifs-<deleted_modifs_id>',
+@app.route('/<string:repository>/catmodifs/delete-modifs-<deleted_modifs_id>',
            defaults={'deleted_cat_id': None},
            methods=['POST'])
-@app.route('/catmodifs/delete-<deleted_cat_id>',
+@app.route('/<string:repository>/catmodifs/delete-<deleted_cat_id>',
            defaults={'deleted_modifs_id': None},
            methods=['POST'])
-@app.route('/catmodifs',
+@app.route('/<string:repository>/catmodifs',
            defaults={'deleted_cat_id': None, 'deleted_modifs_id': None},
            methods=['GET', 'POST'])
-def cat_modifs(deleted_cat_id, deleted_modifs_id):
+def cat_modifs(repository, deleted_cat_id, deleted_modifs_id):
     """
         View that handles all the visualisation of changes for a user's
         session, links to the editor forms, allows the users to cancel their
         own changes and submits all their changes.
     """
+    if repository not in app.config["REPOSITORY_LIST"]:
+        abort(404)
+
+    logger.debug(repository)
+
     cat_list = []
     modified_cat_list = []
     created_cat_list = []
@@ -173,8 +185,8 @@
         # display the changes
         if request.method == "GET":
             if session.get("user_logged", None) is not None:
-                serialized_cat_list = cat_api_instance.get()
-                changes_list = cat_changes_api_instance.get()[0]
+                serialized_cat_list = cat_api_instance.get(repository=repository)
+                changes_list = cat_changes_api_instance.get(repository=repository)[0]
 
                 # Creating existing cat list
                 for serialized_cat in serialized_cat_list:
@@ -229,14 +241,15 @@
                                    modified_cat_list=modified_cat_list,
                                    modified_cat_namelist=modified_cat_namelist,
                                    deleted_cat_namelist=deleted_cat_namelist,
-                                   commit_form=commit_form)
+                                   commit_form=commit_form,
+                                   current_repository=repository)
         # If it's a POST with no delete_cat_id and delete_modifs_id, then we
         # will submit all the stored changes
         elif request.method == "POST":
             if commit_form.validate_on_submit():
-                cat_api_instance.put()
-                cat_changes_api_instance.delete()
-            return redirect(url_for('cat_recap'))
+                cat_api_instance.put(repository=repository)
+                cat_changes_api_instance.delete(repository=repository)
+            return redirect(url_for('cat_recap',repository=repository))
 
     # One of the ids is not None (either deleting a category or a modification)
     else:
@@ -246,20 +259,24 @@
             if (session.get("user_logged", None) is not None and
                 session.get("user_can_edit", False) is not False):
                 if deleted_modifs_id is not None:
-                    cat_changes_api_instance.delete(deleted_modifs_id)
+                    cat_changes_api_instance.delete(repository=repository,
+                                                    modified_cat_id=deleted_modifs_id)
                 # We identify if we want to delete a category
                 elif deleted_cat_id is not None:
-                    cat_api_instance.delete(delete_cat_id)
-        return redirect(url_for('cat_modifs'))
+                    cat_api_instance.delete(repository=repository, deleted_cat_id=deleted_cat_id)
+        return redirect(url_for('cat_modifs', repository=repository))
 
 
-@app.route('/cateditor', methods=['GET', 'POST'])
-@app.route('/cateditor/<string:cat_id>', methods=['GET', 'POST'])
-def cat_editor(cat_id=None):
+@app.route('/<string:repository>/cateditor', methods=['GET', 'POST'])
+@app.route('/<string:repository>/cateditor/<string:cat_id>', methods=['GET', 'POST'])
+def cat_editor(repository, cat_id=None):
     """
         View that handles creation and edition of categories. Template is
         cateditor.html, located in src/templates
     """
+    if repository not in app.config["REPOSITORY_LIST"]:
+        abort(404)
+
     cat_api_instance = CategoryAPI()
     cat_changes_api_instance = CategoryChangesAPI()
 
@@ -267,15 +284,13 @@
     deleted_cat_list = []
     serialized_cat_list = []
     if session.get("user_logged", None) is not None:
-        serialized_cat_list = cat_api_instance.get()
-        cat_changes=cat_changes_api_instance.get()
+        serialized_cat_list = cat_api_instance.get(repository)
+        cat_changes=cat_changes_api_instance.get(repository)
         deleted_cat_list = [
-            category["name"] for category in
-            cat_changes_api_instance.get()[0]["deleted_categories"]
+            category["name"] for category in cat_changes[0]["deleted_categories"]
         ]
         modified_cat_list = [
-            category["name"] for category in
-            cat_changes_api_instance.get()[0]["modified_categories"]
+            category for category in cat_changes[0]["modified_categories"]
         ]
     for serialized_cat in serialized_cat_list:
         cat_rdf_graph = Graph()
@@ -303,14 +318,15 @@
 
     if cat_id is not None:
         specific_serialized_cat = ""
-        changes_response = cat_changes_api_instance.get(cat_id)
+        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"] \
                                                              ["content"]
         else:
-            specific_serialized_cat = cat_api_instance.get(cat_id)
+            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),
@@ -340,24 +356,28 @@
                                    cat_properties=cat.properties,
                                    form=cat_form,
                                    cat_list=cat_list,
-                                   deleted_cat_list=deleted_cat_list)
+                                   deleted_cat_list=deleted_cat_list,
+                                   current_repository=repository)
 
         # 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 \
                 [element["name"] for element in
-                    session.get("deleted_categories", [])]:
+                 cat_changes[0]["deleted_categories"]]:
             if (session.get("user_logged", None) is not None and
                     session.get("user_can_edit", False) is not False):
-                cat_api_instance.put(cat_id)
-            return redirect(url_for('cat_recap'))
+                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)
+                                   deleted_cat_list=deleted_cat_list,
+                                   current_repository=repository)
 
     else:
         setattr(NewCategoryMinimalForm,
@@ -371,24 +391,26 @@
 
         cat_form = NewCategoryMinimalForm(request.form)
 
-        # GET seul = Create cat 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)
+                                   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()
-            return redirect(url_for('cat_recap'))
+                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)
+                                   deleted_cat_list=deleted_cat_list,
+                                   current_repository=repository)
 
 
 @app.route('/catedit-github-login')
@@ -403,9 +425,10 @@
     if getattr(catedit.persistence,
                app.config["PERSISTENCE_METHOD"])().session_compliant is True:
         session["save_user_changes"] = True
-        session["modified_categories"] = []
-        session["deleted_categories"] = []
+        session["modified_categories"] = {repo: [] for repo in app.config["REPOSITORY_LIST"]}
+        session["deleted_categories"] = {repo: [] for repo in app.config["REPOSITORY_LIST"]}
     if app.config["PERSISTENCE_METHOD"] == "PersistenceToGithub":
+        logger.debug(str(github.get("rate_limit")["resources"]))
         return github.authorize(scope="repo", redirect_uri=url_for('github_callback', _external=True))
     elif app.config["PERSISTENCE_METHOD"] == "PersistenceToFile":
         session["user_logged"] = True
@@ -423,10 +446,19 @@
     session.permanent = False
     session["user_code"] = oauth_code
     session["user_logged"] = True
-    session["user_login"] = github.get("user")["login"]
+    session["user_login"] = "auth-error"
+    try:
+        session["user_login"] = github.get("user")["login"]
+        logger.debug(str(github.get("rate_limit")["resources"]))
+    except GitHubError as ghe:
+        logger.debug(
+            "GitHubError trying to get the user login"
+        )
+        logger.debug(ghe.request.text)
     try:
         repo_list = []
         repo_list = github.get("user/repos")
+        logger.debug(str(github.get("rate_limit")["resources"]))
         for repo in repo_list:
             logger.debug(repo["name"])
         session["user_can_edit"] = True
@@ -434,10 +466,12 @@
                    for repo in repo_list):
             session["user_can_edit"] = False
         logger.debug(session["user_can_edit"])
-    except GitHubError:
-        logger.debug("error getting repos!")
-
-    logger.debug(session["user_login"])
+    except GitHubError as ghe:
+        logger.debug(
+            "GitHubError trying to get the list of repository for user "
+            +session["user_login"]
+        )
+        logger.debug(ghe.request.text)
     return redirect(url_for('cat_index'))
 
 
@@ -466,6 +500,6 @@
     session["user_login"] = None
     session["user_can_edit"] = None
     session["save_user_changes"] = None
-    session["modified_categories"] = []
-    session["deleted_categories"] = []
-    return redirect(url_for('cat_recap'))
+    session["modified_categories"] = {repo: [] for repo in app.config["REPOSITORY_LIST"]}
+    session["deleted_categories"] = {repo: [] for repo in app.config["REPOSITORY_LIST"]}
+    return redirect(url_for('cat_index'))