correct initialization and import of application + rename api file
authorymh <ymh.work@gmail.com>
Fri, 02 Jan 2015 16:46:56 +0100
changeset 20 d47f8f8b3faf
parent 19 82635fefa88e
child 21 b1b002c5ff60
correct initialization and import of application + rename api file
src/catedit/__init__.py
src/catedit/api.py
src/catedit/main.py
src/catedit/models.py
src/catedit/persistence.py
src/catedit/resources.py
src/catedit/views.py
--- a/src/catedit/__init__.py	Fri Jan 02 12:05:47 2015 +0100
+++ b/src/catedit/__init__.py	Fri Jan 02 16:46:56 2015 +0100
@@ -2,12 +2,16 @@
 __init__.py:
 module main file used to configure the Flask app
 """
+
+from logging import FileHandler, Formatter
+
 from flask import Flask, session
 from flask.ext.github import GitHub
 from flask.ext.cache import Cache
-from settings import AppSettings
-from config import AppConfig
-from logging import FileHandler, Formatter
+from flask.ext.restful import Api
+
+from catedit.config import AppConfig
+from catedit.settings import AppSettings
 
 # set up app and database
 app = Flask(__name__)
@@ -15,8 +19,30 @@
 cache = Cache(app, config={"CACHE_TYPE": "simple"})
 app.config.from_object(AppConfig)
 
+#github
 github = GitHub(app)
 
+#api
+api = Api(app)
+
+
+#views
+from catedit.views import cat_editor, cat_recap, github_login,\
+                          github_callback, logout
+
+from catedit.resources import CategoryAPI, CategoryChangesAPI
+
+
+api.add_resource(CategoryAPI,
+                 '/category/<string:cat_id>',
+                 '/category',
+                 endpoint='category')
+api.add_resource(CategoryChangesAPI,
+                 '/category-changes/<string:cat_id>',
+                 '/category-changes',
+                 endpoint='category_changes')
+
+
 # set up logging
 if app.config["LOGGING"]:
     file_handler = FileHandler(filename=app.config["LOG_FILE_PATH"])
--- a/src/catedit/api.py	Fri Jan 02 12:05:47 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,350 +0,0 @@
-"""
-api.py:
-contains the api that links the views (views.py) to the model (models.py) and
-its persistence method (persistence.py). As it only trades rdf graphs
-serializations strings, it isn't bound to one specific view
-"""
-
-from rdflib import Graph
-from flask.ext.restful import Resource, Api, reqparse
-from flask import request, session
-from catedit import app, cache
-from catedit.models import Category, CategoryManager
-import catedit.persistence
-from io import StringIO
-
-api = Api(app)
-
-logger = app.logger
-
-cat_parser = reqparse.RequestParser()
-cat_parser.add_argument('label', type=str)
-cat_parser.add_argument('description', type=str)
-cat_parser.add_argument('commit_message', type=str)
-cat_parser.add_argument('property_predicate', type=str, action="append")
-cat_parser.add_argument('property_object', type=str, action="append")
-cat_parser.add_argument('delete_message', type=str)
-
-
-class CategoryAPI(Resource):
-    """
-        The API to create and edit categories, returns rdf graph serializations
-        when successful
-    """
-    @classmethod
-    @cache.memoize(timeout=3600)
-    def get(cls, 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"])()
-        )
-        if cat_id is not None:
-            cat = cat_manager_instance.load_category(cat_id)
-            return cat.cat_graph.serialize(format='turtle').decode("utf-8")
-        else:
-            response = []
-            for cat in cat_manager_instance.list_categories():
-                response.append(cat.cat_graph.serialize(format='turtle')
-                                             .decode("utf-8"))
-            return response
-
-    # update category cat_id
-    @classmethod
-    def put(cls, 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"])()
-        )
-        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", []))
-                             + " and modified categories are:"
-                             + str(session.get("modified_categories", [])))
-                cat_manager_instance.save_changes(
-                    deleted_cat_list = session.get("deleted_categories", []),
-                    modified_cat_list = session.get("modified_categories", []),
-                    message=args["commit_message"]
-                )
-        else:
-            new_property_list = []
-            logger.debug(args["property_predicate"])
-            logger.debug(args["property_object"])
-            if args["property_predicate"] is not None and \
-               args["property_object"] is not None:
-                for property_predicate, property_object in zip(
-                        args["property_predicate"],
-                        args["property_object"]):
-                    if property_object:
-                        property_object_to_append = property_object
-                        # if URIRef category, we must prefix id with namespace
-                        if (app.config["PROPERTY_LIST"]
-                                      [property_predicate]
-                                      ["object_type"]) == "uriref-category":
-                            property_object_to_append = \
-                                app.config["CATEGORY_NAMESPACE"] \
-                                + property_object
-                            logger.debug(property_object_to_append)
-                        new_property_list.append((property_predicate,
-                                                  property_object_to_append))
-            logger.debug(new_property_list)
-
-            # 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", []):
-                    if element["name"] == cat_id:
-                        cat_graph = Graph()
-                        cat_graph.parse(
-                            source=StringIO(element["content"]),
-                            format="turtle"
-                        )
-                        cat = Category(graph=cat_graph)
-            else:
-                cat = cat_manager_instance.load_category(cat_id)
-
-            cat.edit_category(new_description=args["description"],
-                              new_label=args["label"],
-                              new_other_properties=new_property_list)
-
-            session["modified_categories"][:] = [
-                elt for elt in session.get("modified_categories", [])
-                if elt["name"] != cat.cat_id
-            ]
-            session["modified_categories"].append(
-                {"name": cat.cat_id,
-                 "content": str(
-                    cat.cat_graph.serialize(format="turtle"), "utf-8"
-                 )}
-            )
-
-            # 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", []):
-                if element["name"] == cat.cat_id:
-                    session["deleted_categories"].remove(element)
-
-            logger.debug("put id: "+cat.cat_id)
-        cache.clear()
-        return 204
-
-    @classmethod
-    def post(cls):
-        """
-            API to create a new category
-        """
-        args = cat_parser.parse_args()
-        property_list = []
-        logger.debug(args["property_predicate"])
-        logger.debug(args["property_object"])
-        for property_predicate, property_object in zip(
-                request.form.getlist('property_predicate'),
-                request.form.getlist('property_object')):
-            if property_object:
-                if (app.config["PROPERTY_LIST"]
-                              [property_predicate]
-                              ["object_type"]) == "uriref-category":
-                    property_list.append((property_predicate,
-                                          app.config["CATEGORY_NAMESPACE"]
-                                          + property_object))
-                else:
-                    property_list.append((property_predicate,
-                                          property_object))
-        logger.debug(property_list)
-        cat = Category(label=args["label"],
-                       description=args["description"],
-                       other_properties=property_list)
-
-        session["modified_categories"][:] = [
-            elt for elt in session.get("modified_categories", [])
-            if elt["name"] != cat.cat_id
-        ]
-        session["modified_categories"].append(
-            {"name": cat.cat_id,
-             "content": str(
-                cat.cat_graph.serialize(format="turtle"), "utf-8"
-             )}
-        )
-
-        logger.debug("post id: "+cat.cat_id)
-        cache.clear()
-        return cat.cat_graph.serialize(format='turtle').decode("utf-8"), 201
-
-    @classmethod
-    def delete(cls, deleted_cat_id):
-        """
-            API to delete the category of id cat_id or restore it from the
-            deletion list
-        """
-        args = cat_parser.parse_args()
-        if (deleted_cat_id in [
-            element["name"] for element in session.get("deleted_categories", [])
-        ]):
-            session["deleted_categories"].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})
-            # now we must clean the modified categories list in case the
-            # deleted category was modified before
-            for element in session.get("modified_categories", []):
-                if element["name"] == deleted_cat_id:
-                    session["modified_categories"].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"]
-                )()
-            )
-            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", []))
-            if deleted_cat_id in [element["name"] for
-                                  element in session.get("deleted_categories",
-                                                         [])]:
-                for element in element_list:
-                    logger.debug(str(element))
-                    modified_cat_graph = Graph()
-                    modified_cat_graph.parse(
-                        source=StringIO(element["content"]),
-                        format="turtle"
-                    )
-                    modified_cat = Category(graph=modified_cat_graph)
-                    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"] == "uriref-category")
-                                and
-                                (obj == (app.config["CATEGORY_NAMESPACE"] +
-                                         deleted_cat_id))
-                            ):
-                                new_property_list.append((predicate, obj))
-
-                        if new_property_list != modified_cat.properties:
-                            logger.debug("Modifying modified category")
-                            modified_cat.edit_category(
-                                new_other_properties=new_property_list
-                            )
-                            session["modified_categories"][:] = [
-                                elt for elt in session.get(
-                                    "modified_categories", []
-                                )
-                                if elt["name"] != modified_cat.cat_id
-                            ]
-                            session["modified_categories"].append(
-                                {"name": modified_cat.cat_id,
-                                 "content": str(
-                                    modified_cat.cat_graph
-                                                .serialize(format="turtle"),
-                                    "utf-8"
-                                 )}
-                            )
-                # now we check if an unmodified category reference the deleted
-                # category
-                for cat in cat_list:
-                    if cat.cat_id not in [
-                            element["name"] for element in
-                            session.get("modified_categories", [])
-                    ] and cat.cat_id not in [
-                            element["name"] for element in
-                            session.get("deleted_categories", [])
-                    ]:
-                        new_property_list = []
-                        for (predicate, obj) in cat.properties:
-                            if not (
-                                (app.config["PROPERTY_LIST"]
-                                           [predicate]
-                                           ["object_type"] == "uriref-category")
-                                and
-                                (obj == (app.config["CATEGORY_NAMESPACE"] +
-                                         deleted_cat_id))
-                            ):
-                                new_property_list.append((predicate, obj))
-
-                        if new_property_list != cat.properties:
-                            logger.debug("Modifying untouched category")
-                            cat.edit_category(
-                                new_other_properties=new_property_list
-                            )
-                            session["modified_categories"][:] = [
-                                elt for elt in session.get(
-                                    "modified_categories", []
-                                )
-                                if elt["name"] != cat.cat_id
-                            ]
-                            session["modified_categories"].append(
-                                {"name": cat.cat_id,
-                                 "content": str(
-                                    cat.cat_graph.serialize(format="turtle"),
-                                    "utf-8"
-                                 )}
-                            )
-
-        logger.debug("delete id: " + deleted_cat_id)
-        cache.clear()
-        return 204
-
-class CategoryChangesAPI(Resource):
-    """
-        API for getting and deleting category changes, returns a dict when
-        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"]
-    """
-    @classmethod
-    def get(cls, 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", []))
-        if modified_cat_id is None:
-            return {
-                "modified_categories": session.get("modified_categories", []),
-                "deleted_categories": session.get("deleted_categories", [])
-            }, 201
-        else:
-            for category in session.get("modified_categories", []):
-                logger.debug(category)
-                if category["name"] == modified_cat_id:
-                    return { "type": "modified", "category": category }, 201
-            for category in session.get("deleted_categories", []):
-                logger.debug(category)
-                if category["name"] == modified_cat_id:
-                    return { "type": "deleted", "category": category }, 201
-            return 404
-
-    def delete(cls, 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"] = []
-        return 204
-
-api.add_resource(CategoryAPI,
-                 '/category/<string:cat_id>',
-                 '/category',
-                 endpoint='category')
-api.add_resource(CategoryChangesAPI,
-                 '/category-changes/<string:cat_id>',
-                 '/category-changes',
-                 endpoint='category_changes')
--- a/src/catedit/main.py	Fri Jan 02 12:05:47 2015 +0100
+++ b/src/catedit/main.py	Fri Jan 02 16:46:56 2015 +0100
@@ -3,9 +3,6 @@
 script that is used to boot up the application
 """
 from catedit import app
