Exemple #1
0
def get_article_json(id: IntLike,
                     only_from_cache=False,
                     process_json=True) -> Union[dict, None]:
    """
    Get  article json by id

    `only_from_cache` is for multiget_article_json()
    """
    key = Keys.article_json.format(id)
    data = rd.get(key)  # none is returned if not exists
    if data is not None:
        json_article = json.loads(data.decode())
        rd.expire(key, Keys.article_json_expire)
        if not process_json:
            return json_article
        return Article.process_json(json_article)
    if only_from_cache:
        return None
    article = Article.query.get(id)
    if article is None:
        return None
    json_article = article.to_json(cache=True)
    cache_article_json(json_article)
    if not process_json:
        return json_article
    return Article.process_json(json_article)
Exemple #2
0
def get_status_json(id: IntLike,
                    only_from_cache=False,
                    process_json=True) -> Union[dict, None]:
    """Get processed status_json

    * None is returned in case of status is not found
    * `only_from_cache` is for multiget_status_json()
    """
    key = KEYS.status_json.format(id)
    data = rd.get(key)
    # data is a dict with bytes key and bytes value
    if data:  # hit in redis cache
        result = json.loads(data.decode())
        rd.expire(key, KEYS.status_json_expire)
        if process_json:
            return Status.process_json(result)
        return result
    if only_from_cache:
        return None
    print("Can't load status {} from redis".format(id))
    print("Try to load from mysql")
    status = Status.query.get(id)
    if status is None:
        print("Can't load status {} from mysql".format(id))
        return None
    result = status.to_json(cache=True)
    cache_status_json(result)
    if process_json:
        return Status.process_json(result)
    return result
Exemple #3
0
def _load_user_timeline(id):
    """
    Load user timeline from database
    """
    sql = """
    select * from (
        select 0 as kind, id, timestamp
        from statuses where user_id=:UID or user_id in (
            select followed_id from user_follows as F
            where F.follower_id=:UID
        )
        union
        select 1 as kind, id, timestamp
        from articles where official_account_id in (
            select official_account_id from subscriptions as S
            where S.users_id=:UID
        )
    ) as t order by timestamp DESC limit :LIMIT offset :OFFSET;
    """ # NOTE: `S.users_id` is a typo of column name(Don't change)
    key = Keys.user_timeline.format(id)
    result = db.engine.execute(text(sql), UID=id, LIMIT=100, OFFSET=0)
    result = list(result)
    args = []
    for item in result:
        if item['kind'] == 0:
            timeline_item = Keys.timeline_status_item.format(item['id'])
            score = Score.timestamp_to_score(item['timestamp'])
            rd.zadd(key, score, timeline_item)
        elif item['kind'] == 1:
            timeline_item = Keys.timeline_article_item.format(item['id'])
            score = Score.timestamp_to_score(item['timestamp'])
            args += [score, timeline_item]
    if args:
        rd.zadd(key, *args)
        rd.expire(key, Keys.user_timeline_expire)
Exemple #4
0
def _cache_liked_users(id: IntLike):
    key = KEYS.status_liked_users.format(id)
    sql = 'select user_id from status_likes where status_id=:SID'
    result = db.engine.execute(text(sql), SID=id)
    liked_user_ids = [row[0] for row in result]
    liked_user_ids.append(-1)
    rd.sadd(key, *liked_user_ids)
    rd.expire(key, KEYS.status_liked_users_expire)
    def add_to_cache(self, value, label=None):
        if type(value) != str:
            value = ujson.dumps(value)
        key = self._get_key(label=label)
        resp = rd.set(name=key, value=value)
        rd.expire(name=key, time=app.config['CACHE_KEY_EXPIRE'])

        return resp
Exemple #6
0
def get_subscriber_ids(id: IntLike):
    key = KEYS.official_account_subscribers.format(id)
    ids = rd.smembers(key)
    if not ids:
        _cache_account_subscribers(id)
        ids = rd.smembers(key)
    rd.expire(key, KEYS.official_account_subscribers_expire)
    ids = [t.decode() for t in ids]
    return ids
Exemple #7
0
def get_follower_ids(id: IntLike):
    key = Keys.user_followers.format(id)
    # returns an empty set if key not exists
    ids = rd.smembers(key)
    if not ids:
        _cache_followers(id)
        ids = rd.smembers(key)
    rd.expire(key, Keys.user_followers_expire)
    ids = [t.decode() for t in ids]
    return ids
Exemple #8
0
def _cache_account_subscribers(id: IntLike):
    key = KEYS.official_account_subscribers.format(id)
    sql = """
    select users_id from subscriptions
    where official_account_id=:OID
    """
    result = db.engine.execute(text(sql), OID=id)
    subscriber_ids = [row[0] for row in result]
    subscriber_ids.append(-1)
    rd.sadd(key, *subscriber_ids)
    rd.expire(key, KEYS.official_account_subscribers_expire)
Exemple #9
0
def _cache_followers(id: IntLike):
    key = Keys.user_followers.format(id)
    sql = "select follower_id from user_follows where followed_id=:UID"
    result = db.engine.execute(text(sql), UID=id)
    follower_ids = [row[0] for row in result]
    """
    As redis does not support empty set, but we
    still need to know whether an empty set is cached,
    so we need a placeholder element(use self's id is good)
    """
    follower_ids.append(id)
    rd.sadd(key, *follower_ids)
    rd.expire(key, Keys.user_followers_expire)
