Esempio n. 1
0
def channel_invite_v2(token, channel_id, u_id):
    '''
    Summary:
        Invites a user (with user id u_id) to join a channel with ID channel_id. 
        Once invited the user is added to the channel immediately.
    Args:
        token (string): A user session token 
        channel_id (int): A channel_id number
        u_id (int): A user id 
    Returns: 
        empty dictionary

    Raises:
        InputError when:
            channel_id does not refer to a valid channel
            u_id does not refer to a valid user
        AccessError when:
            the authorised user is not already a member of the channel
    '''
    global users, channels
    assert check_token(token)
    auth_user = user_from_token(token)

    if valid_channel(channel_id) == False:
        raise InputError(f"Channel ID {channel_id} is not a valid channel")

    if valid_user(u_id) == False:
        raise InputError(f"u_id {u_id} does not refer to a valid user")

    current_channel = find_channel(
        channel_id)  #current channel with the given channel id
    invitee = user_from_id(u_id)

    if auth_user['u_id'] not in current_channel['all_members']:
        raise AccessError(
            f"Authorised user {auth_user['u_id']} is not a member of channel with channel_id {channel_id}"
        )

    if u_id in current_channel['all_members']:
        raise AccessError(
            f"u_id {u_id} you are inviting is already inside the channel")

    current_channel['all_members'].append(u_id)
    if invitee[
            'permission'] == 1:  # Dreams owner is automatically channel owner
        current_channel['owner_members'].append(u_id)
    invitee['channels'].append(channel_id)
    update_user_channel_stats(invitee['u_id'])
    send_channel_added_notification(auth_user['handle_str'], u_id,
                                    current_channel['channel_id'])
    return {}
Esempio n. 2
0
def channel_addowner_v1(token, channel_id, u_id):
    '''
    Summary:
        Make user with user id u_id an owner of this channel
    Args:
        token (string): A user session token 
        channel_id (int): A channel_id number
        u_id (int): A user id number
    Returns: 
        a empty dictionary
    Raises:
        InputError when:
            Channel ID is not a valid channel
            When user with user id u_id is already an owner of the channel
        AccessError when:
           the authorised user is not an owner of the **Dreams**, 
           or an owner of this channel
    '''
    global users, channels
    assert check_token(token)
    assert valid_user(u_id)
    if valid_channel(channel_id) == False:
        raise InputError(f"Channel ID is not a valid channel")
    auth_user = user_from_token(token)
    current_channel = find_channel(
        channel_id)  #current channel with the given channel id

    if not is_channel_owner(auth_user['u_id'],
                            channel_id) and not is_dreams_owner(
                                auth_user['u_id']):
        raise AccessError(
            f"the authorised user is not an owner of the channel or Dreams")
    if is_channel_owner(u_id, channel_id) == True:
        raise InputError(
            f"User with user id {u_id} is already an owner of the channel")

    target_user = user_from_id(u_id)

    current_channel['owner_members'].append(u_id)
    if u_id not in current_channel['all_members']:
        current_channel['all_members'].append(u_id)
        target_user['channels'].append(channel_id)
        update_user_channel_stats(u_id)
        send_channel_added_notification(auth_user['handle_str'], u_id,
                                        current_channel['channel_id'])
    return {}
Esempio n. 3
0
def dm_invite_v1(token, dm_id, u_id):
    """Summary
        Inviting a user to an existing dm
    Args:
        token (string): A user session token
        dm_id (int): A dm id number
        u_id (int): An user's id, who want to add this dm
        
    Returns:
        Empty dictionary
    
    Raises:
        AccessError: When an invalid token is given, or the user that token refers to is not the creator of the dm
                     with id dm_id
    """
    check_token(token)
    auth_user = user_from_token(token)

    invitee = user_from_id(u_id)

    # InputError: When u_id does not refer to a valid user.
    if invitee == {}:
        raise InputError(f"id {u_id} does not refer to a valid user")

    # search all the dm in dms, and search the current dm by dm_id
    for dm in dms:
        if dm['dm_id'] == dm_id:
            # if auth user is a member of the dm, add the u_id to this dm
            if auth_user['u_id'] in dm['members']:
                dm['members'].append(u_id)
                invitee['dms'].append(dm_id)
                update_user_dm_stats(invitee['u_id'])
                send_dm_added_notification(auth_user['handle_str'], u_id,
                                           dm['dm_id'])
                return {}
            else:
                raise AccessError(
                    f"The authorised user {auth_user['handle_str']} is not already a member of the DM with id {dm_id}"
                )

    # InputError: When dm_id does not refer to a valid dm
    raise InputError(f"id {dm_id} does not refer to a valid dm")
