예제 #1
0
def channel_leave(token, channel_id):
    '''
    User leaves a channel.

    Parameters:
        token -
        channel_id -

    Returns: {}

    Errors:
        InputError:
            Invalid channel id.
        AccessError:
            User is not inside channel.
    '''
    check_token(token)
    data = get_data()
    if not find_id_in_list(data['channels'], channel_id, 'channel_id'):
        raise InputError(description='Channel does not exist')

    current_channel = data['channels'][channel_id - 1]
    target_u_id = get_user_from_token(token)
    if find_id_in_list(current_channel['all_members'], target_u_id, 'u_id'):
        target = get_user_data(target_u_id)
        user_info = {
            'u_id': target['u_id'],
            'name_first': target['name_first'],
            'name_last': target['name_last'],
        }
        data['channels'][channel_id - 1]['all_members'].remove(user_info)
        return {}
    # the authorised user is not a member of channel with channel_id
    raise AccessError(
        description='The authorised user is not a member of this channel')
예제 #2
0
def message_sendlater(token, channel_id, message, time_sent):
    '''
    Send a message from authorised_user to the channel \
         specified by channel_id automatically at a specified time in the future

    Parameters:
        token - The user's token that was generated from their user id
        channel_id - The id of the channel the user wishes to message
        message - The message the user wishes to send
        time_sent

    Returns:
        A dictionary containing a bool is_sucess

    Errors:
        InputError:
            Channel ID is not a valid channel
            Message is more than 1000 characters
            Time sent is a time in the past
        AccessError:
            The authorised user has not joined the channel they are trying to post to
    '''
    check_token(token)
    data = get_data()
    #check channel exist
    if not find_id_in_list(data['channels'], channel_id, 'channel_id'):
        raise InputError(description="Channel does not exist")
    if len(message) > 1000:
        raise InputError(description="Message is too long")
    curr_time = datetime.utcnow()
    time_stamp = int(time.mktime(curr_time.timetuple()))
    if time_sent < time_stamp:
        raise InputError(description="Cannot send messages in the past")
    curr_channel = data['channels'][int(channel_id) - 1]
    u_id = get_user_from_token(token)
    if not find_id_in_list(curr_channel['all_members'], u_id, 'u_id'):
        raise AccessError("Cannot send messages in channels you're not in")
    message_id = get_max_msg_id() + 1
    new_message = {
        'u_id': u_id,
        'channel_id': channel_id,
        'message_id': message_id,
        'message': message,
        'time_created': time_sent,
        'send_later': True,
        'react': [],
        'is_pinned': False
    }
    curr_time = datetime.utcnow()
    time_stamp = int(time.mktime(curr_time.timetuple()))
    timer = threading.Timer(time_sent - time_stamp,
                            data['messages'].insert(0, new_message))
    timer.start()
    return {"message_id": new_message['message_id']}
예제 #3
0
def message_react(token, message_id, react_id):
    '''
    Given a message within a channel the authorised user is part of, add a "react" to \
        that particular message

    Parameters:
        token - The user's token that was generated from their user id
        message_id - The id of the message to be reacted to
        react_id - What type of reaction is shown

    Returns:
        An empty dictionary

    Errors:
        InputError:
            Message_id is not a valid message within a channel that the authorised user has joined
            React_id is not a valid React ID. The only valid react ID the frontend has is 1
            Message with ID message_id already contains an active React with ID react_id \
                from the authorised user
    '''
    check_token(token)
    data = get_data()
    # The only valid react ID the frontend has is 1
    if react_id != 1:
        raise InputError(description="Invalid React ID")
    if not find_id_in_list(data['messages'], message_id, 'message_id'):
        raise InputError(
            description="Message_id is not a valid message within a \
            channel that the authorised user has joined")
    for message in data['messages']:
        if message['message_id'] == message_id:
            msg = message
    u_id = get_user_from_token(token)
    channel_id = msg['channel_id']
    curr_channel = data['channels'][channel_id - 1]
    if not find_id_in_list(curr_channel['all_members'], u_id, 'u_id'):
        raise InputError(
            description="Message_id is not a valid message within a \
            channel that the authorised user has joined")
    # check if user has already reacted
    for react in msg['react']:
        if react['u_id'] == u_id:
            raise InputError(
                description="User has already reacted to this message")
    new_react = {'react_id': react_id, 'u_id': u_id}
    for message in data['messages']:
        if message['message_id'] == message_id:
            message['react'].append(new_react)
    return {}
