Example #1
0
async def add_tweet(user, msg, tags):
    """
    add user tweet with specific tags and after that add to redis to fetch in future
    :param user: login user json data
    :param msg: tweet message
    :param tags: list of tags
    :return:
    """
    try:
        async with db.transaction():
            tweet = Tweet(msg=msg, user_id=user.get('user_id'))
            await tweet.create()
            for tag_item in tags:
                tag = await get_or_create(Tag, *(Tag.tag_name == tag_item, ),
                                          **({
                                              "tag_name": tag_item
                                          }))
                tweet_tag = TagTweet(tag_id=tag.id, tweet_id=tweet.id)
                await tweet_tag.create()
                if tweet_tag:
                    await redis.append_value(tag.tag_name, tweet.as_json())
        return tweet.as_json(), None
    except Exception as ex:
        global_logger.write_log('error', f"error: {ex}")
        return None, ex
Example #2
0
async def delete(model, *args):
    """
    delete method for using delete a record from model
    :param model: model class
    :param args: where condition
    :return:
    """
    try:
        await model.delete.where(*args).gino.status()
    except Exception as ex:
        global_logger.write_log('error', f"error: {ex}")
Example #3
0
async def fetch_tweets(tag, page=1, page_size=10):
    """
    At the first lookup in redis if does not exist, search on PG
    in pg run this sql query => SELECT * FROM tweets WHERE tweets.id IN
                            (SELECT tweet_id FROM tag_tweet WHERE tag_tweet.tag_id =
                            (SELECT tags.id FROM tags WHERE tags.tag_name={tag}))
                            limit {page_size} offset (page - 1) * page_size
    fetch all of tweets which related with specific tag
    :param tag: tag name
    :param page: page number
    :param page_size: page_size
    :return: A list of tweet and total count
    """
    # fetch from redis
    result, total, error = await redis.get_values(tag, page, page_size)
    if total and result:
        return result, total, error

    try:
        # If does not exist in redis after that search in pg
        # select count of tweets record
        q_total = db.select([func.count(Tweet.id)]).where(
            Tweet.id.in_(
                db.select([
                    TagTweet.tweet_id
                ]).where(TagTweet.tag_id == db.select([Tag.id]).where(
                    Tag.tag_name == tag))))
        total = await q_total.gino.model(Tweet).scalar()

        # If there aren't any records then return [], 0
        if not total:
            return [], total, None

        # select Tweet.id, Tweet.msg, Tweet.user_id of tweets record
        q_data = db.select(
            [Tweet.id, Tweet.msg, Tweet.user_id, Tweet.created_at]).where(
                Tweet.id.in_(
                    db.select([
                        TagTweet.tweet_id
                    ]).where(TagTweet.tag_id == db.select([Tag.id]).where(
                        Tag.tag_name == tag)))).limit(page_size).offset(
                            (page - 1) * page_size)
        result = []
        tweets = await q_data.gino.model(Tweet).all()

        for item in tweets:
            result.append(item.as_json())
            # add key and value to redis
            await redis.append_value(tag, item.as_json())

        return result, total, None
    except Exception as ex:
        global_logger.write_log('error', f"error: {ex}")
        return None, None, ex
Example #4
0
async def create_user(username, password, full_name):
    """
    create user if exist return a dictionary with user is None
    :param username: user username
    :param password: user password
    :param full_name: user full name
    :return: a dictionary which contains user dictionary and a msg
    """
    try:
        if await User.query.where(User.username == username).gino.first():
            return None, "User exists"
        user = User(username=username,
                    password=utils.hash_password(password),
                    full_name=full_name)
        await user.create()
        return user.as_json(), None
    except Exception as ex:
        global_logger.write_log('error', f"error: {ex}")
        return None, ex
Example #5
0
async def get_or_create(model, *args, **kwargs):
    """
    get or create method for using at the first create object if exist return object
    :param model: model class
    :param args: where condition
    :param kwargs: for setting model attribute to create object
    :return: model instance
    """
    try:
        if args:
            instance = await model.query.where(*args).gino.first()
        if not instance and kwargs:
            instance = model(**kwargs)
            await instance.create()
            return instance
        return instance
    except Exception as ex:
        global_logger.write_log('error', f"error: {ex}")
        return None
Example #6
0
async def get_values(key, page, page_size):
    """
    fetch values from a specific key and return as
    :param key: redis key to fetch values
    :param page: page number
    :param page_size: page size
    :return:
    """
    result = []
    total = 0
    error = None
    try:
        values = await app.redis_pool.get(key)
        if values:
            start = (page - 1) * page_size
            result = values.decode('utf-8').split(';')[:-1]
            total = len(result)
            result = [eval(item) for item in result[start:start + page_size]]
    except Exception as ex:
        global_logger.write_log('error', f"error: {ex}")
        error = ex
    finally:
        return result, total, error