예제 #1
0
def channel_removeowner(token, channel_id, u_id):
    """ Remove user with user ID 'u_id' as an owner of this channel.

    Parameters:
        token (str): Authorisation hash for the user
        channel_id (int): Channels' channel ID
        u_id (int): Users' user ID

    Returns:
        {} (dict): Empty dictionary

    """
    if not isinstance(token, str):
        raise AccessError('Token is invalid')

    if not valid_channel_id(token, channel_id):
        raise InputError('Channel ID is not a valid channel')

    owner_id = get_user_id(token)
    channel_data = get_channel(channel_id)
    if not u_id in channel_data["owner_members"]:
        raise InputError('User is not an owner of the channel')

    list_of_auth_users = data["permissions"][0]["users"]
    if owner_id not in channel_data["owner_members"] + list_of_auth_users:
        raise AccessError(
            'User is not an owner of the channel or an owner of the flockr')

    channel_data["owner_members"].remove(u_id)
    channel_data["all_members"].append(u_id)
    channel_data = get_channel(channel_id)
    return {}
예제 #2
0
def channel_leave(token, channel_id):
    """ Given a channel ID, the user is removed as a member of this channel.

    Parameters:
        token (str): Authorisation hash for the user
        channel_id (int): Channels' channel ID

    Returns:
        {} (dict): Empty dictionary
    """
    if not isinstance(token, str):
        raise AccessError('Token is invalid')

    if not valid_channel_id(token, channel_id):
        raise InputError('Channel ID is not a valid channel')

    channel_data = get_channel(channel_id)

    user_id = get_user_id(token)

    result_access = user_id in channel_data["all_members"] + channel_data["owner_members"] and \
        channel_data["channel_id"] == channel_id
    if not result_access:
        raise AccessError('User is not a member of the channel')

    # If member of channel wants to leave we remove it. Otherwise we remove a owner member.
    if user_id in channel_data["all_members"]:
        channel_data["all_members"].remove(user_id)
    else:
        # Remove user_id for owner.
        channel_data["owner_members"].remove(user_id)

    return {}
