def message_sendlater(token, channel_id, message, time_sent): # Error handling for long messages, non-existent channels, invalid time # and user not part of channel if len(message) > 1000: raise InputError("Message is too long") if not channel_exists(channel_id): raise InputError("Channel cannot be found") now = datetime.now() if time_sent < datetime.timestamp(now): raise InputError("Requested time to send message has already passed") if not user_in_channel(get_u_id(token), channel_id): raise AccessError("User is not part of the requested channel") m_id = 1 # Calculating message_id for channel in channels: for message in channel['messages']: m_id = m_id + 1 # Calculating time difference and delay = time_sent - datetime.timestamp(now) # Starting timer to execute sending the message t = Timer(delay, message_sendlater_action, args=[get_u_id(token), m_id, message, time_sent, channel_id]) t.start() return {'message_id': m_id}
def channels_create(token, name, is_public): ''' Creates a new channel ''' valid_token = False for user in users: if user['token'] == token: valid_token = True if valid_token and len(name) <= 20: new_channel = { 'channel_id': len(channels) + 1, 'name': name, 'is_public': is_public, 'creator': create_member(get_u_id(token)), 'owners': [create_member(get_u_id(token))], 'members': [create_member(get_u_id(token))], 'messages': [], 'is_standup': False, 'standup_finish': None, 'standup': '' } new_channel_copy = new_channel.copy() channels.append(new_channel_copy) saveChannelData(channels) return {'channel_id': new_channel_copy['channel_id']} if len(name) > 20: raise InputError('Invalid Name') return None
def user_profile_uploadphoto(token, img_url, x_start, y_start, x_end, y_end, url): u_id = get_u_id(token) profile_img_url = os.path.join("src/static/", str(u_id) + ".jpg") try: urllib.request.urlretrieve(img_url, profile_img_url) except HTTPError as e: raise InputError("Invalid url:", e) if (not img_url.endswith('jpg')): raise InputError("invalid file type") img = Image.open(profile_img_url) size = img.size if ( (x_start < 0) | (x_end > size[0]) | (y_start < 0) | (y_end > size[1]) ): raise InputError("Not valid start points") cropped = img.crop( (int(x_start), int(y_start), int(x_end), int(y_end)) ) cropped.save(profile_img_url) profile_img_url = str(url) + profile_img_url change_picture(u_id, profile_img_url) return {}
def standup_start(token, channel_id, length): channels = getChannelData() authorised_u_id = get_u_id(token) if not channel_exists_persist(channel_id): raise InputError('Invalid channel') if not user_in_channel_persist(authorised_u_id, channel_id): raise AccessError('User not a member of channel') for channel in channels: if channel['channel_id'] == channel_id: if channel['is_standup'] != False: raise InputError('Channel already in standup') thread = Thread(target=standup, args=(channel_id, token, length)) for channel in channels: if channel['channel_id'] == channel_id: channel['is_standup'] = True thread.start() finish_time = datetime.now() + timedelta(seconds=int(length)) unixstamp = time.mktime(finish_time.timetuple()) for channel in channels: if channel['channel_id'] == channel_id: channel['standup_finish'] = unixstamp saveChannelData(channels) return {'time_finish': unixstamp}
def message_remove(token, message_id): ''' Funtion remove message from channel given message and token ''' u_id = get_u_id(token) channel_id = find_channel(message_id) m_id = message_exists(message_id) owner = user_is_owner(u_id, channel_id) creator = message_creator(u_id, message_id) permission_id = permission(u_id) #raising error if message doesnt exist if not m_id: raise InputError("Invalid message ID") #checking if user has authorization to remove message if not creator and not owner and permission_id == 2: raise AccessError("user is not authorised to remove message") #removing message from channel for channel in channels: for chan_messages in channel['messages']: if chan_messages['message_id'] == message_id: channel['messages'].remove(chan_messages) return {} return {}
def channel_invite(token, channel_id, u_id): channels = getChannelData() ''' Tests channel_invite function ''' #retireving u_id from token from token authorised_u_id = get_u_id(token) #raising error if channel does not exist if not channel_exists_persist(channel_id): raise InputError('Invalid channel') #raising error is user does not exist if not user_exists_persist(u_id): raise InputError('Invalid user id') #raising error is user in now in channel if not user_in_channel_persist(authorised_u_id, channel_id): raise AccessError('User not a member of channel') #finding the correct channel then and appending new user for channel in channels: if channel['channel_id'] == int(channel_id): channel['members'].append(create_member(int(u_id))) saveChannelData(channels) return {}
def channel_join_p(token, channel_id): # pragma: no cover ''' adds user to channel ''' #Comment out below channels = getChannelData() channel_id = int(channel_id) u_id = get_u_id(token) #rasies error if channel does not exist if not channel_exists(channel_id): raise InputError('Invalid channel') #Check if channel is public or private public = False for channel in channels: if int(channel['channel_id']) == channel_id: if channel['is_public']: public = True #if channel is prive error is raised if not public: raise AccessError('Private Channel') #adds member to channel for channel in channels: if (int(channel['channel_id']) == channel_id and create_member(u_id) not in channel['members']): channel['members'].append(create_member(u_id)) #Comment out below saveChannelData(channels) return {}
def standup_send(token, channel_id, message): channels = getChannelData() users = getUserData() channel_id = int(channel_id) authorised_u_id = get_u_id(token) if not channel_exists_persist(channel_id): raise InputError('Invalid channel') if not user_in_channel_persist(authorised_u_id, channel_id): raise AccessError('User not a member of channel') if len(message) > 1000: raise InputError("Message too long") for channel in channels: if channel['channel_id'] == channel_id: if channel['is_standup'] == False: raise InputError("Channel not in standup") for user in users: if user['u_id'] == authorised_u_id: handle = user['handle_str'] new_message = handle + ": " + message + "\n" for channel in channels: if channel['channel_id'] == channel_id: channel['standup'] = channel['standup'] + new_message saveChannelData(channels) return {}
def channel_leave(token, channel_id): ''' removes user from channel ''' authorised_u_id = get_u_id(token) channels = getChannelData() #raises error is channel does not exist if not channel_exists(channel_id): raise InputError('Invalid channel') #raises error is user is not a member of the channel if not user_in_channel(authorised_u_id, channel_id): raise AccessError('User not a member of channel') #removing member from channel for channel in channels: if channel['channel_id'] == channel_id: print("Channel_before:\n", channel['members']) for owner in channel['owners']: if owner['u_id'] == authorised_u_id: channel['owners'].remove(owner) for member in channel['members']: if member['u_id'] == authorised_u_id: channel['members'].remove(member) print("Channels_after:\n", channel['members']) saveChannelData(channels) return {}
def message_edit(token, message_id, message): ''' Function edits message with new message given ''' u_id = get_u_id(token) channel_id = find_channel(message_id) owner = user_is_owner(u_id, channel_id) creator = message_creator(u_id, message_id) permission_id = permission(u_id) #checking if user has authorization to edit message if not creator and not owner and permission_id == 2: raise AccessError("user is not authorised to remove message") #checking if new message is empty strin no_message = False if message == "": no_message = True for channel in channels: for chan_messages in channel['messages']: if chan_messages['message_id'] == message_id: #removing message if empty string if no_message: channel['messages'].remove(chan_messages) #chaning old message to new message else: chan_messages['message'] = message return {}
def channel_removeowner(token, channel_id, u_id): ''' removes owner from channel ''' if not channel_exists(channel_id): raise InputError('Invalid channel_id') if not user_in_channel(get_u_id(token), channel_id): raise AccessError('User not associated with channel') if not user_is_owner(u_id, channel_id) and not user_is_creator( u_id, channel_id): raise InputError('User is not owner') if user_in_channel(get_u_id(token), channel_id) is not None: for channel in channels: if channel['channel_id'] == channel_id: channel['owners'].remove(create_member(u_id)) return {}
def users_all(token): users = getUserData() u_id = get_u_id(token) if (user_exists_persist(int(u_id))): return {"users": users} else: # pragma: no cover cannot test this as not way to fake a invalid token return {}
def channel_addowner(token, channel_id, u_id): ''' adds owner to channel ''' if not channel_exists(channel_id): raise InputError('Invalid channel_id') if not user_in_channel(get_u_id(token), channel_id): raise AccessError('User not associated with channel') if user_is_owner(u_id, channel_id) or user_is_creator(u_id, channel_id): raise InputError('User is already owner') if user_in_channel(get_u_id(token), channel_id) is not None: for channel in channels: if channel['channel_id'] == channel_id: channel['owners'].append(create_member(u_id)) return {}
def message_unreact(token, message_id, react_id): ''' Removes a 'react' to a certain message within a channel the authorised user has joined ''' channel_id = 0 the_message = {} react_found = False # Raising error if message not found if not message_exists(message_id): raise InputError("Message cannot be found in any channel") # Obtaining channel id as well as the message dictionary for channel in channels: for message in channel['messages']: if message['message_id'] == message_id: channel_id = channel['channel_id'] the_message = message break # Getting user_id, and seeing if the user is a member of the channel the_user = get_u_id(token) if not user_in_channel(the_user, channel_id): raise InputError("User is not a member of the message's channel") # Error returned if react_id is invalid if react_id != 1: raise InputError("React_id is not valid") for react in the_message['reacts']: if react_id == react['react_id']: react_found = True break # Error is returned if no reacts of the specified react_id is found in msg if react_found == False: raise InputError("Message does not contain a react of that react_id") # Find react_id and remove user from the users who have used that react for channel in channels: if channel['channel_id'] == channel_id: for message in channel['messages']: if message['message_id'] == message_id: for react in message['reacts']: if react['react_id'] == react_id: react['u_ids'].remove(the_user) # If there are no more users who have used the react # remove it completely from the message if len(react['u_ids']) == 0: message['reacts'].remove(react) break break break return {}
def message_send(token, channel_id, message): ''' Function sends message to channel ''' channel_id = int(channel_id) #check message length if len(message) > 1000: raise InputError("Message too long") #check user send message is in the channel if not user_in_channel(get_u_id(token), channel_id): raise AccessError("User not in channel") #creating timestamp for message now = datetime.now() timestamp = datetime.timestamp(now) m_id = len(messages) + 1 #creating new message dictionary new_message = { 'message_id': m_id, 'u_id': get_u_id(token), 'creator': get_u_id(token), 'message': message, 'time_created': timestamp, 'is_pinned': False, 'reacts': [] } #adding message_id to list messages.append(new_message['message_id']) #appending new message to message list in channel dictionary for channel in channels: if channel['channel_id'] == channel_id: channel['messages'].append(new_message) break return { 'message_id': m_id, }
def channels_listall(token): ''' Lists all currents channels in flock ''' if user_exists(get_u_id(token)): allchannel = [] for channel in channels: allchannel.append({ 'channel_id': channel['channel_id'], 'name': channel['name'] }) return {"channels": allchannel} return None
def channel_messages(token, channel_id, start): ''' returns messages in channel with given index ''' channel_id = int(channel_id) start = int(start) #raises error if channel does not exits if not channel_exists(channel_id): raise InputError('Invalid channel') #raises error is user is not in channel if not user_in_channel(get_u_id(token), channel_id): raise AccessError('User is not in channel') #appends the messages in given channel to new list all_messages = [] for channel in channels: if channel['channel_id'] == channel_id: all_messages = channel['messages'] break #sorts list accoring to time returning lasest message first in the list all_messages = sorted(all_messages, key=lambda k: k['time_created'], reverse=True) total_messages = len(all_messages) #raises error if start index is greating than the amount of messages in the channel if start > (total_messages - 1) and total_messages != 0: raise InputError('Invalid start value') end = start + 50 current_message = start #appending all the messages from the channel to a new list starting from the start index given channel_msg = [] while current_message < end: if current_message == total_messages: end = -1 break channel_msg.append(all_messages[current_message]) current_message += 1 #returning messages dictionary for channel return { 'messages': channel_msg, 'start': start, 'end': end, }
def channels_list(token): ''' Lists all current channels user is apart of ''' u_id = get_u_id(token) user_channels = [] for channel in channels: if user_in_channel(u_id, channel['channel_id']): channel = { 'channel_id': channel['channel_id'], 'name': channel['name'] } user_channels.append(channel) # return user_channels return {"channels": user_channels}
def search(token, query_str): ''' Function finds matching strings to the one given and returns them, only if the user is a member of the channel the message is in ''' message_matches = [] member = create_member(get_u_id(token)) for channel in channels: if member in channel['members']: for msg in channel['messages']: if query_str in msg['message']: message_matches.append(msg) return {"messages": message_matches}
def user_profile_setname(token, name_first, name_last): u_id = get_u_id(token) ''' Checks if the length of the user's name is within the set restrictions ''' if (len(name_first) < 1 or len(name_first) > 50): raise InputError('Invalid First Name') if (len(name_last) < 1 or len(name_last) > 50): raise InputError('Invalid Last Name') for user in users: if user['u_id'] == u_id: user['name_first'] = name_first user['name_last'] = name_last break return {}
def standup_active(token, channel_id): channels = getChannelData() authorised_u_id = get_u_id(token) if not channel_exists_persist(channel_id): raise InputError('Invalid channel') if not user_in_channel_persist(authorised_u_id, channel_id): raise AccessError('User not a member of channel') for channel in channels: if channel['channel_id'] == channel_id: is_active = channel['is_standup'] time_finish = channel['standup_finish'] saveChannelData(channels) return {'is_active': is_active, 'time_finish': time_finish}
def user_profile_setemail(token, email): u_id = get_u_id(token) ''' Checking if the email entered is not a valid email ''' if check(email) == False: raise InputError('Invalid Email') ''' Making sure that the email address is not already being used by another user ''' for user in users: if user['email'] == email: raise InputError('Email is already being used') for user in users: if user['u_id'] == u_id: user['email'] = email break return {}
def channel_details(token, channel_id): channels = getChannelData() ''' Returns the details of the channel ''' channel_id = int(channel_id) u_id = get_u_id(token) if not channel_exists_persist(int(channel_id)): raise InputError('1') if not user_in_channel_persist(int(u_id), int(channel_id)): raise AccessError('2') for channel in channels: if channel['channel_id'] == int(channel_id): return { 'name': channel['name'], 'owner_members': channel['owners'], 'all_members': channel['members'] } return None
def user_profile(token, u_id): ''' For a valid user, return information on the user ''' new_u_id = get_u_id(token) ''' Raise error if user with u_id is not a valid user ''' u_id = int(u_id) for user in users: if not user_exists(new_u_id) or new_u_id != u_id: raise InputError('Invalid User') for user in users: if user['u_id'] == u_id: return { 'u_id': user['u_id'], 'email': user['email'], 'name_first': user['name_first'], 'name_last': user['name_last'], 'handle_str': user['handle_str'], }
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 ''' u_id = get_u_id(token) channel_id = find_channel(message_id) message = find_message(channel_id, message_id) m_id = message_exists(message_id) auth_user = user_in_channel(u_id, channel_id) # Input errors for invalid / already pinned messages if not m_id: raise InputError("Invalid message ID") if message['is_pinned']: raise InputError("Message is already pinned") # Access error for non-owners / unauthorised users if not auth_user: raise AccessError("User is not a member of the channel") message['is_pinned'] = True return {}
def message_unpin(token, message_id): ''' Given a message within a channel, remove its mark as unpinned ''' u_id = get_u_id(token) channel_id = find_channel(message_id) message = find_message(channel_id, message_id) m_id = message_exists(message_id) auth_user = user_in_channel(u_id, channel_id) # Input errors for invalid / already unpinned messages if not m_id: raise InputError("Invalid message ID") if not message['is_pinned']: raise InputError("Message is already unpinned") # Access error for non-owners / unauthorised users if not auth_user: raise AccessError("User is not a member of the channel") message['is_pinned'] = False return {}
def message_react(token, message_id, react_id): ''' Adds a 'react' to a certain message within a channel the authorised user has joined ''' channel_id = 0 the_message = {} react_exists = False # Raising error if message not found if not message_exists(message_id): raise InputError("Message cannot be found in any channel") # Obtaining channel id as well as the message dictionary for channel in channels: for message in channel['messages']: if message['message_id'] == message_id: channel_id = channel['channel_id'] the_message = message break # Getting user_id, and seeing if the user is a member of the channel the_user = get_u_id(token) if not user_in_channel(the_user, channel_id): raise InputError("User is not a member of the message's channel") # Error returned if react_id is invalid if react_id != 1: raise InputError("React_id is not valid") message_reacts = the_message['reacts'] reacted_users = [] for react in message_reacts: if react['react_id'] == react_id: reacted_users = react['u_ids'] break # Error returned if user has already used the react for the message for user in reacted_users: if user == the_user: raise InputError( "User has already used this react for this message") # Find the react in channel message and add in the user to people who've reacted for channel in channels: if channel['channel_id'] == channel_id: for message in channel['messages']: if message['message_id'] == message_id: for react in message['reacts']: if react['react_id'] == react_id: react['u_ids'].append(the_user) react_exists = True break # If react doesn't yet exist for that message add it in if not react_exists: new_react = { 'react_id': react_id, 'u_ids': [the_user], 'is_this_user_reacted': True } message['reacts'].append(new_react) break break return {}