aboutsummaryrefslogtreecommitdiff
path: root/pyaggr3g470r/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'pyaggr3g470r/controllers')
-rw-r--r--pyaggr3g470r/controllers/__init__.py6
-rw-r--r--pyaggr3g470r/controllers/abstract.py69
-rw-r--r--pyaggr3g470r/controllers/article.py27
-rw-r--r--pyaggr3g470r/controllers/feed.py24
-rw-r--r--pyaggr3g470r/controllers/user.py7
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'
bgstack15