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 {}
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
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 }
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 {}
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 {}
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 {}
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 {}
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}
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, }
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}
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}
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 {}