예제 #4
0
def standup_active(token, channel_id):
    '''
    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

    Parameters:
        token - The user's token that was generated from their user id
        channel_id - The id of the channel

    Returns:
        A dictionary containing the time the standup will finish and whether a
        standup is active

    Errors:
        InputError:
            Channel ID is not a valid channel
    '''
    check_token(token)
    data = get_data()
    # Check if channel_id is valid
    if not find_id_in_list(data['channels'], channel_id, 'channel_id'):
        raise InputError(description="Channel ID is not a valid channel")
    curr_time = datetime.utcnow()
    time_stamp = int(curr_time.replace(tzinfo=timezone.utc).timestamp())
    standup = data['standup']
    if time_stamp > standup['time_finish'] or standup['channel_id'] != channel_id:
        is_active = False
        time_finish = None
    else:
        is_active = True
        time_finish = standup['time_finish']
    return {
        'is_active': is_active,
        'time_finish': time_finish
    }
예제 #5
0
def channel_join(token, channel_id):
    '''
    User joins a channel.

    Parameters:
        token -
        channel_id -

    Returns: {}

    Errors:
        InputError:
            Invalid channel id.
        AccessError:
            Channel is private.
    '''
    check_token(token)
    data = get_data()
    if not find_id_in_list(data['channels'], channel_id, 'channel_id'):
        # Channel ID is not a valid channel
        raise InputError(description='Channel does not exist')
    current_channel = data['channels'][channel_id - 1]

    target_u_id = get_user_from_token(token)
    target = get_user_data(target_u_id)
    if not current_channel['is_public'] and target['permission_id'] != 1:
        raise AccessError(description='Private channel')
    user_info = {
        'u_id': target['u_id'],
        'name_first': target['name_first'],
        'name_last': target['name_last'],
    }
    data['channels'][channel_id - 1]['all_members'].append(user_info)
    return {}
예제 #6
0
def channels_listall(token):
    '''
    Provide a list of all channels (and their associated details)

    Parameters:
        token - The user's token that was generated from their user id

    Returns:
        A dictionary containing a list of channels that are public or the user is
        in

    Errors:
    '''
    check_token(token)
    data = get_data()
    c_list = []
    u_id = get_user_from_token(token)
    # Iterating through the list of channels
    for channel in data['channels']:
        # If the user is in the channel append the channel to the list
        if find_id_in_list(channel['all_members'], u_id,
                           'u_id') or channel['is_public']:
            current_channel = {
                'channel_id': channel['channel_id'],
                'name': channel['name'],
            }
            c_list.append(current_channel)
    return {'channels': c_list}
예제 #7
0
def standup_send(token, channel_id, message):
    '''
    Sending a message to get buffered in the standup queue, assuming a standup is
    currently active

    Parameters:
        token - The user's token that was generated from their user id
        channel_id - The id of the channel
        message - The message being sent

    Returns:
        A dictionary containing the time the standup will finish and whether a
        standup is active

    Errors:
        InputError:
            Channel ID is not a valid channel
            Message is more than 1000 characters
            An active standup is not currently running in this channel
        AccessError:
            The authorised user is not a member of the channel that the message is within
    '''
    check_token(token)
    data = get_data()
    # Check if channel_id is valid
    if not find_id_in_list(data['channels'], channel_id, 'channel_id'):
        raise InputError(description="Channel ID is not a valid channel")
    # Check if the message is too long
    if len(message) > 1000:
        raise InputError(description="Message is more than 1000 characters")
    # Check if a standup is already active
    if not standup_active(token, channel_id)['is_active']:
        raise InputError(description="An active standup is not currently running in this channel")
    # Check if the user is in the channel
    u_id = get_user_from_token(token)
    curr_channel = data['channels'][channel_id - 1]
    if not find_id_in_list(curr_channel['all_members'], u_id, 'u_id'):
        raise AccessError(description="The authorised user is not a member of the \
        channel that the message is within")
    # Appending the packaged message
    for user in data['users']:
        if user['u_id'] == u_id:
            handle_str = user['handle_str']
    data['standup']['buffer'].append(handle_str + ': ' + message)
    data['standup']['message'] = '\n'.join(data['standup']['buffer'])
    return {
    }