예제 #3
0
def channel_join(token, channel_id):
    """ Given a channel ID of a channel that the authorised user can join, adds them to the channel.

    Parameters:
        token (str): Authorisation hash for the user
        channel_id (int): Channels' channel ID

    Returns:
        {} (dict): Empty dictionary

    """
    if not isinstance(token, str):
        raise AccessError('Token is invalid')

    # Check Token exists.
    if not valid_channel_id(token, channel_id):
        raise InputError('Channel ID is not a valid channel')

    u_id = get_user_id(token)

    channel_data = get_channel(channel_id)
    if verify_user_member(channel_id, u_id):
        raise InputError("User already exists in channel.")

    list_of_auth_users = data["permissions"][0]["users"]

    # If channel not public and user not authorised.
    if not channel_data["public"] and (u_id not in list_of_auth_users):
        raise AccessError("Channel is private and user is not a global owner")

    channel_data["all_members"].append(u_id)
    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 (str): Authorisation hash for user
        channel_id (int): Channels' channel ID

    Returns:
        is_active (bool): Whether or not a standup is active
        time_finish (int): Time standup finishes - Unix timestamp

    """
    if not isinstance(token, str):
        raise AccessError('Token is invalid')

    if not auth.check_token_exists(token):
        raise AccessError("User does not exist.")

    if not valid_channel_id(token, channel_id):
        raise InputError('Channel ID is not a valid channel')

    channel_data = get_channel(channel_id)

    return {
        'is_active': channel_data["is_active"],
        'time_finish': channel_data["time_finish"],
    }
예제 #5
0
def standup_send(token, channel_id, message):
    """ Send a message to get buffered in the standup queue, 
    assuming a standup is currently active.
    
    Parameters:
        token (str): Authorisation hash for user
        channel_id (int): Channels' channel ID
        message (str): Message from userz

    Returns:
        {} (dict): Empty dictionary

    """
    if not isinstance(token, str):
        raise AccessError('Token is invalid')

    if auth.check_token_exists(token):
        auth_user = get_user_id(token)

    else:
        raise AccessError("User does not exist.")

    if not valid_channel_id(token, channel_id):
        raise InputError('Channel ID is not a valid channel')

    if len(message) > 1000:
        raise InputError("The message is longer than 1000 characters")

    channel_data = get_channel(channel_id)
    if channel_data["is_active"] is False:
        raise InputError(
            'An active standup is not currently running in this channel')

    auth_id = get_user_id(token)
    if not verify_user_member(channel_id, auth_id):
        raise AccessError('Authorised user is not a member of the channel')

    usr = get_user_profile(auth_user)

    handle = usr["handle_str"]

    global msg
    msg += f"{handle}: {message}\n"

    return {}
예제 #6
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 (str): Authorisation hash for user
        channel_id (int): Channels' channel ID
        length (int): Number of seconds 

    Returns:
        time_finish (int): Time standup finishes - Unix timestamp

    """
    if not isinstance(token, str):
        raise AccessError('Token is invalid')

    if not auth.check_token_exists(token):
        raise AccessError("User does not exist.")

    if not valid_channel_id(token, channel_id):
        raise InputError('Channel ID is not a valid channel')

    channel_data = get_channel(channel_id)

    if channel_data["is_active"]:
        raise InputError(
            'An active standup is currently running in this channel')
    else:
        channel_data["is_active"] = True

    current_time = int(math.floor(time.time()))
    time_finish = current_time + length

    channel_data["time_finish"] = time_finish

    t = threading.Timer(length, reset_and_delay_messages,
                        [channel_data, token])
    t.start()

    return {'time_finish': time_finish}
예제 #7
0
def message_sendlater(token, channel_id, message, time_sent):
    """ Send a message from the authorised_user to the channel specified
        by channel_id automatically at a specified time in the future.

    Parameters:
        token (str): Authorisation hash for user
        channel_id (int): Channels' channel ID
        message (str): Message from user
        time_sent (int): Unix timestamp

    Returns:
        message_id (int): Messages' message ID

    """
    if not isinstance(token, str):
        raise AccessError('Token is invalid')

    if len(message) > 1000:
        raise InputError("The message is longer than 1000 characters")

    if not valid_channel_id(token, channel_id):
        raise InputError('Channel ID is not a valid channel')

    auth_id = get_user_id(token)

    if not verify_user_member(channel_id, auth_id):
        raise AccessError('User is not a member of the channel')

    current_date = datetime.today()
    current_unix_time = time.mktime(current_date.timetuple())
    time_difference = time_sent - current_unix_time

    if time_difference < 0:
        raise InputError('Time specified is a time in the past')

    with concurrent.futures.ThreadPoolExecutor() as executor:
        executor_instance = executor.submit(message_send, token, channel_id,
                                            message, time_difference)
        msg_result = executor_instance.result()

    return {"message_id": msg_result["message_id"]}
예제 #8
0
def channel_invite(token, channel_id, u_id):
    """ Invites a user with ID 'u_id' to join a channel with ID 'channel_id'.
        Once invited, the user is added to the channel immediately.

    Parameters:
        token (str): Authorisation hash for user
        channel_id (int): Channels' channel ID
        u_id (int): Users' user ID

    Returns:
        {} (dict): Empty dictionary

    """

    #step 0: error testing
    if not isinstance(token, str):
        raise AccessError('Token is invalid')

    if not valid_channel_id(token, channel_id):
        raise InputError('Channel ID is not a valid channel')

    # Check user id exists.
    if not check_uid_exists(u_id):
        raise InputError('User ID does not refer to a valid user')

    # Check auth user exists.
    # if check_user_exists(token):
    auth_id = get_user_id(token)
    if not verify_user_member(channel_id, auth_id):
        raise AccessError('Authorised user is not a member of the channel')

    channel_data = get_channel(channel_id)

    # Check for user exists.
    if u_id in channel_data["all_members"] + channel_data["owner_members"]:
        raise InputError("User already exists!")

    channel_data["all_members"].append(u_id)

    return {}
