Beispiel #1
0
def user_remove():
    '''admin removes a user from slackr'''
    data = get_data()
    payload = request.get_json()
    token = payload['token']
    u_id = int(payload['u_id'])
    check_token(token)

    user_data = get_user_data(u_id)
    if user_data == {}:
        raise InputError(description='No such user exists')
    person_u_id = get_user_from_token(token)
    person_data = get_user_data(person_u_id)
    if person_data['permission_id'] != 1:
        raise AccessError(description='The authorised person is not an owner of slackr')
    user_info = {
        'u_id': u_id,
        'name_first': user_data['name_first'],
        'name_last': user_data['name_last'],
    }
    for channel in data['channels']:
        if user_info in channel['owner_members']:
            curr_channel_id = channel['channel_id']
            data['channels'][curr_channel_id - 1]['owner_members'].remove(user_info)
            data['channels'][curr_channel_id - 1]['all_members'].remove(user_info)
        elif user_info in channel['all_members']:
            curr_channel_id = channel['channel_id']
            data['channels'][curr_channel_id - 1]['all_members'].remove(user_info)
    dumps({})
Beispiel #2
0
def user_profile_setemail(token, email):
    '''
    Update the authorised user's email address

    Parameters:
        token - The user's token that was generated from their user id
        email - The email the user wants to change to

    Returns:
        An empty dictionary

    Errors:
        InputError:
            The email is an invalid email
            The email has already been taken by another user
    '''
    check_token(token)
    data = get_data()
    # Checking if the email is valid
    if not check(email):
        raise InputError(description="Invalid email")
    # Checking if email is taken
    for user in data['users']:
        if user['email'] == email:
            raise InputError(description="Email is already taken")
    # Setting the email
    u_id = get_user_from_token(token)
    for user in data['users']:
        if user['u_id'] == u_id:
            user['email'] = email
    return {
    }
Beispiel #3
0
def user_profile_sethandle(token, handle_str):
    '''
    Update the authorised user's handle (i.e. display name)

    Parameters:
        token - The user's token that was generated from their user id
        handle_str - The handle the user wants to change to

    Returns:
        An empty dictionary

    Errors:
        InputError:
            The handle name is greater than 20 characters
            The handle name is less than 2 characters
    '''
    check_token(token)
    data = get_data()
    # Checking if the handle is too long or short
    if len(handle_str) > 20:
        raise InputError(description="Handle is too long. Maximum characer length 20.")
    if len(handle_str) < 2:
        raise InputError(description="Handle is too short. Minimum character length 2.")
    #Check if handle is already taken by another user
    for user in data['users']:
        if user['handle_str'] == handle_str:
            raise InputError(description="Handle is already taken")
    # Setting the handle
    u_id = get_user_from_token(token)
    for user in data['users']:
        if user['u_id'] == u_id:
            user['handle_str'] = handle_str
    return {
    }
Beispiel #4
0
def user_profile(token, u_id):
    '''
    For a valid user, returns information about their
    user id, email, first name, last name, handle, and image profile URL

    Parameters:
        token - The user's token that was generated from their user id
        u_id - The profile id number to be checked

    Returns:
        An dictionary containing all the users information

    Errors:
        InputError:
            Given a u_id for a non-existent user
    '''
    check_token(token)
    data = get_data()
    # Finding the user
    for user in data['users']:
        if user['u_id'] == u_id:
            profile = {
                'u_id': u_id,
                'email': user['email'],
                'name_first': user['name_first'],
                'name_last': user['name_last'],
                'handle_str': user['handle_str'],
                'profile_img_url': user['profile_img_url']
            }
            return {
                'user': profile
            }
    # If u_id hasn't been found then it is obviously invalid
    raise InputError(description="Invalid u_id")
Beispiel #5
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}
Beispiel #6
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
    }
Beispiel #7
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 {}
Beispiel #8
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')
Beispiel #9
0
def users_all(token):
    '''
    Returns a list of all users and their associated details

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

    Returns:
        A dictionary containing a list of users

    Errors:
    '''
    check_token(token)
    data = get_data()
    u_list = []
    # Adds all the users in data to u_list
    for user in data['users']:
        current_user = {
            'u_id': user['u_id'],
            'email': user['email'],
            'name_first': user['name_first'],
            'name_last': user['name_last'],
            'handle_str': user['handle_str'],
            'profile_img_url': user['profile_img_url'],
        }
        u_list.append(current_user)
    return {
        'users': u_list
    }
