Exemplo n.º 1
0
def get_message_info(message_id):
    '''
    This is a helper function.
    It will return a message with given message_id

    Args:
        param1: target message_id

    Returns:
        it will return message_info with given message_id if it exists,
        else return None to represent no such a message.
        {
            'message' : msg,
            'u_id' : msg['u_id'],
            'channel_id' : channel_id,
            'msg_list' : channel['messages'],
        }
    '''
    channel_id = int(str(message_id)[:-4])
    channel = get_channel_from_id(channel_id)
    if channel is None:
        return None
    for msg in channel['messages']:
        if msg['message_id'] == message_id:
            return {
                'message': msg,
                'u_id': msg['u_id'],
                'channel_id': channel_id,
                'msg_list': channel['messages'],
                'channel': channel,
                'reacts': msg['reacts'],
                'is_pinned': msg['is_pinned'],
            }
    return None
Exemplo n.º 2
0
def search(token, query_str):
    """
        Given a query string, return a collection of messages in all of the 
        channels that the user has joined that match that query.

        :param token: The token of an authorised Flockr user
        :type token: str

        :param u_id: The user ID of the user whose permissions we want to change
        :type u_id: int

        :return: A dictionary with nested list of messages containing
        the query string
        :rtype: dict with nested list
    """

    # check token validity
    if get_user_from_token(token) is None:
        raise AccessError(description="Unauthorised access")

    result = []
    user = get_user_from_token(token)

    # search for messages with query string
    for channel_id in user['channels']:
        channel = get_channel_from_id(channel_id)
        for message in channel['messages']:
            if query_str in message['message']:
                if user['u_id'] in message['reacts'][0]['u_ids']:
                    message['reacts'][0]['is_this_user_reacted'] = True
                else:
                    message['reacts'][0]['is_this_user_reacted'] = False
                result.append(message)

    return {'messages': result}
Exemplo n.º 3
0
def message_send_later(token, channel_id, message, time_sent):
    '''
    This function will send a message from an authorised user to the channel
    specified by channel_id automatically at a specified time in the future.

    Args:
        param1(str): authorised uesr's token
        param2(int): id of target channel
        param3(str): sent message
        param4(int): unix_timestamp, a future time

    Returns:
        It will return a dict with message_id

    Raises:
        InputError if:
            - Channel_id is invalid
            - Message is more than 1000 characters
            - Time sent is a time in the past

        AccessError if:
            - when the authorised use hasn't joined the channel
            - when given token is invalid
    '''
    ## Errors
    auth_user = get_user_from_token(token)
    channel = get_channel_from_id(channel_id)
    # access error when given token does not refer to a valid user
    if auth_user is None:
        raise AccessError(description='Invalid token')
    # input error when given channel_id is invalid
    if channel is None:
        raise InputError(description='Invalid channel.')
    # access error when the authorised use hasn't joined the channel
    if auth_user['u_id'] not in channel['all_members']:
        raise AccessError(description='User is not a member of channel.')
    # input error when message is more than 1000 characters
    if len(message) > 1000:
        raise InputError(description='Message exceeds 1000 characters.')

    ### InputError for time in past
    countdown = time_sent - int(time.time())
    if countdown < 0:
        raise InputError(description='past time given')

    ### Initiate timer for message_send function
    new_msg = create_new_msg(message, channel, auth_user['u_id'])
    channel['latest_msg_id'] += 1
    timer = threading.Timer(countdown,
                            append_msg_to_channel,
                            args=[new_msg, channel])
    timer.start()
    return {'message_id': new_msg['message_id']}