예제 #9
0
def channel_details(token, channel_id):
    """ Given a channel with ID 'channel_id' that the authorised user is a part of,
    provide basic details about the channel.

    Parameters:
        token (str): Authorisation hash for the user
        channel_id (int): Channels' channel ID

    Returns:
        {} (dict): Empty dictionary

    """
    #step 0: error testing
    if not isinstance(token, str):
        raise AccessError('Token is invalid')

    if not valid_channel_id(token, channel_id):
        raise InputError('Channel ID is not a valid channel')

    channel_data = get_channel(channel_id)
    auth_user = get_user_id(token)

    if auth_user not in channel_data["owner_members"] + channel_data[
            "all_members"]:
        raise AccessError('User is not a member of the channel')

    owners_list = list(map(list_members, channel_data["owner_members"]))
    members_list = owners_list + list(
        map(list_members, channel_data["all_members"]))

    return {
        "name": channel_data["name"],
        "owner_members": owners_list,
        "all_members": members_list,
        # ensure that profile_img_url is also returned
    }
예제 #10
0
def channel_messages(token, channel_id, start):
    """ Given a channel with ID 'channel_id' that the authorised user is a part of, return up to
        50 messages between index "start" and "start + 50". Message with index 0 is the most recent
        message in the channel. This function returns a new index "end" which is the value of
        "start + 50", or, if this function has returned the least recent messages in the channel,
        returns -1 in "end" to indicate there are no more messages to load after this return.

    Parameters:
        token (str): Authorisation hash for the user
        channel_id (int): Channels' channel ID
        start (int): start index of messages to return

    Returns:
        Dictionary containing:
            messages (list): List of dictionaries containing messages and their basic details
            start (int): Start index of messages to return
            end (int): End index of messages to return

    """
    if not isinstance(token, str):
        raise AccessError('Token is invalid')

    if not valid_channel_id(token, channel_id):
        raise InputError('Channel ID is not a valid channel')

    # Case for invalid start
    if start < 0:
        raise InputError("Invalid start index provided")


    channel_msgs = list(filter(lambda msg_list: msg_list["channel_id"]\
        == channel_id, data["messages"]))
    end = start + 50
    # Doesn't return an error if splice end index is too high.
    channel_msgs_spliced = channel_msgs[start:end]

    # if start of messages is greater than total number of messages in the
    # channel, then raise InputError
    if start > len(channel_msgs):
        raise InputError("Start greater than channel messages length.")
    if channel_msgs != []:
        min_time_found = min(
            list(map(lambda x: x["time_created"], channel_msgs)))
    else:
        return {"messages": [], "start": start, "end": -1}

    # if channel_msgs_spliced is not None:
    min_time_in_spliced = min(
        list(map(lambda x: x["time_created"], channel_msgs_spliced)))

    if min_time_found == min_time_in_spliced:
        end = -1
    # Sorted in descending order (biggest larger time means more recent in UNIX)
    # and key is sorting by time_created.
    # channel_msgs_spliced.sort(reverse=False, key=lambda x: x.get("time_created"))
    channel_msgs_spliced.sort(reverse=True,
                              key=lambda x: x.get("time_created"))
    user_id = get_user_id(token)
    for msg in channel_msgs_spliced:
        if user_id in msg["reacts"][0]["u_ids"]:
            msg["reacts"][0]["is_this_user_reacted"] = True
        else:
            msg["reacts"][0]["is_this_user_reacted"] = False
    return {
        'messages': channel_msgs_spliced,
        'start': start,
        'end': end,
    }