Exemple #1
0
def dm_leave_v1(token, dm_id):
    """
    Given a DM ID, the user is removed as a member of this DM

    Arguments:
        token (string)  - jwt encoded data structure of auth_user
        dm_id (int)    - target dm

    Exceptions:
        InputError      -   Occurs when dm_id is not a valid DM
        AccessError     -   Occurs when Authorised user is not a member of DM with dm_id

    Return value:
        Returns user (dictionary) on success
            a dictionary with information about nothing
    """
    time_stamp = datetime.now().replace(microsecond=0).timestamp()

    with open("data.json") as json_file:
        data = load(json_file)

    auth_user_id = token_check(token)["u_id"]

    is_dm_exist = False
    for dm_data in data["dms"]:
        if dm_data["dm_id"] == dm_id:
            dm = dm_data
            is_dm_exist = True
            break
    if is_dm_exist is False:
        raise InputError("dm_id is not a valid DM")

    is_auth_user_member = False
    if auth_user_id in dm["members"]:
        is_auth_user_member = True
    if is_auth_user_member is False:
        raise AccessError("Authorised user is not a member of DM with dm_id")

    user_stats_update(data, auth_user_id, stat_types.DM_LEAVE, time_stamp)

    if auth_user_id != dm["original_creator"]:
        dm["members"].remove(auth_user_id)
    else:
        dm["members"].remove(auth_user_id)
        dm["original_creator"] = dm["members"][0]

    list(set(dm["members"]))

    with open("data.json", "w") as json_file:
        dump(data, json_file, indent=4)

    return {}
Exemple #2
0
def standup_close_v1(token, channel_id, u_id):
    with open("data.json") as json_file:
        data = load(json_file)

    standup_channel = None
    for standup_channel_data in data["standups"]:
        if standup_channel_data["channel_id"] == channel_id:
            standup_channel = standup_channel_data

    if standup_channel is None:
        return

    combine_message = "\n".join(standup_channel["message"])

    time_created = datetime.now().replace(microsecond=0).timestamp()

    for channel in data["channels"]:
        if channel["channel_id"] == channel_id:
            found_channel = channel

    all_msgs = found_channel["messages"]
    # Keep track of last message id
    last_msg_id = data.get("last_message_id", 0)
    message_id = last_msg_id + 1
    # Update data
    data["last_message_id"] = message_id
    # unix timestamp
    user_stats_update(data, u_id, stat_types.MSG_SEND, time_created)
    dreams_stats_update(data, stat_types.MSG_SEND, time_created)

    new_message = {
        "message_id": message_id,
        "u_id": int(u_id),
        "message": combine_message,
        "time_created": time_created,
        "reacts": [{
            'react_id': 0,
            'u_ids': [],
            'is_this_user_reacted': False
        }],
        "react_history": [],
        "is_pinned": False,
    }
    # Append the new message to the end of the list
    all_msgs.append(new_message)

    data["standups"].remove(standup_channel)

    with open("data.json", "w") as json_file:
        dump(data, json_file, indent=4)

    return
Exemple #3
0
def channels_create_v2(token, name, is_public):
    '''
    Creates a new channel with that name that is either a public or private channel
    
    Returns type:
        { channel_id }

    Input Error:
        Name is more than 20 characters long
    '''
    time_stamp = datetime.now().replace(microsecond=0).timestamp()

    with open("data.json") as json_file:
        data = load(json_file)

    # Decode token (u_id) if valid, otherwise raise AccessError
    user = token_check(token)
    # Raise error if channel name is > 20 characters
    # or if there is no name given
    if len(name) > 20:
        raise InputError("Channel name is more than 20 characters.")
    if len(name) == 0:
        raise InputError("No channel name has been entered.")

    # Ensure users sets channel to private or public
    if is_public not in (True, False):
        raise InputError("Channel privacy is undefined")

    # Makes the channel id in order from 1 as they are created
    channel_id = len(data["channels"]) + 1
    # Store data in data.py channels
    user_stats_update(data, user["u_id"], stat_types.CH_JOIN, time_stamp)
    dreams_stats_update(data, stat_types.CH_CREATE, time_stamp)

    data["channels"].append(
        {
            'channel_id': channel_id,
            'name': name,
            'owner_members': [user['u_id']],
            'all_members': [user['u_id']],
            'invites' : [],
            'is_public': is_public,
            'messages': []
        }
    )
    with open("data.json", "w") as json_file:
        dump(data, json_file, indent=4)

    return { 
        'channel_id': channel_id 
    }
