From 2849c82255b4b889c7342a0a8fa8a4aecfbe599d Mon Sep 17 00:00:00 2001 From: François Schmidts Date: Sat, 17 Jan 2015 16:50:38 +0100 Subject: a first big refacto of the existing arch --- pyaggr3g470r/views/api/article.py | 40 +++++---------------------------- pyaggr3g470r/views/api/common.py | 47 ++++++++++++++++++--------------------- pyaggr3g470r/views/api/feed.py | 32 ++++++-------------------- 3 files changed, 35 insertions(+), 84 deletions(-) (limited to 'pyaggr3g470r/views/api') diff --git a/pyaggr3g470r/views/api/article.py b/pyaggr3g470r/views/api/article.py index c509b0a8..3642cda9 100644 --- a/pyaggr3g470r/views/api/article.py +++ b/pyaggr3g470r/views/api/article.py @@ -1,15 +1,11 @@ import re import dateutil.parser -import conf -if not conf.ON_HEROKU: - import pyaggr3g470r.search as fastsearch - from flask import request, g from flask.ext.restful import Resource, reqparse -from pyaggr3g470r import api, db from pyaggr3g470r.models import Article, Feed +from pyaggr3g470r.controllers import ArticleController from pyaggr3g470r.views.api.common import authenticate, to_response, \ PyAggResource @@ -77,7 +73,7 @@ class ArticleListAPI(Resource): feed = Feed.query.filter(Feed.id == article_dict["feed_id"], Feed.user_id == g.user.id).first() feed.articles.append(article) try: - db.session.commit() + g.db.session.commit() return {"message": "ok"}, 201 except: return {"message": "Impossible to create the article."}, 500 @@ -86,7 +82,8 @@ class ArticleListAPI(Resource): class ArticleAPI(PyAggResource): "Defines a RESTful API for Article elements." method_decorators = [authenticate, to_response] - db_cls = Article + controller_cls = ArticleController + editable_attrs = ['like', 'readed'] def __init__(self): self.reqparse = reqparse.RequestParser() @@ -94,32 +91,7 @@ class ArticleAPI(PyAggResource): self.reqparse.add_argument('readed', type=bool, location= 'json') super(ArticleAPI, self).__init__() - def get(self, id): - article = self._get_or_raise(id) - if not article.readed: - article.readed = True - db.session.commit() - return {'result': [article.dump()]} - - def put(self, id): - """ Update an article. It is only possible to update the status - ('like' and 'readed') of an article.""" - args = self.reqparse.parse_args() - article = self._get_or_raise(id) - if 'like' in args: - article.like = args['like'] - if 'readed' in args: - article.readed = args['readed'] - db.session.commit() - - try: - fastsearch.delete_article(g.user.id, article.feed_id, article.id) - except: - pass - return {"message": "ok"} - -api.add_resource(ArticleListAPI, '/api/v1.0/articles', - endpoint='articles.json') -api.add_resource(ArticleAPI, '/api/v1.0/articles/', +g.api.add_resource(ArticleListAPI, '/articles', endpoint='articles.json') +g.api.add_resource(ArticleAPI, '/articles/', endpoint='article.json') diff --git a/pyaggr3g470r/views/api/common.py b/pyaggr3g470r/views/api/common.py index 872c4ae1..a116b9c3 100644 --- a/pyaggr3g470r/views/api/common.py +++ b/pyaggr3g470r/views/api/common.py @@ -2,12 +2,8 @@ from functools import wraps from flask import request, g, session, Response, jsonify from flask.ext.restful import Resource -from pyaggr3g470r import db from pyaggr3g470r.models import User - - -class HttpError(Exception): - pass +from pyaggr3g470r.lib.exceptions import PyAggError def authenticate(func): @@ -43,8 +39,10 @@ def to_response(func): def wrapper(*args, **kwargs): try: res = func(*args, **kwargs) - except HttpError, error: - return Response(*error.args) + except PyAggError, error: + response = jsonify(**error.message) + response.status_code = error.status_code + return response if isinstance(res, tuple): response = jsonify(**res[0]) if len(res) > 1: @@ -55,25 +53,24 @@ def to_response(func): class PyAggResource(Resource): - db_cls = None + method_decorators = [authenticate, to_response] + controller_cls = None + editable_attrs = [] + + def __init__(self, *args, **kwargs): + self.controller = self.controller_cls(g.user.id) + super(PyAggResource, self).__init__(*args, **kwargs) - def _get_or_raise(self, obj_id=None): - if obj_id is None: - raise HttpError({'message': 'No id given'}, 400) - obj = self.db_cls.query.filter(self.db_cls.id == obj_id).first() - if obj is None: - raise HttpError({'message': 'Article not found'}, 404) - if obj.user_id != g.user.id: - raise HttpError({'message': "Unauthorized for %s." - % self.db_cls.__class__.__name__}, 403) - return obj + def get(self, obj_id=None): + return {'result': [self.controller.read(id=obj_id).dump()]} - def get(self, id=None): - return {'result': [self._get_or_raise(id).dump()]} + def put(self, obj_id=None): + args = self.reqparse.parse_args() + new_values = {key: args[key] for key in + set(args).intersection(self.editable_attrs)} + self.controller.update(obj_id, **new_values) + return {"message": "ok"} - def delete(self, id): - """Delete a feed.""" - feed = self._get_or_raise(id) - db.session.delete(feed) - db.session.commit() + def delete(self, obj_id=None): + self.controller.delete(obj_id) return {"message": "ok"}, 204 diff --git a/pyaggr3g470r/views/api/feed.py b/pyaggr3g470r/views/api/feed.py index e5937128..346898b5 100644 --- a/pyaggr3g470r/views/api/feed.py +++ b/pyaggr3g470r/views/api/feed.py @@ -1,7 +1,7 @@ from flask import g from flask.ext.restful import Resource, reqparse -from pyaggr3g470r import api, db +from pyaggr3g470r.controllers import FeedController from pyaggr3g470r.models import Feed from pyaggr3g470r.views.api.common import authenticate, to_response, \ @@ -62,7 +62,7 @@ class FeedListAPI(Resource): enabled=feed_dict["enabled"]) g.user.feeds.append(new_feed) try: - db.session.commit() + g.db.session.commit() return {"message": "ok"} except: return {'message': 'Impossible to create the feed.'}, 500 @@ -70,8 +70,9 @@ class FeedListAPI(Resource): class FeedAPI(PyAggResource): "Defines a RESTful API for Feed elements." - method_decorators = [authenticate, to_response] - db_cls = Feed + controller_cls = FeedController + editable_attrs = ['title', 'description', 'link', 'site_link', + 'email_notification', 'enabled'] def __init__(self): self.reqparse = reqparse.RequestParser() @@ -85,25 +86,6 @@ class FeedAPI(PyAggResource): self.reqparse.add_argument('enabled', type=bool ,location='json') super(FeedAPI, self).__init__() - def put(self, id): - "Update a feed" - args = self.reqparse.parse_args() - feed = self.get_feed_or_raise(id) - if 'title' in args: - feed.title = args['title'] - if 'description' in args: - feed.description = args['description'] - if 'link' in args: - feed.link = args['link'] - if 'site_link' in args: - feed.site_link = args['site_link'] - if 'email_notification' in args: - feed.email_notification = args['email_notification'] - if 'enabled' in args: - feed.enabled = args['enabled'] - db.session.commit() - return {"message": "ok"} - -api.add_resource(FeedListAPI, '/api/v1.0/feeds', endpoint = 'feeds.json') -api.add_resource(FeedAPI, '/api/v1.0/feeds/', endpoint = 'feed.json') +g.api.add_resource(FeedListAPI, '/feeds', endpoint='feeds.json') +g.api.add_resource(FeedAPI, '/feeds/', endpoint='feed.json') -- cgit