Exemplo n.º 4
0
def channel_addowner(token, channel_id, u_id):
    '''
    This will set the user with u_id as the owner of target channel.
    Token refers to one of the owner of target channel.
    It will return an empty dictionaty.

    Args:
        param1: authorised user's token.
        param2: target channel.
        param3: new owner's u_id

    Returns:
        This will return an empty dictionary.

    Raises:
        InputError:
            1. Channel ID is not a valid channel
            2. When user with user id u_id is already an owner of the channel
        AccessError:
            1. when the authorised user is not an owner of
                the flockr, or an owner of this channel
            2. given token does not refer to a valid token
    '''
    auth_user = get_user_from_token(token)
    channel = get_channel_from_id(channel_id)
    invited_user = get_user_from_id(u_id)
    # access error when the token does not refer to a valid token
    if auth_user is None:
        raise AccessError(description='Invalid token')

    # input error when Channel ID is not a valid channel
    if channel is None:
        raise InputError(description='Invalid channel_id')

    # input error when u_id does not refer to a valid user
    if invited_user is None:
        raise InputError(description='Invalid u_id')

    # input error when When user with user id u_id
    # is already an owner of the channel
    if invited_user['u_id'] in channel['owner_members']:
        raise InputError(description='Already an owner')

    # access error when the authorised user is not
    # an owner of the flockr, or an owner of this channel
    if is_user_an_owner(token, channel_id) is False:
        raise AccessError(description='Not permitted to add')

    channel['owner_members'].append(u_id)
    return {}
Exemplo n.º 5
0
def standup_send(token, channel_id, message):
    '''
    This function is for sending a message to get buffered
    in the standup queue, assuming a standup is currently active.

    Args:
        param1(str): request user's token
        param2(int): the id of target channel
        param3(str): sent message

    Returns:
        It would return an empty dict

    Raises:
        InputError:
            1. Channel ID is not a valid channel
            2. Message is more than 1000 characters
            3. An active standup is not currently running in this channel
        AccessError:
            1. given token is invalid
            2. The authorised user is not a member of the channel that the message is within
    '''
    user = get_user_from_token(token)
    channel = get_channel_from_id(channel_id)
    # access error when given token is invalid
    if user is None:
        raise AccessError(description='Invalid token')

    # input error when given channel_id is invalid
    if channel is None:
        raise InputError(description='Invalid channel_id')

    # input error when An active standup is not currently running in this channel
    if standup_active(token, channel_id)['is_active'] is False:
        raise InputError(description='No active standup')

    # input error when msg is too long
    if len(message) > 1000:
        raise InputError(description='Message is too long')

    # access error when The authorised user is not a member of
    # the channel that the message is within
    if channel_id not in user['channels']:
        raise AccessError(description='Not a member')

    channel['standup_msg'] += '\n' + user['handle'] + ': ' + message
    return {}
Exemplo n.º 6
0
def channel_detail(channel_id):
    """
        A helper function to get a channel's details from its id.

        :param channel_id: channel_id of channel whose details we want 
        :type token: int

        :return: A dictionary containing the new channel's details (id & name) as
        key value pairs 
        :rtype: dict

    """
    channel = get_channel_from_id(channel_id)
    return {
        'channel_id' : channel['channel_id'],
        'name' : channel['name'],
    }
Exemplo n.º 7
0
def channel_invite(token, channel_id, u_id):
    '''
    This will invite a user (with user id u_id) to join a channel with channel_id.
    Once invited the user is added to the channel immediately.

    Args:
        param1: invitor's token.
        param2: target channel.
        param3: invited user's u_id

    Returns:
        This will return an empty dictionary.

    Raises:
        InputError:
            1. channel_id does not refer to a valid channel.
            2. u_id does not refer to a valid user.
        AccessError:
            1. the authorised user is not already a member of the channel.
            2. given token does not refer to a valid token
    '''
    auth_user = get_user_from_token(token)
    invited_user = get_user_from_id(u_id)
    channel = get_channel_from_id(channel_id)

    # access error when given token does not refer to a valid user
    if auth_user is None:
        raise AccessError(description='Invalid Token')
    # input error when u_id does not refer to a valid user
    if invited_user is None:
        raise InputError(description='Invalid u_id')
    # input error when channel_id does not refer to a valid channel.
    if channel is None:
        raise InputError(description='Invalid channel_id')

    # accesss error when the authorised user is not a member of the channel
    if auth_user['u_id'] not in channel['all_members']:
        raise AccessError(description='Not a member')

    # invited_user is already in channel
    if invited_user['u_id'] in channel['all_members']:
        return {}

    channel['all_members'].append(u_id)
    invited_user['channels'].append(channel_id)
    return {}