Exemple #4
0
def dm_remove_v1(token, dm_id):
    """
    Remove an existing DM. This can only be done by the original creator of the DM.

    Arguments:
        token (string)  - jwt encoded data structure of auth_user
        dm_id (int)    - dm_id that be removed

    Exceptions:
        InputError      -   Occurs when dm_id does not refer to a valid DM
        AccessError     -   Occurs when the user is not the original DM creator

    Return value:
        Returns user (dictionary) on success
            a dictionary with information about nothing
    """
    time_stamp = datetime.now().replace(microsecond=0).timestamp()

    with open("data.json") as json_file:
        data = load(json_file)

    auth_user_id = token_check(token)["u_id"]

    is_dm_exist = False
    for dm_data in data["dms"]:
        if dm_data["dm_id"] == dm_id:
            dm = dm_data
            is_dm_exist = True
            break
    if is_dm_exist is False:
        raise InputError("dm_id does not refer to a valid DM")

    is_auth_user_creator = False
    if auth_user_id == dm["original_creator"]:
        is_auth_user_creator = True
    if is_auth_user_creator is False:
        raise AccessError("the user is not the original DM creator")

    dreams_stats_update(data, stat_types.DM_REMOVE, time_stamp)

    for member in dm["members"]:
        user_stats_update(data, member, stat_types.DM_LEAVE, time_stamp)

    data["dms"].remove(dm)

    with open("data.json", "w") as json_file:
        dump(data, json_file, indent=4)

    return {}
Exemple #5
0
def channel_invite_v2(token, channel_id, u_id):
    '''
    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

    Arguments:
        token (string)      - jwt encoded data structure of auth_user
        channel_id (int)    - channel_id of channel to have u_id invited into
        u_id (int)          - u_id of individual to be invited

    Exceptions:
        InputError  -   Occurs when channel_id does not refer to a valid channel,
                        u_id does not refer to a valid user
        AccessError -   Occurs when the authorised user is not already a member of the channel,
                        token is invalid

    Return value:
        {}
    '''
    time_stamp = datetime.now().replace(microsecond=0).timestamp()

    with open("data.json") as json_file:
        data = load(json_file)

    data_structure = token_check(token)

    errorcheck_channel_invite_v2(token, channel_id, u_id)

    user_stats_update(data, data_structure["u_id"], stat_types.CH_JOIN,
                      time_stamp)

    for channel in data["channels"]:
        if channel["channel_id"] == channel_id:
            found_channel = channel

    found_channel['all_members'].append(u_id)
    list(set(found_channel['all_members']))

    found_channel['invites'].append({
        "auth_user_id": data_structure["u_id"],
        "u_id": u_id,
        "time_invited": time_stamp
    })

    with open("data.json", "w") as json_file:
        dump(data, json_file, indent=4)

    return {}
Exemple #6
0
def channel_leave_v1(token, channel_id):
    '''
    Given a channel ID, the user removed as a member of this channel. 
    Their messages should remain in the channel
    
    Parameters:
    token (str): jwt encoded data structure for authorised user
    channel_id (int): id for channel

    Returns:
    {}

    InputError when:
        Channel ID is not a valid channel
    AccessError when:
        Authorised user is not a member of channel with channel_id
    '''
    time_stamp = datetime.now().replace(microsecond=0).timestamp()

    with open("data.json") as json_file:
        data = load(json_file)

    user = token_check(token)

    errorcheck_leave_v2(token, channel_id)

    user_stats_update(data, user["u_id"], stat_types.CH_LEAVE, time_stamp)

    found_channel = find_channel(data, channel_id)

    found_channel['all_members'].remove(user['u_id'])

    if user['u_id'] in found_channel['owner_members']:
        found_channel['owner_members'].remove(user['u_id'])

    with open("data.json", "w+") as json_file:
        dump(data, json_file, indent=4)

    return {}