Beispiel #10
0
def user_profile_setname(token, name_first, name_last):
    '''
    Update the authorised user's first and last name

    Parameters:
        token - The user's token that was generated from their user id
        handle_str - The handle the user wants to change to

    Returns:
        An empty dictionary

    Errors:
        InputError:
            Either name is greater than 50 characters
            Either name is less than 1 characters
    '''
    check_token(token)
    data = get_data()
    # Checking if the name is too long or short
    if len(name_first) > 50 or len(name_last) > 50:
        raise InputError(description="Name is too long. Maximum characer length 50.")
    if len(name_first) < 1 or len(name_last) < 1:
        raise InputError(description="Name is too short. Minimum character length 1.")
    # Setting the name
    u_id = get_user_from_token(token)
    for user in data['users']:
        if user['u_id'] == u_id:
            user['name_first'] = name_first
            user['name_last'] = name_last
    return {
    }
Beispiel #11
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']}
Beispiel #12
0
def auth_logout(token):
    '''This program logs a user out'''
    check_token(token)
    data = get_data()
    u_id = get_user_from_token(token)
    for user in data['users']:
        if user['u_id'] == u_id:
            # Set the specified users login flag to 0 to log them off
            if user['logged_in'] == 1:
                user['logged_in'] = 0
                return {'is_success': True}
    return {'is_success': False}
Beispiel #13
0
def user_profile_uploadphoto(token, img_url, x_start, y_start, x_end, y_end):
    '''
    Given a URL of an image on the internet, crops the image within bounds
    (x_start, y_start) and (x_end, y_end). Position (0,0) is the top left

    Parameters:
        token - The user's token that was generated from their user id
        img_url - The url containing the image the user wants to upload as their profile picture
        x_start - The left side of the area the user wishes to crop the photo at the url
        x_end - The right side of the area the user wishes to crop the photo at the url
        y_start - The top of the area the user wishes to crop the photo at the url
        y_end - The bottom of the area the user wishes to crop the photo at the url

    Returns:
        An empty dictionary

    Errors:
        InputError:
            The img_url returns a non 200 response
            The image at the url is not a jpg
            The start values for the crop are greater then or equal to then end values
            One of the values given for the crop are outside the bounds of the photo
    '''
    check_token(token)
    data = get_data()
    if not os.path.exists('static/images'):
        os.makedirs('static/images')
    filename = 'images/' + uuid.uuid4().hex + '.jpg'
    response = requests.get(img_url)
    if not response.status_code == 200:
        raise InputError(description="img_url does not return a 200 status code")
    urllib.request.urlretrieve(img_url, 'static/' + filename)
    img = Image.open(BytesIO(response.content))
    if img.format != ('JPEG' or 'JPG' or 'jpg' or 'jpeg'):
        raise InputError(description="Image is not a JPG")
    width, height = img.size
    if x_start >= x_end or y_start >= y_end:
        raise InputError(description="End coordinates must be greater that start coordinates ")
    if  ((x_start or y_start or x_end or y_end) < 0 or
         (x_start or x_end) > width or (y_start or y_end) > height):
        raise InputError(description="Crop is not within the bounds of the image")
    area = (x_start, y_start, x_end, y_end)
    img = img.crop(area)
    img.save('static/' + filename)
    u_id = get_user_from_token(token)
    img_url = url_for('static', filename=filename, _external=True)
    for user in data['users']:
        if user['u_id'] == u_id:
            user['profile_img_url'] = img_url
    return {
    }
Beispiel #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}
Beispiel #15
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 {}
Beispiel #16
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 {
    }
Beispiel #17
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')
Beispiel #18
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")
Beispiel #19
0
def userpermission_change():
    '''admian change user's permission id'''
    data = get_data()
    payload = request.get_json()
    token = payload['token']
    check_token(token)
    u_id = int(payload['u_id'])
    permission_id = int(payload['permission_id'])
    if u_id is None or permission_id is None:
        raise InputError(description='Empty input')
    if permission_id != 1 and permission_id != 2:
        raise InputError(description='Invalid permission id')
    if get_user_data(u_id) == {}:
        raise InputError(description='No such user exists')
    for user in data['users']:
        if user['u_id'] == u_id:
            user['permission_id'] = permission_id
    return dumps({})
Beispiel #20
0
def channels_create(token, name, is_public):
    '''
    Creates a new channel with that name that is either a public or private channel

    Parameters:
        token - The user's token that was generated from their user id
        name - The name of the channel being created
        is_public - A boolean of whether the channel is public or private

    Returns:
        A dictionary containing the channel_id of the new channel

    Errors:
        InputError:
            The channel name is over 20 characters
    '''
    check_token(token)
    # Raising an error
    if len(name) > 20:
        raise InputError(description='Name is over 20 characters')
    # Getting the channel_id
    data = get_data()
    channel_id = len(data['channels']) + 1
    u_id = get_user_from_token(token)
    # Getting the user details
    for user in data['users']:
        if user['u_id'] == u_id:
            current_user = user
    creator = {
        'u_id': current_user['u_id'],
        'name_first': current_user['name_first'],
        'name_last': current_user['name_last'],
    }

    # Creating a new channel in the class
    new_channel = {
        'name': name,
        'is_public': is_public,
        'owner_members': [creator],
        'all_members': [creator],
        'channel_id': channel_id
    }
    data['channels'].append(new_channel)
    return {'channel_id': channel_id}