Exemple #10
0
def get_user(id: IntLike):
    """ None is returned if user can't found """
    key = Keys.user.format(id)
    data = rd.get(key)
    if data != None:
        user = pickle.loads(data)
        user = db.session.merge(user, load=False)
        rd.expire(key, Keys.user_expire)
        return user
    user = User.query.get(id)
    if user != None:
        data = pickle.dumps(user)
        rd.set(key, data, Keys.user_expire)
    return user
Exemple #11
0
def get_user_json(id: IntLike) -> Union[dict, None]:
    """
    None is returned in case of user not exists
    """
    key = Keys.user_json.format(id)
    data = rd.get(key)
    if data:
        json_user = json.loads(data.decode())
        rd.expire(key, Keys.user_json_expire)
        return User.process_json(json_user)
    user = get_user(id)
    if user is None:
        return None
    json_user = user.to_json(cache=True)
    cache_user_json(json_user)
    return User.process_json(json_user)
Exemple #12
0
def get_official_account_json(id: IntLike):
    """ Get official_account_json from redis by id

    None is returned in case of not found
    """
    key = KEYS.official_account_json.format(id)
    data = rd.get(key)
    if data is not None:
        json_account = json.loads(data.decode())
        rd.expire(key, KEYS.official_account_json_expire)
        return OfficialAccount.process_json(json_account)
    account = OfficialAccount.query.get(id)
    if account is None:
        return None
    json_account = account.to_json(cache=True)
    cache_account_json(json_account)
    return OfficialAccount.process_json(json_account)
Exemple #13
0
def get_group_josn(id: IntLike):
    """
    Get group json from redis
    None is returned in case of not found
    """
    key = KEYS.group_json.format(id)
    data = rd.get(key)
    if data is not None:
        json_group = json.loads(data.decode())
        rd.expire(key, KEYS.group_json_expire)
        return Group.process_json(json_group)
    group = Group.query.get(id)
    if group is None:
        return None
    json_group = group.to_json(cache=True)
    cache_group_json(json_group)
    return Group.process_json(json_group)
def login():
    auth = request.authorization
    
    if not auth:
        return jsonify('Authorization request missing'), 401

    if not auth.username:
        return jsonify('Username is missing'), 401

    if not auth.password:
        return jsonify('Password is missing'), 401

    user = Users.query.filter_by(email=auth.username).first()
    if not user:
        return jsonify('Username not found'), 401

    # if check_password_hash(user.password, auth.password):
    print(user.password)
    if bcrypt.checkpw(auth.password.encode('utf-8'), user.password.encode('utf-8') ):

        # generate session id
        sessionid = str(uuid.uuid4())
        print('sessionid at login:'******'uid' : user.id, 
            'cid' : user.cid,
            'sessionid' : sessionid, 
            'exp' : datetime.datetime.utcnow() + datetime.timedelta(seconds=app.config['SESSION_EXPIRY'])
            }

        token = create_access_token(identity=user.id, headers=jwt_payload)

        # set session keys and setting expiry in redis
        # rd.hset(user.id,'token', token)
        rd.hset(user.id,'sessionid', sessionid)
        rd.expire(user.id, app.config['SESSION_EXPIRY'])

        # set additional keys in redis
        rd.hset(user.id,'segid', user.segid)
        rd.hset(user.id,'cid', user.cid)

        return jsonify({'token' : token})

    return jsonify('Invalid Password'), 401
Exemple #15
0
def get_timeline():
    """
    获取个人Timeline
    参数:
    limit: 可选,default=10
    offset: 可选,default=10
    """
    limit = request.args.get('limit', 10, type=int)
    offset = request.args.get('offset', 0, type=int)
    key = Keys.user_timeline.format(g.user.id)
    print("View:", key)
    if not rd.exists(key):
        # A long time no-logged in user comes back
        #rd.rpush(Keys.timeline_events_queue,
        #         Keys.user_returned.format(g.user.id))
        _load_user_timeline(g.user.id)
    """element: type:id,  type=s|a"""
    datas = rd.zrevrange(key, offset, offset + limit - 1)
    rd.expire(key, Keys.user_timeline_expire)
    items = [d.decode() for d in datas]
    print("Timeline items:", items)
    status_ids = []
    article_ids = []
    for item in items:
        if item[0] == Keys.timeline_status_prefix:
            status_ids.append(item[2:])
        elif item[0] == Keys.timeline_article_prefix:
            article_ids.append(item[2:])
        else:
            raise Exception("No such type")
    statuses = Cache.multiget_status_json(status_ids)
    articles = Cache.multiget_article_json(article_ids)
    res_map = {}
    for s in statuses:
        item_key = Keys.timeline_status_item.format(s['id'])
        res_map[item_key] = s
    for a in articles:
        item_key = Keys.timeline_article_item.format(a['id'])
        res_map[item_key] = a
    res = [res_map[t] for t in items if t in res_map]
    return jsonify(res)
Exemple #16
0
def get_group_user_title(group_id: IntLike, user_id: IntLike):
    """
    Get user's title in some group
    "" is returned if not found
    """
    key = KEYS.group_user_title.format(group_id=group_id, user_id=user_id)
    data = rd.get(key)
    if data is not None:
        rd.expire(key, KEYS.group_user_title_expire)
        return data.decode()
    sql = """
    select title from group_memberships
    where user_id=:UID and group_id=:GID
    """
    result = db.engine.execute(text(sql), UID=user_id, GID=group_id)
    res = result.first()
    if res is None:
        return ""
    title = res[0]
    rd.set(key, title, ex=KEYS.group_user_title_expire)
    return title