Exemple #7
0
def channel_join_v2(token, channel_id):
    '''
    Given a channel_id of a channel that the authorised user can join, adds them to that channel

    Arguments:
        token (string)      - jwt encoded string containing auth_user_id info
        channel_id (int)    - id of channel to join

    Exceptions:
        InputError  -   Occurs when channel ID is not a valid channel
        AccessError -   Occurs when channel_id refers to a channel that is private (when the authorised user is not a global owner),
                        token is invalid
    Return value:
        {}
    '''
    time_stamp = datetime.now().replace(microsecond=0).timestamp()

    with open("data.json") as json_file:
        data = load(json_file)

    data_structure = token_check(token)

    errorcheck_channel_join_v2(data_structure, data, channel_id)

    user_stats_update(data, data_structure["u_id"], stat_types.CH_JOIN,
                      time_stamp)

    found_channel = find_channel(data, channel_id)

    found_channel['all_members'].append(int(data_structure["u_id"]))
    list(set(found_channel['all_members']))

    with open("data.json", "w") as json_file:
        dump(data, json_file, indent=4)

    return {}
Exemple #8
0
def message_share_v1(token, og_message_id, message, channel_id, dm_id):
    """
    og_message_id is the original message. 
    channel_id is the channel that the message is being shared to, and is -1 if it is being sent to a DM. 
    dm_id is the DM that the message is being shared to, and is -1 if it is being sent to a channel.
    message is the optional message in addition to the shared message, 
    and will be an empty string "" if no message is given

    Parameters:
        token - token of the user sharing message
        og_message_id - message id of the original message
        message - optional message to be commented with shared message
        channel_id - channel_id of the channel msg is being shared to (default -1)
        dm_id - dm_id of the dm group that message is being sent to (default -1)

    Returns:
        { shared_message-id }

    InputError when:
        Optional message is more than 1000 characters (Assumption)

    AccessError when:
        Invalid token
        The authorised user has not joined the channel or DM they are trying to share the message to
    
    """
    time_stamp = datetime.now().replace(microsecond=0).timestamp()

    with open("data.json") as json_file:
        data = load(json_file)
    # Decode token if token is valid
    user = token_check(token)

    optional_msg = message
    # Input Error when optional message is more than 1000 chars
    if len(optional_msg) > 1000:
        raise InputError(
            description="Your optional message is more than 1000 characters")
    # Let the channel/dm not being shared to be -1
    not_shared = -1
    # If channel_id and dm_id are both given
    # user should give either a channel_id or dm_id
    if channel_id is not not_shared and dm_id is not not_shared:
        raise InputError(
            description=
            "Both channel_id and dm_id is given, choose one or the other")
    # Both channel_id and dm_id are given as -1
    elif channel_id is not_shared and dm_id is not_shared:
        raise InputError(
            description="Both channel_id and dm_id are given as -1")
    # ----SHARING TO CHANNEL----
    # If channel_id is given and dm_id is -1
    elif channel_id is not not_shared and dm_id is not_shared:
        user_stats_update(data, user["u_id"], stat_types.MSG_SEND, time_stamp)
        dreams_stats_update(data, stat_types.MSG_SEND, time_stamp)

        # Check if channel_id given is valid
        if is_valid_channel_id(channel_id) is False:
            raise InputError(description="Channel id not found")
        # Check if the authorised user is a member of the channel
        if is_auth_user_memberof_channel_id(token, channel_id) is False:
            raise AccessError(
                description="Authorised use is not a member of the channel")

        msg_found = False
        # Loop through channel data to look for message_id
        for ch in data["channels"]:
            # Loop through messages of channel
            for msg in ch["messages"]:
                # if og_message_id is found
                if msg["message_id"] == og_message_id:
                    msg_found = True
                    break
        # The message wasn"t found in channel
        # Loop through the DM messages and check if it is there
        for dm in data["dms"]:
            # Loop through messages of dms
            for dm_message in dm["messages"]:
                # If message_id is found
                if dm_message["message_id"] == og_message_id:
                    msg_found = True
        # If the message is found, assign string of shared message
        if msg_found:
            og_message = msg["message"]
        else:
            raise InputError(description="message id could not be found")
        # Find the channel for channel id given
        channel = find_channel(data, channel_id)
        # Loop through to the channel given and return specified channel dictionary
        all_msgs = channel["messages"]
        # Keep track of last message id
        last_msg_id = data.get("last_message_id", 0)
        message_id = last_msg_id + 1
        # Update data
        data["last_message_id"] = message_id
        # unix timestamp
        time_create_date = datetime.now().replace(microsecond=0)
        time_created = time_create_date.timestamp()
        # New message struct
        new_message = {
            "message_id": message_id,
            "u_id": user["u_id"],
            # E.g. Hi guys, look at this ----|funny cat meme|----
            "message": optional_msg + " " + "----|" + og_message + "|----",
            "time_created": time_created,
            'reacts': [{
                'react_id': 0,
                'u_ids': [],
                'is_this_user_reacted': False
            }],
            'react_history': [],
            'is_pinned': False,
        }
        # Append the new message to the end of the list
        all_msgs.append(new_message)

    # ----SHARING TO DM----
    # If channel is -1 and dm_id is given
    elif channel_id is not_shared and dm_id is not not_shared:
        user_stats_update(data, user["u_id"], stat_types.MSG_SEND, time_stamp)
        dreams_stats_update(data, stat_types.MSG_SEND, time_stamp)

        # Check if dm_id given is valid
        is_dm_exist = False
        for dm_data in data["dms"]:
            if dm_data["dm_id"] == dm_id:
                # Assign dm dictionary of given dm_id
                dm = dm_data
                is_dm_exist = True
                break
        if is_dm_exist is False:
            raise InputError("DM ID is not a valid DM")
        # Check if user is a member of dm group
        is_auth_user_member = False
        if user["u_id"] in dm["members"]:
            is_auth_user_member = True
        if is_auth_user_member is False:
            raise AccessError(
                description=
                "Authorised user is not a member of this DM with dm_id")

        msg_found = False
        # Loop through channel data to look for message_id
        for ch in data["channels"]:
            # Loop through messages of channel
            for msg in ch["messages"]:
                # if og_message_id is found
                if msg["message_id"] == og_message_id:
                    msg_found = True
        # The message wasn"t found in channel
        # Loop through the DM messages and check if it is there
        for dm in data["dms"]:
            # Loop through messages of dms
            for dm_message in dm["messages"]:
                # If message_id is found
                if dm_message["message_id"] == og_message_id:
                    msg_found = True
                    break

        # If the message is found, assign string of shared message
        if msg_found:
            og_message = dm_message["message"]
        else:
            raise InputError(description="message id could not be found")

        # Keep track of last message id
        last_msg_id = data["last_message_id"]
        message_id = last_msg_id + 1
        # Update data
        data["last_message_id"] = message_id

        # unix timestamp
        time_create_date = datetime.now().replace(microsecond=0)
        time_created = time_create_date.timestamp()

        new_message = {
            "message_id": message_id,
            "u_id": user["u_id"],
            "message": message + " " + "----|" + og_message + "|----",
            "time_created": time_created,
            'reacts': [{
                'react_id': 0,
                'u_ids': [],
                'is_this_user_reacted': False
            }],
            'react_history': [],
            'is_pinned': False,
        }

        all_msgs = dm["messages"]
        # Append the new message to the end of the list
        all_msgs.append(new_message)

    with open("data.json", "w") as json_file:
        dump(data, json_file, indent=4)

    return {"shared_message_id": message_id}
