def get_topics(user, sort_by, offset=0, limit=10): """Gets topics from redis or postgresql Args: user (User): the current user sort_by (str): the sort key offset (int): offset limit (int): limit Returns: An array of topics (formatted by json_data) sorted by :sort_by and limited by :limit started from :offset """ rev = sort_by[0] == '-' if rev: sort_by = sort_by[1:] key = _generate_topics_key(sort_by) redis_client = get_client(key) if not redis_client.exists(key): fetch_topics(sort_by) start = offset stop = offset + limit - 1 if rev: topic_ids = redis_client.zrevrange(key, start, stop) else: topic_ids = redis_client.zrange(key, start, stop) topics = [] for id in topic_ids: topics.append(get_topic(id)) return topics
def get_article(id, user=None): """Gets a single article (formatted by json_data) from redis or postgresql And performs some pre-filters for the current user Args: id (int): id user (User): the current user Returns: None if the article is not existed or a dict of article data """ id = int(id) key = Article.cache_key(id) redis_client = get_client(key) article = None if not redis_client.exists(key): article = Article.find_by_pk(id) if article: data = article.json_data() redis_client.set(key, json.dumps(data)) article = data else: if redis_client.type(key) == 'hash': print redis_client article = json.loads(redis_client.get(key)) article['user_vote'] = Article.check_vote(user, article['id']) return article
def get_articles(user, sort_by, offset=0, limit=10): """Gets articles from redis or postgresql Args: user (User): the current user sort_by (str): the sort key offset (int): offset limit (int): limit Returns: An array of articles (formatted by json_data) sorted by :sort_by and limited by :limit started from :offset """ rev = sort_by[0] == '-' if rev: sort_by = sort_by[1:] key = _generate_articles_key(sort_by) redis_client = get_client(key) if not redis_client.exists(key): fetch_articles(sort_by) start = offset stop = offset + limit - 1 if rev: article_ids = redis_client.zrevrange(key, start, stop) else: article_ids = redis_client.zrange(key, start, stop) articles = [] for id in article_ids: articles.append(get_article(id)) return articles
def get_topic(id, user=None): """Gets a single topic (formatted by json_data) from redis or postgresql And performs some pre-filters for the current user Args: id (int): id user (User): the current user Returns: None if the topic is not existed or a dict of topic data """ id = int(id) key = Topic.cache_key(id) redis_client = get_client(key) topic = None if not redis_client.exists(key): topic = Topic.find_by_pk(id) if topic: data = topic.json_data() redis_client.set(key, json.dumps(data)) topic = data else: if redis_client.type(key) == 'hash': print redis_client topic = json.loads(redis_client.get(key)) topic['user_vote'] = Topic.check_vote(user, topic['id']) return topic
def check_vote(cls, user, article_id): """Determine if user_id has voted or not Args: user (User): the current user Returns: None if the user has not voted yet True if the user has up-voted False if the user has down-voted """ self = cls() self.id = article_id ref_name = get_remote_side(self, 'votes') if not user: return None key = self._user_vote_redis_key(user.id) redis_client = get_client(key) if not redis_client.exists(key): filter_data = {ref_name: self.id, 'user_id': user.id} cls = get_remote_side_class(self, 'votes') vote = cls.query.filter_by(**filter_data).first() if vote: user_vote = vote.up else: user_vote = None redis_client.set(key, self._vote_value_for_redis(vote)) else: value = int(redis_client.get(key)) user_vote = self._parse_vote_value_from_redis(value) return user_vote
def _last_ip_view(self, ip): key = ":".join([self.__tablename__, str(self.id), ip, 'last_view']) redis_client = get_client(key) last_view = redis_client.getset(key, now_ms()) if last_view is None: last_view = now_ms() return int(last_view)
def get_user_comment_count(instance, user_id): key = _comment_count_redis_key(instance, user_id) redis_client = get_client(key) count = redis_client.get(key) if not count: return None return int(count)
def update_user_comment_count(instance, user_id, offset=1): key = _comment_count_redis_key(instance, user_id) redis_client = get_client(key) if offset > 0: result = redis_client.incr(key, offset) else: result = redis_client.decr(key, abs(offset)) return int(result)
def get_tags(instance): key = _tags_redis_key(instance) redis_client = get_client(key) if not redis_client.exists(key): tags = [tag.json_data()['name'] for tag in instance.tags] redis_client.sadd(key, *tags) tags = [{"name": tag} for tag in tags] else: tags = redis_client.smembers(key) tags = [{"name": tag} for tag in tags] return tags
def fetch_topics(sort_by): """Fetches all the topics from postgresql and construct a set sorted by :sort_by DESC Args: sort_by(str): the sort key applied to topics Returns: None """ topics = Topic.query.all() key = _generate_topics_key(sort_by) redis_client = get_client(key) data = dict() for topic in topics: data[str(topic.id)] = getattr(topic, sort_by) redis_client.zadd(key, **data)
def fetch_articles(sort_by): """Fetches all the articles from postgresql and construct a set sorted by :sort_by DESC Args: sort_by(str): the sort key applied to articles Returns: None """ articles = Article.query.filter_by(is_active=True).all() key = _generate_articles_key(sort_by) redis_client = get_client(key) data = dict() for article in articles: data[str(article.id)] = getattr(article, sort_by) redis_client.zadd(key, **data)
def update_topic(id, topic=None): """Updates the cache of article :id Args: id (int): topic id topic (Topic): if not provided, a topic will be queried from postgresql Returns: Topic """ id = int(id) if not topic: topic = Topic.find_by_pk(id) if topic: key = Topic.cache_key(id) redis_client = get_client(key) data = topic.json_data() redis_client.set(key, json.dumps(data)) return topic
def update_article(id, article=None): """Updates the cache of article :id Args: id (int): article id article (Article): if not provided, an article will be queried from postgresql Returns: Article """ id = int(id) if not article: article = Article.find_by_pk(id) if article: key = Article.cache_key(id) redis_client = get_client(key) data = article.json_data() redis_client.set(key, json.dumps(data)) return article
def check_vote(cls, user, article_id): """Determine if user_id has voted or not Args: user (User): the current user Returns: None if the user has not voted yet True if the user has up-voted False if the user has down-voted """ self = cls() self.id = article_id ref_name = get_remote_side(self, 'votes') if not user: return None key = self._user_vote_redis_key(user.id) redis_client = get_client(key) if not redis_client.exists(key): filter_data ={ ref_name: self.id, 'user_id': user.id } cls = get_remote_side_class(self, 'votes') vote = cls.query.filter_by(**filter_data).first() if vote: user_vote = vote.up else: user_vote = None redis_client.set(key, self._vote_value_for_redis(vote)) else: value = int(redis_client.get(key)) user_vote = self._parse_vote_value_from_redis(value) return user_vote
def update_sorted_articles(article, sort_by): key = _generate_articles_key(sort_by) redis_client = get_client(key) data = dict() data[str(article.id)] = getattr(article, sort_by) redis_client.zadd(key, **data)
def update_sorted_topics(topic, sort_by): key = _generate_topics_key(sort_by) redis_client = get_client(key) data = dict() data[str(topic.id)] = getattr(topic, sort_by) redis_client.zadd(key, **data)
def _update_vote_value_for_redis(self, user_id, vote): key = self._user_vote_redis_key(user_id) redis_client = get_client(key) redis_client.set(key, self._vote_value_for_redis(vote))
def delete_tags(instance): key = _tags_redis_key(instance) redis_client = get_client(key) redis_client.delete(key)
def _update_user_view_log(self, user_id): key = ":".join(["users", str(user_id), "view_log", self.__tablename__]) redis_client = get_client(key) redis_client.zadd(key, now_ms(), self.id)
def _update_vote_value_for_redis(self, user_id, vote): key = self._user_vote_redis_key(user_id) redis_client = get_client(key) redis_client.set(key, self._vote_value_for_redis(vote))