diff options
Diffstat (limited to 'pyaggr3g470r/controllers')
-rw-r--r-- | pyaggr3g470r/controllers/__init__.py | 6 | ||||
-rw-r--r-- | pyaggr3g470r/controllers/abstract.py | 69 | ||||
-rw-r--r-- | pyaggr3g470r/controllers/article.py | 27 | ||||
-rw-r--r-- | pyaggr3g470r/controllers/feed.py | 24 | ||||
-rw-r--r-- | pyaggr3g470r/controllers/user.py | 7 |
5 files changed, 133 insertions, 0 deletions
diff --git a/pyaggr3g470r/controllers/__init__.py b/pyaggr3g470r/controllers/__init__.py new file mode 100644 index 00000000..d8d1a104 --- /dev/null +++ b/pyaggr3g470r/controllers/__init__.py @@ -0,0 +1,6 @@ +from .feed import FeedController +from .article import ArticleController +from .user import UserController + + +__all__ = ['FeedController', 'ArticleController', 'UserController'] diff --git a/pyaggr3g470r/controllers/abstract.py b/pyaggr3g470r/controllers/abstract.py new file mode 100644 index 00000000..a99e67f3 --- /dev/null +++ b/pyaggr3g470r/controllers/abstract.py @@ -0,0 +1,69 @@ +import logging +from bootstrap import db +from sqlalchemy import update +from werkzeug.exceptions import Forbidden, NotFound + +logger = logging.getLogger(__name__) + + +class AbstractController(object): + _db_cls = None # reference to the database class + _user_id_key = 'user_id' + + def __init__(self, user_id): + self.user_id = user_id + + def _to_filters(self, **filters): + if self.user_id: + filters[self._user_id_key] = self.user_id + db_filters = set() + for key, value in filters.items(): + if key.endswith('__gt'): + db_filters.add(getattr(self._db_cls, key[:-4]) > value) + elif key.endswith('__lt'): + db_filters.add(getattr(self._db_cls, key[:-4]) < value) + elif key.endswith('__ge'): + db_filters.add(getattr(self._db_cls, key[:-4]) >= value) + elif key.endswith('__le'): + db_filters.add(getattr(self._db_cls, key[:-4]) <= value) + elif key.endswith('__ne'): + db_filters.add(getattr(self._db_cls, key[:-4]) != value) + elif key.endswith('__in'): + db_filters.add(getattr(self._db_cls, key[:-4]).in_(value)) + else: + db_filters.add(getattr(self._db_cls, key) == value) + return db_filters + + def _get(self, **filters): + return self._db_cls.query.filter(*self._to_filters(**filters)) + + def get(self, **filters): + obj = self._get(**filters).first() + if not obj: + raise NotFound({'message': 'No %r (%r)' + % (self._db_cls.__class__.__name__, filters)}) + if getattr(obj, self._user_id_key) != self.user_id: + raise Forbidden({'message': 'No authorized to access %r (%r)' + % (self._db_cls.__class__.__name__, filters)}) + return obj + + def create(self, **attrs): + attrs[self._user_id_key] = self.user_id + obj = self._db_cls(**attrs) + db.session.add(obj) + db.session.commit() + return obj + + def read(self, **filters): + return self._get(**filters) + + def update(self, filters, attrs): + result = self._get(**filters).update(attrs, synchronize_session=False) + db.session.commit() + return result + + def delete(self, obj_id): + obj = self.get(id=obj_id) + db.session.delete(obj) + db.session.commit() + return obj diff --git a/pyaggr3g470r/controllers/article.py b/pyaggr3g470r/controllers/article.py new file mode 100644 index 00000000..46ca0988 --- /dev/null +++ b/pyaggr3g470r/controllers/article.py @@ -0,0 +1,27 @@ +import conf +from .abstract import AbstractController +from pyaggr3g470r.models import Article + + +class ArticleController(AbstractController): + _db_cls = Article + + def get(self, **filters): + article = super(ArticleController, self).get(**filters) + if not article.readed: + self.update({'id': article.id}, {'readed': True}) + return article + + def delete(self, obj_id): + obj = super(ArticleController, self).delete(obj_id) + if not conf.ON_HEROKU: + import pyaggr3g470r.search as fastsearch + fastsearch.delete_article(self.user_id, obj.feed_id, obj_id) + return obj + + def challenge(self, ids): + """Will return each id that wasn't found in the database.""" + for id_ in ids: + if self.read(**id_).first(): + continue + yield id_ diff --git a/pyaggr3g470r/controllers/feed.py b/pyaggr3g470r/controllers/feed.py new file mode 100644 index 00000000..a2455e2b --- /dev/null +++ b/pyaggr3g470r/controllers/feed.py @@ -0,0 +1,24 @@ +from datetime import datetime, timedelta +from .abstract import AbstractController +from pyaggr3g470r.models import Feed + +DEFAULT_MAX_ERROR = 3 +DEFAULT_LIMIT = 5 + + +class FeedController(AbstractController): + _db_cls = Feed + + def list_fetchable(self, max_error=DEFAULT_MAX_ERROR, limit=DEFAULT_LIMIT): + from pyaggr3g470r.controllers import UserController + now = datetime.now() + user = UserController(self.user_id).get(id=self.user_id) + max_last = now - timedelta(minutes=user.refresh_rate or 60) + feeds = [feed for feed in self.read(user_id=self.user_id, + error_count__lt=max_error, enabled=True, + last_retreived__lt=max_last).limit(limit)] + + if feeds: + self.update({'id__in': [feed.id for feed in feeds]}, + {'last_retreived': now}) + return feeds diff --git a/pyaggr3g470r/controllers/user.py b/pyaggr3g470r/controllers/user.py new file mode 100644 index 00000000..c6c1d545 --- /dev/null +++ b/pyaggr3g470r/controllers/user.py @@ -0,0 +1,7 @@ +from .abstract import AbstractController +from pyaggr3g470r.models import User + + +class UserController(AbstractController): + _db_cls = User + _user_id_key = 'id' |