Exemple #9
0
def message_send_v2(token, channel_id, message):
    """
    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.

    InputError when:
        Message is more than 1000 characters.
        Channel ID is not valid.
    AccessError when:
        The authorised user has not joined the channel they are trying to post to.
        Invalid token is passed.

    Parameters:
        token - token of the user,
        channel_id - channel id in which message is being sent to,
        message - message that is being sent

    Returns:
        { message_id }
    """
    time_created = datetime.now().replace(microsecond=0).timestamp()

    with open("data.json") as json_file:
        data = load(json_file)

    # Check token is valid, if so, assign variable to decode u_id
    user = token_check(token)
    # Check channel ID given is valid
    if is_valid_channel_id(channel_id) is False:
        raise InputError("Invalid Channel ID")
    # Make sure authorised user is a member of the channel
    if is_auth_user_memberof_channel_id(token, channel_id) is False:
        raise AccessError(description="User is not a member of this channel")
    # InputError raised when empty message is sent
    if message == "":
        raise InputError(description="Cannot send an empty message")
    # Ensure message being sent is no more than 1000 characters
    if len(message) > 1000:
        raise InputError(description="Message is more than 1000 characters")
    # Loop through to the channel given and return specified channel dictionary

    for channel in data["channels"]:
        if channel["channel_id"] == channel_id:
            found_channel = channel

    all_msgs = found_channel["messages"]
    # Keep track of last message id
    last_msg_id = data.get("last_message_id", 0)
    message_id = last_msg_id + 1
    # Update data
    data["last_message_id"] = message_id
    # unix timestamp
    user_stats_update(data, user["u_id"], stat_types.MSG_SEND, time_created)
    dreams_stats_update(data, stat_types.MSG_SEND, time_created)

    new_message = {
        "message_id": message_id,
        "u_id": int(user["u_id"]),
        "message": message,
        "time_created": time_created,
        "reacts": [{
            'react_id': 0,
            'u_ids': [],
            'is_this_user_reacted': False
        }],
        "react_history": [],
        "is_pinned": False,
    }
    # Append the new message to the end of the list
    all_msgs.append(new_message)

    with open("data.json", "w") as json_file:
        dump(data, json_file, indent=4)

    if message == "/u start":
        unscramble_play(word_banks.DEFAULT, found_channel["channel_id"])

    elif message == "/u simple":
        unscramble_play(word_banks.SIMPLE, found_channel["channel_id"])

    elif message == "/u leaderboard":
        unscramble_leaderboard(found_channel["channel_id"])

    # i.e. the message is one singular word
    elif len(message.split(" ")) == 1:
        unscramble_listen(int(user["u_id"]), found_channel["channel_id"],
                          message)

    return {
        "message_id": message_id,
    }