Esempio n. 4
0
def dm_create_v1(token, u_id):
    '''
    Summary:
        u_ids is the user(s) that this DM is directed to, and will not include the creator. 
        The creator is the owner of the DM. 
        
        name should be automatically generated based on the user(s) that is in this dm. 
        The name should be an alphabetically-sorted, comma-separated list of user handles, e.g. 
        'handle1, handle2, handle3'.
    Args:
        token (string): A user session token 
        u_ids (list): A list of user ids 
    Returns: 
        a dictionary which contains the id of the dm (dm_id) 
        and the name of the dm which is the concatenated handles

    Raises:
        InputError when:
            u_id does not refer to a valid user
    '''
    global users, channels, next_dm_id, dms
    assert check_token(token)

    auth_user = user_from_token(token)
    user_list_handles = [auth_user['handle_str']]

    for i in range(len(u_id)):
        if valid_user(u_id[i]) == False:
            raise InputError(f"u_id {u_id[i]} does not refer to a valid user")
        else:
            member = user_from_id(u_id[i])
            user_list_handles.append(member['handle_str'])
    name = join_handle(user_list_handles)
    dm_id = next_dm_id['id']  #give the current global id number to this dm
    next_dm_id['id'] += 1  #after add one so the the dm id is always unique
    dm_members = [auth_user['u_id']]
    for user_id in u_id:
        dm_members.append(user_id)

    # Add dm to each member's list of dms
    for user in users:
        if user['u_id'] in dm_members:
            user['dms'].append(dm_id)
            update_user_dm_stats(user['u_id'])

    new_dm = {
        'dm_id': dm_id,
        'name': name,
        'creator': auth_user['u_id'],
        'messages': [],
        'members': dm_members
    }

    dms.append(new_dm)

    update_dm_stats()

    for user_id in new_dm['members']:
        send_dm_added_notification(auth_user['handle_str'], user_id, dm_id)

    return {'dm_id': dm_id, 'dm_name': new_dm['name']}
Esempio n. 5
0
def admin_user_remove_v1(token, u_id):
    '''
    Summary:
        Given a User by their user ID, remove the user from the Dreams. 
        Dreams owners can remove other **Dreams** owners (including the original first owner). 
        Once users are removed from **Dreams**, the contents of the messages they sent will be replaced by 'Removed user'. 
        Their profile must still be retrievable with user/profile/v2, with their name replaced by 'Removed user'.
    Args:
        token (string): A user session token 
        u_id (int): A user id number
    Returns: 
        empty dictionary
    Raises:
        InputError when:
            u_id does not refer to a valid user
            The user is currently the only owner
        AccessError when:
            The authorised user is not an owner
    '''
    global users, channels, tokens, dms
    assert check_token(token)
    auth_user = user_from_token(token)
    if valid_user(u_id) == False:
        raise InputError(f"User with u_id is not a valid user")
    dream_owners = find_all_dream_owners()  #list of all dream owners
    if auth_user['permission'] != 1:
        raise AccessError("The authorised user is not an owner")
    elif auth_user['u_id'] == u_id and len(dream_owners) == 1:
        # Only way that user being removed can be only owner is if they are removing themself
        raise InputError("The user is currently the only owner")

    # Remove all tokens associated with user being removed
    cleared_tokens = [
        tkn for tkn in tokens if user_from_token(tkn)['u_id'] != u_id
    ]
    tokens.clear()
    for tkn in cleared_tokens:
        tokens.append(tkn)

    user = user_from_id(u_id)
    user['name_first'] = 'Removed'
    user['name_last'] = 'user'
    user['permission'] = 0  # User permission id 0 indicates a removed user

    for channel in channels:
        for owner_member in channel['owner_members']:
            if owner_member == u_id:
                channel['owner_members'].remove(u_id)
        for normal_member in channel['all_members']:
            if normal_member == u_id:
                channel['all_members'].remove(u_id)

    for dm in dms:
        for member in dm['members']:
            if member == u_id:
                dm['members'].remove(u_id)

    for message in messages:
        if message['author_id'] == u_id:
            message['message'] = 'Removed user'

    return {}