Exemplo n.º 8
0
def channel_removeowner(token, channel_id, u_id):
    '''
    This will remove the user with u_id from the owners of target channel.
    If u_id refers to the owner of flockr, it will ignore the request.
    Token refers to one of the owner of target channel.
    It will return an empty dictionaty.

    Args:
        param1: authorised user's token.
        param2: target channel.
        param3: the user's u_id who is removed from owners

    Returns:
        This will return an empty dictionary.

    Raises:
        InputError:
            1. Channel ID is not a valid channel
            2. When user with user id u_id is not an owner of the channel
        AccessError:
            1. when the authorised user is not an owner of
                the flockr, or an owner of this channel
            2. given token does not refer to a valid token
    '''
    auth_user = get_user_from_token(token)
    channel = get_channel_from_id(channel_id)
    removed_user = get_user_from_id(u_id)
    # access error when given token does not refer to a valid user
    if auth_user is None:
        raise AccessError(description='Invalid token')
    # input error when Channel ID is not a valid channel
    if channel is None:
        raise InputError(description='Invalid channel_id')
    # input error when u_id does not refer to a valid user
    if removed_user is None:
        raise InputError(description='Invalid u_id')
    # input error when user with user id u_id is not an owner of the channel
    if removed_user['u_id'] not in channel['owner_members']:
        raise InputError(description='Not a owner of channel')

    # accesss error when the authorised user is not
    # an owner of the flockr, or an owner of this channel
    if is_user_an_owner(token, channel_id) is False:
        raise AccessError(description='Not permitted to remove')
    channel['owner_members'].remove(u_id)
    return {}
Exemplo n.º 9
0
def channel_details(token, channel_id):
    '''
    This will provide basic details about a channel whose Channel Id is channel_id.
    Also, the authorised user is part of that channel.

    Args:
        param1: authorised user's token.
        param2: target channel.

    Returns:
        This will return a dictionary with channel details.
        {
            'name': channel['name'],
            'owner_members': owner_details,
            'all_members': all_details,
        }

    Raises:
        InputError:
            1. channel_id does not refer to a valid channel.
            2. u_id does not refer to a valid user.
        AccessError:
            1. the authorised user is not already a member of the channel.
            2. given token does not refer to a valid token
    '''
    auth_user = get_user_from_token(token)
    channel = get_channel_from_id(channel_id)

    # access error when given token does not refer to a valid user
    if auth_user is None:
        raise AccessError(description='Invalid token')
    # inputerror when Channel ID is not a valid channel
    if channel is None:
        raise InputError(description='Invalid channel_id')
    # access error when Authorised user is not a member of channel with channel_id
    if auth_user['u_id'] not in channel['all_members']:
        raise AccessError(description='Not a member')

    return {
        'name': channel['name'],
        'owner_members': list(map(member_initial, channel['owner_members'])),
        'all_members': list(map(member_initial, channel['all_members'])),
    }