Exemple #10
0
def message_senddm_v1(token, dm_id, message):
    """
    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.

    InputError when:
        Message is more than 1000 characters.
        DM ID is not valid.
    AccessError when:
        The authorised user not a member of the DM they are trying to post to.
        Invalid token is passed.

    Parameters:
        token - token of the user,
        dm_id - dm id in which message is being sent to,
        message - message that is being sent

    Returns:
        { message_id }
    """
    # unix timestamp
    time_created = datetime.now().replace(microsecond=0).timestamp()

    with open("data.json") as json_file:
        data = load(json_file)

    # Check token is valid, if so, assign variable to decode u_id
    auth_user_id = token_check(token)["u_id"]
    # Loop through to the dm_id given and return specified DM dictionary
    is_dm_exist = False
    for dm_data in data["dms"]:
        if dm_data["dm_id"] == dm_id:
            dm = dm_data
            is_dm_exist = True
            break
    # Check DM ID given is valid
    if is_dm_exist is False:
        raise InputError(description="DM ID is not a valid DM")
    # Make sure authorised user is a member of the DM group
    is_auth_user_member = False
    if auth_user_id in dm["members"]:
        is_auth_user_member = True
    if is_auth_user_member is False:
        raise AccessError(
            description="Authorised user is not a member of this DM with dm_id"
        )
    # If message is empty (assumption) raise InputError
    if message == '':
        raise InputError(description='Cannot send an empty message')
    # Ensure message being sent is no more than 1000 characters
    if len(message) > 1000:
        raise InputError(description='Message is more than 1000 characters')

    # Keep track of last message id
    last_msg_id = data['last_message_id']
    message_id = last_msg_id + 1
    # Update data
    data['last_message_id'] = message_id
    user_stats_update(data, auth_user_id, stat_types.MSG_SEND, time_created)
    dreams_stats_update(data, stat_types.MSG_SEND, time_created)

    new_message = {
        'message_id': message_id,
        'u_id': auth_user_id,
        'message': message,
        'time_created': time_created,
        'reacts': [{
            'react_id': 0,
            'u_ids': [],
            'is_this_user_reacted': False
        }],
        'react_history': [],
        'is_pinned': False,
    }
    all_msgs = dm['messages']
    # Append the new message to the end of the list
    all_msgs.append(new_message)

    with open("data.json", "w") as json_file:
        dump(data, json_file, indent=4)

    return {'message_id': message_id}