Esempio n. 6
0
def message_send_v2(token, channel_id, message):
    '''
    Summary:
        Send a message from authorised_user to the channel specified by channel_id. 
        Note: Each message should have it's own unique ID. 
        I.E. No messages should share an ID with another message, 
        even if that other message is in a different channel.
    Args:
        token (string): A user session token 
        channel_id (int): A channel_id number
        message (string): a message string 
    Returns: 
        empty dictionary which contains the message_id
    Raises:
        InputError when:
            Message is more than 1000 characters
        AccessError when:
            the authorised user has not joined the channel they are trying to post to
    '''
    global users, channels, next_message_id, messages
    assert check_token(token)
    assert valid_channel(channel_id)

    auth_user = user_from_token(token)
    current_channel = find_channel(
        channel_id)  #current channel with the given channel id

    if current_channel['standup']['is_active']:
        standup_send_v1(token, channel_id, message)
        return

    if len(message) > 1000:
        raise InputError(f"Message more than 1000 characters")
    if auth_user['u_id'] not in current_channel['all_members']:
        raise AccessError(
            f"the authorised user has not joined the channel they are trying to post to"
        )

    current_time = current_unix_timestamp()  #gives us the current timestamp
    current_message = {}
    current_message['message_id'] = next_message_id['id']  #message_id
    current_message['channel_id'] = channel_id
    current_message[
        'dm_id'] = -1  #this is a channel message not dm so for all dm's give -1
    current_message['author_id'] = auth_user['u_id']
    current_message['message'] = message
    current_message['reacts'] = []
    current_message['time_created'] = current_time
    current_message['is_pinned'] = False
    current_channel['messages'].append(current_message['message_id'])
    next_message_id[
        'id'] += 1  #update the global message id so we get unique ids

    message_words = message.split(' ')

    # Standup start checker
    # Start a standup if message is exactly "/standup X" where X is a number of seconds
    if message.startswith('/standup') and len(
            message_words) == 2 and message_words[1].isdigit():
        duration = int(message_words[1])
        standup_start_v1(token, channel_id, duration)

    #notications checker and handler
    contains_tag = False
    tag_strings = []
    if '@' in message:
        for word in message_words:
            if word.startswith('@'):
                tag_strings.append(word[1:])
                contains_tag = True
    if contains_tag:
        for user_id in current_channel['all_members']:
            user = user_from_id(user_id)
            if user['handle_str'] in tag_strings:
                send_channel_tag_notification(auth_user['handle_str'], user_id,
                                              channel_id, message)

    messages.append(current_message)

    update_user_message_stats(auth_user['u_id'])

    update_message_stats()

    return {
        'message_id': current_message['message_id']  #message_id
    }
Esempio n. 7
0
def message_senddm_v1(token, dm_id, message):
    """Summary
        Send a message from authorised_user to the DM specified by dm_id. Note: Each message should have it's own unique ID. I.E. 
        No messages should share an ID with another message, even if that other message is in a different channel or DM.
    Args:
        token (string): A user session token
        dm_id (int): A dream id number which the message will be sented to
        message (string): The text with which the user wishes to sent to dream
    
    Returns:
        Dictionary: { message_id } the new message
    
    Raises:
        AccessError: when:  the authorised user is not a member of the DM they are trying to post to
        InputError: Message is more than 1000 characters
    """
    global next_message_id
    check_token(token)
    auth_user = user_from_token(token)

    # InputError: Message is more than 1000 characters
    if len(message) > 1000:
        raise InputError(f"Message {message} is more than 1000 characters")

    for dm in dms:
        if dm['dm_id'] == dm_id:
            # AccessError: when:  the authorised user is not a member of the DM they are trying to post to
            if auth_user['u_id'] not in dm['members']:
                raise AccessError(
                    f"the authorised user is not a member of the DM {dm_id}")
            else:
                current_time = current_unix_timestamp()
                message_id = next_message_id['id']
                next_message_id['id'] += 1

                # create a new message which will be sent to the dm
                current_message = {}
                current_message['message_id'] = message_id
                current_message['channel_id'] = -1
                current_message['dm_id'] = dm_id
                current_message['author_id'] = auth_user['u_id']
                current_message['message'] = message
                current_message['reacts'] = []
                current_message['time_created'] = current_time
                current_message['is_pinned'] = False

                contains_tag = False
                tag_strings = []

                if '@' in message:
                    for word in message.split(' '):
                        if word.startswith('@'):
                            tag_strings.append(word[1:])
                            contains_tag = True

                # the massage is already in the taget dm, send a notification
                if contains_tag:
                    for user_id in dm['members']:
                        user = user_from_id(user_id)
                        if user['handle_str'] in tag_strings:
                            send_dm_tag_notification(auth_user['handle_str'],
                                                     user_id, dm_id, message)

                # add the new massage to the messages list in the data
                dm['messages'].append(message_id)
                messages.append(current_message)

                update_user_message_stats(auth_user['u_id'])

                update_message_stats()

                return {'message_id': message_id}
    raise InputError(f"DM id {dm_id} does not refer to a valid dm")