예제 #8
0
def channel_addowner(token, channel_id, u_id):
    '''
    Add a member of channel to owner list.

    Parameters:
        token -
        channel_id -
        u_id -

    Returns: {}

    Errors:
        InputError:
            Invalid channel id.
            User is already an owner.
        AccessError:
            The authorised person is not an owner of channel or owner of slackr.
    '''
    check_token(token)
    data = get_data()
    if not find_id_in_list(data['channels'], channel_id, 'channel_id'):
        raise InputError(description='Channel does not exist')

    current_channel = data['channels'][channel_id - 1]
    if find_id_in_list(current_channel['owner_members'], u_id, 'u_id'):
        raise InputError(
            description='User is already an owner of this channel')

    person_u_id = get_user_from_token(token)
    person = get_user_data(person_u_id)
    person_is_owner = find_id_in_list(current_channel['owner_members'],
                                      person_u_id, 'u_id')
    person_in_channel = find_id_in_list(current_channel['all_members'],
                                        person_u_id, 'u_id')
    if person_is_owner or (person_in_channel and person['permission_id'] == 1):
        target = get_user_data(u_id)
        user_info = {
            'u_id': target['u_id'],
            'name_first': target['name_first'],
            'name_last': target['name_last'],
        }
        data['channels'][channel_id - 1]['owner_members'].append(user_info)
        if not find_id_in_list(current_channel['all_members'], u_id, 'u_id'):
            data['channels'][channel_id - 1]['all_members'].append(user_info)
        return {}
    raise AccessError(description='The authorised person has no permission')
예제 #9
0
def message_pin(token, message_id):
    '''
    Given a message within a channel, mark it as "pinned" to be given special display treatment\
         by the frontend

    Parameters:
        token - The user's token that was generated from their user id
        message_id - The message id which the user wishes to pin

    Returns:
        An empty dictionary

    Errors:
        InputError:
            Message_id is not a valid message
            Message with ID message_id is already pinned
        AccessError:
            The authorised user is not a member of the channel that the message is within
            The authorised user is not an owner
    '''
    check_token(token)
    data = get_data()
    if not find_id_in_list(data['messages'], message_id, 'message_id'):
        raise InputError(description="Message does not exist")
    # msg exists
    for message in data['messages']:
        if message['message_id'] == message_id:
            msg = message
    if msg['is_pinned']:
        raise InputError(description="This message is already pinned")
    u_id = get_user_from_token(token)
    user = data['users'][u_id - 1]
    for channel in data['channels']:
        if not find_id_in_list(channel['all_members'], u_id, 'u_id'):
            raise AccessError(
                description='The authorised user is not in this channel')
        else:
            curr_channel = channel
    if find_id_in_list(curr_channel['owner_members'], u_id,
                       'u_id') or user['permission_id'] == 1:
        msg['is_pinned'] = True
        return {}
    raise InputError(
        description="The authorised user does not have owner priveledge \
        to pin message in this channel")
