# HG changeset patch # User ymh # Date 1420213616 -3600 # Node ID d47f8f8b3faf97d07270187621898abb0999390f # Parent 82635fefa88ee5f27d2896d75e60d8e60b80503b correct initialization and import of application + rename api file diff -r 82635fefa88e -r d47f8f8b3faf src/catedit/__init__.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/', + '/category', + endpoint='category') +api.add_resource(CategoryChangesAPI, + '/category-changes/', + '/category-changes', + endpoint='category_changes') + + # set up logging if app.config["LOGGING"]: file_handler = FileHandler(filename=app.config["LOG_FILE_PATH"]) diff -r 82635fefa88e -r d47f8f8b3faf src/catedit/api.py --- 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/', - '/category', - endpoint='category') -api.add_resource(CategoryChangesAPI, - '/category-changes/', - '/category-changes', - endpoint='category_changes') diff -r 82635fefa88e -r d47f8f8b3faf src/catedit/main.py --- 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"]) diff -r 82635fefa88e -r d47f8f8b3faf src/catedit/models.py --- 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): diff -r 82635fefa88e -r d47f8f8b3faf src/catedit/persistence.py --- 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 diff -r 82635fefa88e -r d47f8f8b3faf src/catedit/resources.py --- /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 diff -r 82635fefa88e -r d47f8f8b3faf src/catedit/views.py --- 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