Exemple #11
0
def dm_create_v1(token, u_ids):
    """
    u_ids contains 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".

    Arguments:
        token (string)  - jwt encoded data structure of auth_user
        u_ids (list)    - a list of users

    Exceptions:
        InputError      -   Occurs when u_id does not refer to a valid user
        AccessError     -   N/A

    Return value:
        Returns user (dictionary) on success
            a dictionary with information about dm_id, dm_name
    """
    time_stamp = datetime.now().replace(microsecond=0).timestamp()

    with open("data.json") as json_file:
        data = load(json_file)

    num_directed_user = len(u_ids)
    count = 0
    for user in data["users"]:
        for u_id in u_ids:
            if user["u_id"] == u_id:
                count += 1
    if count != num_directed_user:
        raise InputError("u_id does not refer to a valid user")

    auth_user_id = token_check(token)["u_id"]

    user_stats_update(data, auth_user_id, stat_types.DM_JOIN, time_stamp)
    dreams_stats_update(data, stat_types.DM_CREATE, time_stamp)

    #dm_id start from 1
    dm_id = len(data["dms"]) + 1

    handles = []

    auth_user_handle = user_profile_v2(token,
                                       auth_user_id)["user"]["handle_str"]
    handles.append(auth_user_handle)

    for u_id in u_ids:
        user_handle = user_profile_v2(token, u_id)["user"]["handle_str"]
        user_stats_update(data, u_id, stat_types.DM_JOIN, time_stamp)
        handles.append(user_handle)
    handles.sort()
    dm_name = ", ".join(handles)

    all_members = []
    all_members.append(auth_user_id)
    for u_id in u_ids:
        all_members.append(u_id)

    data["dms"].append({
        "dm_id": dm_id,
        "name": dm_name,
        "original_creator": auth_user_id,
        "members": all_members,
        "invites": [],
        "messages": []
    })
    with open("data.json", "w") as json_file:
        dump(data, json_file, indent=4)

    return {"dm_id": dm_id, "dm_name": dm_name}
Exemple #12
0
def dm_invite_v1(token, dm_id, u_id):
    """
    Remove an existing DM. This can only be done by the original creator of the DM

    Arguments:
        token (string)  - jwt encoded data structure of auth_user
        dm_id (int)    - target dm
        u_id (int)     - u_id that be invited

    Exceptions:
        InputError      -   Occurs when dm_id does not refer to an existing dm and u_id does not refer to a valid user
        AccessError     -   Occurs when the authorised user is not already a member of the DM

    Return value:
        Returns user (dictionary) on success
            a dictionary with information about nothing
    """
    time_stamp = datetime.now().replace(microsecond=0).timestamp()

    with open("data.json") as json_file:
        data = load(json_file)

    auth_user_id = token_check(token)["u_id"]

    is_dm_exist = False
    for dm_data in data["dms"]:
        if dm_data["dm_id"] == dm_id:
            dm = dm_data
            is_dm_exist = True
            break
    if is_dm_exist is False:
        raise InputError("dm_id does not refer to an existing dm")

    is_u_id_exist = False
    for user in data["users"]:
        if user["u_id"] == u_id:
            is_u_id_exist = True
            break
    if is_u_id_exist is False:
        raise InputError("u_id does not refer to a valid user")

    is_auth_user_member = False
    if auth_user_id in dm["members"]:
        is_auth_user_member = True
    if is_auth_user_member is False:
        raise AccessError(
            "the authorised user is not already a member of the DM")

    dm["members"].append(u_id)
    list(set(dm["members"]))

    user_stats_update(data, auth_user_id, stat_types.DM_JOIN, time_stamp)
    dm["invites"].append({
        "auth_user_id": auth_user_id,
        "u_id": u_id,
        "time_invited": time_stamp
    })

    with open("data.json", "w") as json_file:
        dump(data, json_file, indent=4)

    return {}