Пример #1
0
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
Пример #2
0
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
Пример #3
0
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
Пример #4
0
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
Пример #5
0
    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
Пример #6
0
 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)
Пример #7
0
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)
Пример #8
0
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)
Пример #9
0
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
Пример #10
0
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)
Пример #11
0
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)
Пример #12
0
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
Пример #13
0
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
Пример #14
0
    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
Пример #15
0
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)
Пример #16
0
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)
Пример #17
0
 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))
Пример #18
0
def delete_tags(instance):
    key = _tags_redis_key(instance)
    redis_client = get_client(key)
    redis_client.delete(key)
Пример #19
0
 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)
Пример #20
0
 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))