예제 #10
0
def message_unreact(token, message_id, react_id):
    '''
    Given a message within a channel the authorised user is part of, remove a "react" to \
        that particular message

    Parameters:
        token - The user's token that was generated from their user id

    Returns:
        An empty dictionary

    Errors:
        InputError:
            Message_id is not a valid message within a channel that the authorised user has joined
            React_id is not a valid React ID
            Message with ID message_id does not contain an active React with ID react_id
    '''
    check_token(token)
    data = get_data()
    if react_id != 1:
        raise InputError(description="Invalid React ID")
    if not find_id_in_list(data['messages'], message_id, 'message_id'):
        raise InputError(
            description="Message_id is not a valid message within a \
            channel that the authorised user has joined")
    for message in data['messages']:
        if message['message_id'] == message_id:
            msg = message
    u_id = get_user_from_token(token)
    channel_id = msg['channel_id']
    curr_channel = data['channels'][channel_id - 1]
    if not find_id_in_list(curr_channel['all_members'], u_id, 'u_id'):
        raise InputError(
            description="Message_id is not a valid message within a \
            channel that the authorised user has joined")
    # check if user has already reacted
    for react in msg['react']:
        if react['u_id'] == u_id:
            for message in data['messages']:
                if message['message_id'] == message_id:
                    message['react'].remove(react)
                    return {}
    raise InputError(description="User has not reacted to this message")
예제 #11
0
def message_unpin(token, message_id):
    '''
    Given a message within a channel, remove it's mark as unpinned

    Parameters:
        token - The user's token that was generated from their user id
        message_id - The id of the message to be unpinnned

    Returns:
        An empty dictionary

    Errors:
        InputError:
            Message_id is not a valid message
            Message with ID message_id is already unpinned
        AccessError:
            The authorised user is not a member of the channel that the message is within
            The authorised user is not an owner
    '''
    check_token(token)
    data = get_data()
    if not find_id_in_list(data['messages'], message_id, 'message_id'):
        raise InputError(description="Message does not exist")
    for message in data['messages']:
        if message['message_id'] == message_id:
            msg = message
    if not msg['is_pinned']:
        raise InputError(description="This message is not pinned")
    u_id = get_user_from_token(token)
    user = data['users'][u_id - 1]
    for channel in data['channels']:
        if not find_id_in_list(channel['all_members'], u_id, 'u_id'):
            raise AccessError(
                description='The authorised user is not in this channel')
        else:
            curr_channel = channel
    if find_id_in_list(curr_channel['owner_members'], u_id,
                       'u_id') or user['permission_id'] == 1:
        msg['is_pinned'] = False
        return {}
    raise InputError(
        description="The authorised user does not have owner priveledge \
        to unpin message in this channel")
예제 #12
0
def message_edit(token, message_id, message):
    '''
    Given a message, update it's text with new text. If the new message is an empty string, \
        the message is deleted.

    Parameters:
        token - The user's token that was generated from their user id
        message_id - The id of the message to be edited
        message - The edits to be made

    Returns:
        An empty dictionary

    Errors:
        AccessError when none of the following are true:
        Message with message_id was sent by the authorised user making this request
        The authorised user is an owner of this channel or the slackr
    '''
    check_token(token)
    data = get_data()
    if not find_id_in_list(data['messages'], message_id, 'message_id'):
        raise InputError(description="Message does not exist")
    for item in data['messages']:
        if item['message_id'] == message_id:
            msg = item
    u_id = get_user_from_token(token)
    user = data['users'][u_id - 1]
    channel_id = msg['channel_id']
    curr_channel = data['channels'][channel_id - 1]
    is_owner = find_id_in_list(curr_channel['owner_members'], u_id, 'u_id')
    if msg['u_id'] == u_id or user['permission_id'] == 1 or is_owner:
        if message is None:
            message_remove(token, message_id)
            return {}
        for item in data['messages']:
            if item['message_id'] == message_id:
                item['message'] = message
                return {}
    raise AccessError(
        description=
        'The authorised user does not have privilege to edit message')