Exemplo n.º 10
0
def message_send(token, channel_id, message):
    '''
    This function will send a message from authorised_user
    to the channel specified by channel_id.
    It will create a unique msg_id for new message.
    msg_id = channel_id * 10000 + the order in that channel.
    For example, the third message in channel 6 would have a
    msg_id with 600003.

    Args:
        param1: authorised user's token
        param2: id of target channel
        param3: new message

    Returns:
        it will return a dictionary of new message id.

    Raises:
        InputError:
            Message is more than 1000 characters
        AccessError:
            1. given token does not refer to a valid user
            2. the authorised user has not joined the channel with channel_id
    '''
    auth_user = get_user_from_token(token)
    channel = get_channel_from_id(channel_id)
    # AccessError when given token does not refer to a valid user
    if auth_user is None:
        raise AccessError(description='Invalid token.')
    #InputError when message > 1000 characters
    if len(message) > 1000:
        raise InputError(description='Message exceeds 1000 characters.')
    #AccessError when user hasn't joined the channel
    if channel is None:
        raise AccessError(description='Invalid channel.')
    if auth_user['u_id'] not in channel['all_members']:
        raise AccessError(description='User is not a member of channel.')

    #Send message
    new_msg = create_new_msg(message, channel, auth_user['u_id'])
    channel['latest_msg_id'] += 1
    channel['messages'].append(new_msg)
    return {'message_id': new_msg['message_id']}
Exemplo n.º 11
0
def standup_start(token, channel_id, length):
    '''
    This function would start a standup in given channel.
    Standup would last X second and X is equal to length.
    After time is up, what is send during standup would be buffered in one message
    and be sent to given channel.
    It would return the finish_time.

    Args:
        param1(str): request user's token
        param2(int): the id of target channel
        param3(int): the time would standup last (in second)

    Returns:
        It would return a dict with one tuple 'time_finish' and its value
        is an integer (unix timestamp)

    Raises:
        InputError:
            1. Channel ID is not a valid channel
            2. An active standup is currently running in this channel
        AccessError:
            given token is invalid
    '''
    user = get_user_from_token(token)
    channel = get_channel_from_id(channel_id)
    # access error when given token is invalid
    if user is None:
        raise AccessError(description='Invalid token')
    # input error when given channel_id is invalid
    if channel is None:
        raise InputError(description='Invalid channel_id')
    # input error when an active standup is currently runing in this channel
    if standup_active(token, channel_id)['is_active'] is True:
        raise InputError(description='Standup has started')

    # reset data for standup
    channel['time_standupend'] = int(time.time()) + length
    channel['standup_msg'] = ''
    # set standup_end
    timer = threading.Timer(length, standup_end, args=[user, channel])
    timer.start()
    return {'time_finish': int(time.time()) + length}
Exemplo n.º 12
0
def channel_join(token, channel_id):
    '''
    This will add authorised user to given channel. If user is the
    owner of flockr, it will set user as onwer of that channel.

    Args:
        param1: authorised user's token.
        param2: target channel.

    Returns:
        This will return an empty dictionary.

    Raises:
        InputError:
            Channel ID is not a valid channel
        AccessError:
            1. channel_id refers to a channel that is private
                (when the authorised user is not a global owner)
            2. given token does not refer to a valid token
    '''
    auth_user = get_user_from_token(token)
    channel = get_channel_from_id(channel_id)
    # access error when the token does not refer to a valid token
    if auth_user is None:
        raise AccessError(description='Invalid token')
    # input error when Channel ID is not a valid channel
    if channel is None:
        raise InputError(description='Invalid channel_id')
    # access error when channel_id refers to a channel that is private
    # the authorised user is not a global owner
    if channel['public'] is False and auth_user['permission_id'] != 1:
        raise AccessError(description='Not permitted to join')

    # already in the channel
    if channel_id in auth_user['channels']:
        return {}

    channel['all_members'].append(auth_user['u_id'])
    auth_user['channels'].append(channel_id)
    return {}
Exemplo n.º 13
0
def standup_active(token, channel_id):
    '''
    This funciton is for getting standup active infomation.
    For a given channel, return whether a standup is active in it,
    and what time the standup finishes.
    If no standup is active, then time_finish returns None.

    Args:
        param1(str): request user's token
        param2(int): the id of target channel

    Returns:
        It would return a dict containing relative info
        'is_active' (boolean) true if standup is active, else false
        'time_finish' (int unix timestamp) the time when the standup is finished

    Raises:
        InputError:
            1. Channel ID is not a valid channel
        AccessError:
            1. given token is invalid
    '''
    user = get_user_from_token(token)
    channel = get_channel_from_id(channel_id)
    # access error when given token is invalid
    if user is None:
        raise AccessError(description='Invalid token')
    # input error when given channel_id is invalid
    if channel is None:
        raise InputError(description='Invalid channel_id')

    if channel['time_standupend'] == 0:
        return {
            'is_active': False,
            'time_finish': None,
        }
    return {
        'is_active': True,
        'time_finish': channel['time_standupend'],
    }