-from catedit.api import api
-from catedit.views import cat_editor, cat_recap, github_login, \
-                          github_callback, logout
 
 if __name__ == '__main__':
     app.run(host=app.config["HOST"])
--- a/src/catedit/models.py	Fri Jan 02 12:05:47 2015 +0100
+++ b/src/catedit/models.py	Fri Jan 02 16:46:56 2015 +0100
@@ -9,10 +9,10 @@
 from uuid import uuid4
 from io import StringIO
 from slugify import slugify
+import logging
 from catedit import app
 
-
-logger = app.logger
+logger = logging.getLogger(__name__)
 
 
 class Category(object):
--- a/src/catedit/persistence.py	Fri Jan 02 12:05:47 2015 +0100
+++ b/src/catedit/persistence.py	Fri Jan 02 16:46:56 2015 +0100
@@ -9,9 +9,8 @@
 for categories)
 """
 from abc import ABCMeta, abstractmethod
-from catedit import app, github
+from catedit import github, app
 from base64 import b64decode
-from flask import session
 from flask.ext.github import GitHubError
 import os
 import json
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/catedit/resources.py	Fri Jan 02 16:46:56 2015 +0100
@@ -0,0 +1,336 @@
+"""
+api.py:
+contains the api that links the views (views.py) to the model (models.py) and
+its persistence method (persistence.py). As it only trades rdf graphs
+serializations strings, it isn't bound to one specific view
+"""
+
+
+from rdflib import Graph
+from flask.ext.cache import Cache
+from flask.ext.restful import Resource, reqparse
+from flask import request, session
+from catedit import app, cache
+from catedit.models import Category, CategoryManager
+import catedit.persistence
+from io import StringIO
+import logging
+
+logger = app.logger
+
+cat_parser = reqparse.RequestParser()
+cat_parser.add_argument('label', type=str)
+cat_parser.add_argument('description', type=str)
+cat_parser.add_argument('commit_message', type=str)
+cat_parser.add_argument('property_predicate', type=str, action="append")
+cat_parser.add_argument('property_object', type=str, action="append")
+cat_parser.add_argument('delete_message', type=str)
+
+
+class CategoryAPI(Resource):
+    """
+        The API to create and edit categories, returns rdf graph serializations
+        when successful
+    """
+    @cache.memoize(timeout=3600)
+    def get(self, 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"])()
+        )
+        if cat_id is not None:
+            cat = cat_manager_instance.load_category(cat_id)
+            return cat.cat_graph.serialize(format='turtle').decode("utf-8")
+        else:
+            response = []
+            for cat in cat_manager_instance.list_categories():
+                response.append(cat.cat_graph.serialize(format='turtle')
+                                             .decode("utf-8"))
+            return response
+
+    # update category cat_id
+    def put(self, 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"])()
+        )
+        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", []))
+                             + " and modified categories are:"
+                             + str(session.get("modified_categories", [])))
+                cat_manager_instance.save_changes(
+                    deleted_cat_list = session.get("deleted_categories", []),
+                    modified_cat_list = session.get("modified_categories", []),
+                    message=args["commit_message"]
+                )
+        else:
+            new_property_list = []
+            logger.debug(args["property_predicate"])
+            logger.debug(args["property_object"])
+            if args["property_predicate"] is not None and \
+               args["property_object"] is not None:
+                for property_predicate, property_object in zip(
+                        args["property_predicate"],
+                        args["property_object"]):
+                    if property_object:
+                        property_object_to_append = property_object
+                        # if URIRef category, we must prefix id with namespace
+                        if (app.config["PROPERTY_LIST"]
+                                      [property_predicate]
+                                      ["object_type"]) == "uriref-category":
+                            property_object_to_append = \
+                                app.config["CATEGORY_NAMESPACE"] \
+                                + property_object
+                            logger.debug(property_object_to_append)
+                        new_property_list.append((property_predicate,
+                                                  property_object_to_append))
+            logger.debug(new_property_list)
+
+            # 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", []):
+                    if element["name"] == cat_id:
+                        cat_graph = Graph()
+                        cat_graph.parse(
+                            source=StringIO(element["content"]),
+                            format="turtle"
+                        )
+                        cat = Category(graph=cat_graph)
+            else:
+                cat = cat_manager_instance.load_category(cat_id)
+
+            cat.edit_category(new_description=args["description"],
+                              new_label=args["label"],
+                              new_other_properties=new_property_list)
+
+            session["modified_categories"][:] = [
+                elt for elt in session.get("modified_categories", [])
+                if elt["name"] != cat.cat_id
+            ]
+            session["modified_categories"].append(
+                {"name": cat.cat_id,
+                 "content": str(
+                    cat.cat_graph.serialize(format="turtle"), "utf-8"
+                 )}
+            )
+
+            # 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", []):
+                if element["name"] == cat.cat_id:
+                    session["deleted_categories"].remove(element)
+
+            logger.debug("put id: "+cat.cat_id)
+        cache.clear()
+        return 204
+
+    def post(self):
+        """
+            API to create a new category
+        """
+        args = cat_parser.parse_args()
+        property_list = []
+        logger.debug(args["property_predicate"])
+        logger.debug(args["property_object"])
+        for property_predicate, property_object in zip(
+                request.form.getlist('property_predicate'),
+                request.form.getlist('property_object')):
+            if property_object:
+                if (app.config["PROPERTY_LIST"]
+                              [property_predicate]
+                              ["object_type"]) == "uriref-category":
+                    property_list.append((property_predicate,
+                                          app.config["CATEGORY_NAMESPACE"]
+                                          + property_object))
+                else:
+                    property_list.append((property_predicate,
+                                          property_object))
+        logger.debug(property_list)
+        cat = Category(label=args["label"],
+                       description=args["description"],
+                       other_properties=property_list)
+
+        session["modified_categories"][:] = [
+            elt for elt in session.get("modified_categories", [])
+            if elt["name"] != cat.cat_id
+        ]
+        session["modified_categories"].append(
+            {"name": cat.cat_id,
+             "content": str(
+                cat.cat_graph.serialize(format="turtle"), "utf-8"
+             )}
+        )
+
+        logger.debug("post id: "+cat.cat_id)
+        cache.clear()
+        return cat.cat_graph.serialize(format='turtle').decode("utf-8"), 201
+
+    def delete(self, 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", [])
+        ]):
+            session["deleted_categories"].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})
+            # now we must clean the modified categories list in case the
+            # deleted category was modified before
+            for element in session.get("modified_categories", []):
+                if element["name"] == deleted_cat_id:
+                    session["modified_categories"].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"]
+                )()
+            )
+            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", []))
+            if deleted_cat_id in [element["name"] for
+                                  element in session.get("deleted_categories",
+                                                         [])]:
+                for element in element_list:
+                    logger.debug(str(element))
+                    modified_cat_graph = Graph()
+                    modified_cat_graph.parse(
+                        source=StringIO(element["content"]),
+                        format="turtle"
+                    )
+                    modified_cat = Category(graph=modified_cat_graph)
+                    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"] == "uriref-category")
+                                and
+                                (obj == (app.config["CATEGORY_NAMESPACE"] +
+                                         deleted_cat_id))
+                            ):
+                                new_property_list.append((predicate, obj))
+
+                        if new_property_list != modified_cat.properties:
+                            logger.debug("Modifying modified category")
+                            modified_cat.edit_category(
+                                new_other_properties=new_property_list
+                            )
+                            session["modified_categories"][:] = [
+                                elt for elt in session.get(
+                                    "modified_categories", []
+                                )
+                                if elt["name"] != modified_cat.cat_id
+                            ]
+                            session["modified_categories"].append(
+                                {"name": modified_cat.cat_id,
+                                 "content": str(
+                                    modified_cat.cat_graph
+                                                .serialize(format="turtle"),
+                                    "utf-8"
+                                 )}
+                            )
+                # now we check if an unmodified category reference the deleted
+                # category
+                for cat in cat_list:
+                    if cat.cat_id not in [
+                            element["name"] for element in
+                            session.get("modified_categories", [])
+                    ] and cat.cat_id not in [
+                            element["name"] for element in
+                            session.get("deleted_categories", [])
+                    ]:
+                        new_property_list = []
+                        for (predicate, obj) in cat.properties:
+                            if not (
+                                (app.config["PROPERTY_LIST"]
+                                           [predicate]
+                                           ["object_type"] == "uriref-category")
+                                and
+                                (obj == (app.config["CATEGORY_NAMESPACE"] +
+                                         deleted_cat_id))
+                            ):
+                                new_property_list.append((predicate, obj))
+
+                        if new_property_list != cat.properties:
+                            logger.debug("Modifying untouched category")
+                            cat.edit_category(
+                                new_other_properties=new_property_list
+                            )
+                            session["modified_categories"][:] = [
+                                elt for elt in session.get(
+                                    "modified_categories", []
+                                )
+                                if elt["name"] != cat.cat_id
+                            ]
+                            session["modified_categories"].append(
+                                {"name": cat.cat_id,
+                                 "content": str(
+                                    cat.cat_graph.serialize(format="turtle"),
+                                    "utf-8"
+                                 )}
+                            )
+
+        logger.debug("delete id: " + deleted_cat_id)
+        cache.clear()
+        return 204
+
+class CategoryChangesAPI(Resource):
+    """
+        API for getting and deleting category changes, returns a dict when
+        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"]
+    """
+    def get(self, 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", []))
+        if modified_cat_id is None:
+            return {
+                "modified_categories": session.get("modified_categories", []),
+                "deleted_categories": session.get("deleted_categories", [])
+            }, 201
+        else:
+            for category in session.get("modified_categories", []):
+                logger.debug(category)
+                if category["name"] == modified_cat_id:
+                    return { "type": "modified", "category": category }, 201
+            for category in session.get("deleted_categories", []):
+                logger.debug(category)
+                if category["name"] == modified_cat_id:
+                    return { "type": "deleted", "category": category }, 201
+            return 404
+
+    def delete(self, 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"] = []
+        return 204
--- a/src/catedit/views.py	Fri Jan 02 12:05:47 2015 +0100
+++ b/src/catedit/views.py	Fri Jan 02 16:46:56 2015 +0100
@@ -9,7 +9,7 @@
 from flask import render_template, request, redirect, url_for, session
 from flask.ext.github import GitHubError
 from flask_wtf import Form
-from catedit.api import CategoryAPI, CategoryChangesAPI
+from catedit.resources import CategoryAPI, CategoryChangesAPI
 from wtforms import StringField, TextAreaField
 from wtforms.validators import DataRequired
 from rdflib import Graph