예제 #13
0
def message_remove(token, message_id):
    '''
    Given a message_id for a message, this message is removed from the channel

    Parameters:
        token - The user's token that was generated from their user id
        message_id - Id of the message the user wishes to remove

    Returns:
        An empty dictionary

    Errors:
        InputError:
            Message (based on ID) no longer exists
        AccessError when none of the following are true:
            Message with message_id was sent by the authorised user making this request
            The authorised user is an owner of this channel or the slackr
    '''
    check_token(token)
    data = get_data()
    # Check if message exists
    if not find_id_in_list(data['messages'], message_id, 'message_id'):
        raise InputError(description="Message no longer exists")
    u_id = get_user_from_token(token)
    for message in data['messages']:
        if message['message_id'] == message_id:
            channel_id = message['channel_id']
            curr_channel = data['channels'][channel_id - 1]
            user = data['users'][u_id - 1]
            is_owner = find_id_in_list(curr_channel['owner_members'], u_id,
                                       'u_id')
            if message['u_id'] == u_id or is_owner or user[
                    'permission_id'] == 1:
                data['messages'].remove(message)
                return {}
    raise AccessError(
        description="You did not send this message or are not an owner")
예제 #14
0
def message_send(token, channel_id, message):
    '''
    Send a message from authorised_user to the channel specified by channel_id

    Parameters:
        token - The user's token that was generated from their user id
        channel_id - The id the user wishes to message
        message - The message the user wishes to send

    Returns:
        A dictionary containing a message_id

    Errors:
        InputError:
            Message is more than 1000 characters
        AccessError:
           The authorised user has not joined the channel they are trying to post to
    '''
    # Check if user is valid
    check_token(token)
    # Check if message is too long
    if len(message) > 1000:
        raise InputError(description="Message is too long")
    data = get_data()
    u_id = get_user_from_token(token)
    # Find the channel with channel_id
    curr_channel = data['channels'][channel_id - 1]
    # Check if user is in this channel
    if not find_id_in_list(curr_channel['all_members'], u_id,
                           'u_id') and u_id != 0:
        raise AccessError(description="User is not in channel")
    # Get the time when message is sent
    curr_time = datetime.utcnow()
    timestamp = curr_time.replace(tzinfo=timezone.utc).timestamp()
    # Get message id based on the lastest (max) message id
    message_id = get_max_msg_id() + 1
    new_message = {
        'u_id': u_id,
        'channel_id': channel_id,
        'message_id': message_id,
        'message': message,
        'time_created': timestamp,
        'send_later': False,
        'react': [],
        'is_pinned': False
    }
    # insert new message to the start of list
    data['messages'].insert(0, new_message)
    return {'message_id': message_id}
예제 #15
0
def channel_invite(token, channel_id, u_id):
    '''
    Invite someone to this channel.

    Parameters:
        token -
        channel_id -
        u_id -

    Returns: {}

    Errors:
        InputError:
            Invalid channel id, Invalid u_id.
        AccessError:
            The authorised person is not inside this channel.
    '''
    check_token(token)
    data = get_data()

    if not find_id_in_list(data['channels'], channel_id, 'channel_id'):
        raise InputError(description='Channel does not exist')
    if u_id > get_max_u_id() or u_id <= 0:
        raise InputError(description='u_id does not refer to a valid user')

    current_channel = data['channels'][channel_id - 1]
    person_u_id = get_user_from_token(token)
    # Check if authorised person is in channel with channel_id
    for user in current_channel['all_members']:
        if user['u_id'] == person_u_id:
            target = get_user_data(u_id)
            user_info = {
                'u_id': target['u_id'],
                'name_first': target['name_first'],
                'name_last': target['name_last'],
            }
            data['channels'][channel_id - 1]['all_members'].append(user_info)
            return {}
    # the authorised user is not already a member of the channel
    raise AccessError(
        description='The authorised user is not a member of this channel')