Exemplo n.º 14
0
def channel_leave(token, channel_id):
    '''
    This will remove authorised user from given channel.
    If the last user of that channel leaves, we will keep that channel in data.

    Args:
        param1: authorised user's token.
        param2: target channel.

    Returns:
        This will return an empty dictionary.

    Raises:
        InputError:
            Channel ID is not a valid channel
        AccessError:
            1. Authorised user is not a member of channel with channel_id
            2. given token does not refer to a valid token
    '''
    auth_user = get_user_from_token(token)
    channel = get_channel_from_id(channel_id)
    # access error when the token does not refer to a valid token
    if auth_user is None:
        raise AccessError(description='Invalid token')
    # input error when Channel ID is not a valid channel
    if channel is None:
        raise InputError(description='Invalid channel_id')
    # access error when Authorised user is not a member of channel with channel_id
    if auth_user['u_id'] not in channel['all_members']:
        raise AccessError(description='Not a member')

    auth_user['channels'].remove(channel_id)
    channel['all_members'].remove(auth_user['u_id'])
    if auth_user['u_id'] in channel['owner_members']:
        channel['owner_members'].remove(auth_user['u_id'])
    return {}
Exemplo n.º 15
0
def channel_messages(token, channel_id, start):
    '''
    This will return a list of messages from [start] of
    channel with channel_id. It contains up to 50 messages between
    index "start" and "start + 50". Message with index 0 is the most
    recent message in the channel. This function returns a new index "end"
    which is the value of "start + 50", or, if this function has returned
    the least recent messages in the channel, returns -1 in "end" to indicate
    there are no more messages to load after this return.

    Args:
        param1: authorised user's token.
        param2: target channel.
        param3: start index of messages

    Returns:
        This will return a dictionary.
        {
            'messages' : (a list of messages),
            'start' : (start index),
            'end' : (end index),
        }

    Raises:
        InputError:
            1. channel_id does not refer to a valid channel.
            2. start is greater than the total number of messages in the channel.
        AccessError:
            1. Authorised user is not a member of channel with channel_id.
            2. given token does not refer to a valid token
    '''
    auth_user = get_user_from_token(token)
    channel = get_channel_from_id(channel_id)
    # access error when given token does not refer to a valid user
    if auth_user is None:
        raise AccessError(description='Invalid token')
    # input error when Channel ID is not a valid channel
    if channel is None:
        raise InputError(description='Invalid channel_id')

    all_msgs = list(reversed(channel['messages']))
    # input error when start is greater than the total number
    # of messages in the channel
    if start > len(all_msgs):
        raise InputError(description='Invalid start index')

    # access error when Authorised user is not a member of channel with channel_id
    if auth_user['u_id'] not in channel['all_members']:
        raise AccessError(description='Not a member')

    return_messages = []
    end = start + 50
    if end >= len(all_msgs):
        end = -1
        for msg in all_msgs[start:]:
            if auth_user['u_id'] in msg['reacts'][0]['u_ids']:
                msg['reacts'][0]['is_this_user_reacted'] = True
            else:
                msg['reacts'][0]['is_this_user_reacted'] = False
            return_messages.append(msg)
    else:
        for msg in all_msgs[start:end]:
            if auth_user['u_id'] in msg['reacts'][0]['u_ids']:
                msg['reacts'][0]['is_this_user_reacted'] = True
            else:
                msg['reacts'][0]['is_this_user_reacted'] = False
            return_messages.append(msg)
    return {
        'messages': return_messages,
        'start': start,
        'end': end,
    }