Beispiel #21
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")
Beispiel #22
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")
Beispiel #23
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')
Beispiel #24
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']
    }
Beispiel #25
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')
Beispiel #26
0
def start_game(token, channel_id):
    '''
    Start the game, initialise hangman package for this channel, add package to the database

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

    Returns:
        A message ready to be posted by hangman bot

    Errors:
    '''
    # check if user is valid
    check_token(token)
    # check if the game is already active
    data = get_data()
    for package in data['hangman']:
        if package['channel_id'] == channel_id:
            if package['is_active'] is True:
                raise AccessError(
                    description=
                    'There is already an active game in this channel.')
            # delete/reset package
            data['hangman'].remove(package)

    picked = pick_word()
    hangman_package = {
        'channel_id': channel_id,
        'is_active': True,
        'guessed': False,
        'word': picked,
        'letters_guessed': [],
        'tries': 10
    }
    data['hangman'].insert(0, hangman_package)
    return 'The word contains ' + str(
        len(picked)) + ' letters.\n' + len(picked) * '_'
Beispiel #27
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")
Beispiel #28
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')
Beispiel #29
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 the query. Results are sorted from most
    recent message to least recent message

    Parameters:
        token - The user's token that was generated from their user id
        query_str - A string that will be searched for

    Returns:
        A dictionary containing a list of messages

    Errors:
    '''
    check_token(token)
    data = get_data()
    channels = channels_list(token)
    m_list = []
    # Iterating through the messages
    for message in data['messages']:
        # Iterating through channels
        for channel in channels['channels']:
            # If the message contains the query string, apppend the dictionary
            if message['channel_id'] == channel['channel_id'] and \
               message['message'].lower().find(query_str.lower()) != -1:
                current_message = {
                    'message_id': message['message_id'],
                    'u_id': message['u_id'],
                    'message': message['message'],
                    'time_created': message['time_created'],
                }
                m_list.append(current_message)
    return {
        'messages': m_list
    }
Beispiel #30
0
def check_word(token, guess, channel_id):
    '''
    Check if the guessed letter is inside the picked word, \
    or if the guessed word matches the picked word

    Parameters:
        token - The user's token that was generated from their user id
        guess - The letter or word which the user guesses
        channel_id - The id of the channel in which the game is played in

    Returns:
        A message ready to be posted by hangman bot
    '''
    check_token(token)
    data = get_data()
    hangman_package = {}
    for package in data['hangman']:
        if package['channel_id'] == channel_id:
            if package['is_active'] is False:
                raise AccessError(
                    description='These is no active game in this channel.')
            hangman_package = package

    # No such hangman game active in this channel
    if hangman_package == {}:
        raise InputError(
            description='There is no active hangman game in this channel.')
    alphabet = 'abcdefghijklmnopqrstuvwxyz'
    checked_result = ''
    #1 - user inputs a letter
    if len(guess) == 1:
        if guess not in alphabet:
            checked_result += 'You have not entered a letter.'
        elif guess not in hangman_package['word']:
            hangman_package['letters_guessed'].append(guess)
            hangman_package['tries'] -= 1
        elif guess in hangman_package['word']:
            hangman_package['letters_guessed'].append(guess)

    #2 - user inputs the full word
    elif len(guess) == len(hangman_package['word']):
        if guess == hangman_package['word']:
            checked_result += 'Well done, you have guessed the word! :)'
            hangman_package['guessed'] = True
        else:
            hangman_package['tries'] -= 1
    #3 - user inputs a word that is not of the length of the picked word
    else:
        checked_result += 'The length of the word you entered is not the length we want.'

    checked_result += '\n'
    status = ''
    if hangman_package['guessed'] is False:
        for letter in hangman_package['word']:
            if letter in hangman_package['letters_guessed']:
                status += letter
            else:
                status += '_'
        checked_result += status
        checked_result += '\n'

    if status == hangman_package['word']:
        checked_result += 'Well done, you have guessed the word! :)\n'
        hangman_package['guessed'] = True
        hangman_package['is_active'] = False
        return checked_result

    if hangman_package['tries'] == 0:
        checked_result += 'You have run out of guesses and you haven\'t guessed the word. :(\n'
        checked_result += 'The word is ' + hangman_package['word'] + '.\n'
        hangman_package['is_active'] = False

    return checked_result + print_hangman(hangman_package['tries'])