예제 #16
0
def standup_start(token, channel_id, length):
    '''
    For a given channel, start the standup period whereby for the next "length"
    seconds if someone calls "standup_send" with a message, it is buffered during
    the X second window then at the end of the X second window a message will be
    added to the message queue in the channel from the user who started the standup.
    X is an integer that denotes the number of seconds that the standup occurs for

    Parameters:
        token - The user's token that was generated from their user id
        channel_id - The id of the channel
        length - The length of time in seconds that the standup will last for

    Returns:
        A dictionary containing the time the standup will finish

    Errors:
        InputError:
            Channel ID is not a valid channel
            An active standup is currently running in this channel
    '''
    check_token(token)
    data = get_data()
    # Check if channel_id is valid
    if not find_id_in_list(data['channels'], channel_id, 'channel_id'):
        raise InputError(description="Channel ID is not a valid channel")
    # Check if a standup is already active
    if standup_active(token, channel_id)['is_active']:
        raise InputError(description="An active standup is currently running in this channel")

    standup = data['standup']
    standup['u_id'] = get_user_from_token(token)
    standup['channel_id'] = channel_id
    curr_time = datetime.utcnow()
    time_stamp = int(curr_time.replace(tzinfo=timezone.utc).timestamp())
    standup['time_finish'] = time_stamp + length
    timer = threading.Timer(length, send_standup_package)
    timer.start()
    return {
        'time_finish': standup['time_finish']
    }
예제 #17
0
def channel_details(token, channel_id):
    '''
    Show details to a user.

    Parameters:
        token -
        channel_id -

    Returns: a dict including channel name, owner member list, and member list.

    Errors:
        InputError:
            Invalid channel id.
        AccessError:
            The authorised person is not inside this channel.
    '''
    check_token(token)
    data = get_data()

    if not find_id_in_list(data['channels'], channel_id, 'channel_id'):
        raise InputError(description='Channel does not exist')
    current_channel = data['channels'][channel_id - 1]
    person_u_id = get_user_from_token(token)
    for user in current_channel['all_members']:
        if user['u_id'] == person_u_id:
            for member in current_channel['all_members']:
                info = get_user_data(user['u_id'])
                member['profile_img_url'] = info['profile_img_url']
            # Output { name, owner_members, all_members }
            details = {
                'name': current_channel['name'],
                'owner_members': current_channel['owner_members'],
                'all_members': current_channel['all_members'],
            }
            return details
    raise AccessError(
        description='he authorised user is not a member of this channel')
예제 #18
0
def channel_messages(token, channel_id, start):
    '''
    Show message list inside channel to user.

    Parameters:
        token -
        channel_id -
        start -

    Returns:
    {
        'messages': msg_list,
        'start': start,
        'end': end
    }

    Errors:
        InputError:
            Invalid channel id.
            Start is greater than the total number of messages inside channel.
        AccessError:
            User is not inside channel.
    '''
    check_token(token)
    data = get_data()
    if not find_id_in_list(data['channels'], channel_id, 'channel_id'):
        # Channel ID is not a valid channel
        raise InputError(description='Channel does not exist')
    msg_list = []
    curr_time = datetime.utcnow()
    timestamp = curr_time.replace(tzinfo=timezone.utc).timestamp()
    for message in data['messages']:
        if message['channel_id'] == channel_id and message[
                'time_created'] < timestamp:
            tmp_message = {
                'message_id': message['message_id'],
                'u_id': message['u_id'],
                'message': message['message'],
                'time_created': message['time_created']
            }
            msg_list.append(tmp_message)
    msg_list.sort(key=itemgetter('time_created'), reverse=True)
    num_of_messages = len(msg_list)
    start = int(start)
    if start > num_of_messages or start < 0:
        # start is greater than the total number of messages in the channel
        raise InputError(description='Start exceed limit')
    person_u_id = get_user_from_token(token)
    current_channel = data['channels'][channel_id - 1]
    if find_id_in_list(current_channel['all_members'], person_u_id, 'u_id'):
        if start + 49 > num_of_messages:
            end = -1
            msg_list = msg_list[start:]
        # Output { messages, start, end}
        else:
            end = start + 49
            msg_list = msg_list[start:end]
        return {'messages': msg_list, 'start': start, 'end': end}
    # the authorised user is not a member of channel with channel_id
    raise AccessError(
        description='The authorised user is not a member of this channel')