def user_profile(token, u_id): check_token(token) user = find_with_uid(u_id) user_info = { 'u_id': user['u_id'], 'email': user['email'], 'name_first': user['name_first'], 'name_last': user['name_last'], 'handle_str': user['handle_str'], 'profile_img_url': user['profile_img_url'] } return {'user': user_info}
def channels_listall(token): # check that the token is valid check_token(token) channels_listalls = {} channel_list = [] channel_info = {} for channel in data['channels']: channel_info = {'channel_id': channel['id'], 'name': channel['name']} channel_list.append(channel_info) channels_listalls['channels'] = channel_list return channels_listalls
def user_profile_setname(token, name_first, name_last): caller = check_token(token) # remove trailing and leading whitespaces fname = name_first.strip() lname = name_last.strip() # check name_first is between 1 and 50 characters if len(fname) < 1 or len(fname) > 50: raise error.InputError( 'First name must be between 1 and 50 characters') # check name_last is between 1 and 50 characters if len(lname) < 1 or len(lname) > 50: raise error.InputError('Last name must be between 1 and 50 characters') caller["name_first"] = fname caller["name_last"] = lname # update the user's details in the channels they're part of for channel in data['channels']: for member in channel['all_members']: if member['u_id'] == caller['u_id']: member['name_first'] = fname member['name_last'] = lname for member in channel['owner_members']: if member['u_id'] == caller['u_id']: member['name_first'] = fname member['name_last'] = lname return {}
def standup_start(token, channel_id, length): # Check that the token is valid caller = check_token(token) # Find the channel target_channel = find_channel(channel_id) # Check to see if caller is part of that channe is_member = is_member_check(caller['u_id'], target_channel) if not is_member: raise error.AccessError('You are not part of the channel') # check for active standup standup = standup_active(token, channel_id) if standup['is_active'] is True: raise error.InputError("There is already an active standup in channel") # finds current time and calculates when standup finishes start_time = round(time.time()) end_time = start_time + length # sets values on target_channel to indicate standup occuring target_channel['standup']['is_standup'] = True target_channel['standup']['time_finish'] = end_time target_channel['standup']['standup_messages'] = [] # make new thread threading.Thread(target=end_standup, args=(target_channel, token, length)).start() return {'time_finish': end_time}
def channel_removeowner(token, channel_id, u_id): # Check that token is valied caller = check_token(token) # Check that user is part of flockr removed_person = find_with_uid(u_id) # Find the channel target_channel = find_channel(channel_id) # Check person to remove is part of channel is_member = is_member_check(caller['u_id'], target_channel) if not is_member: raise error.InputError('User to be removed is not in the channel') # Check to see if caller is an owner is_owner = is_owner_check(caller['u_id'], target_channel) # Access Error if the person calling is not an owner if not is_owner: raise error.AccessError( 'You are not an owner of the channel and cannot add owners') # Check to see if caller is a flockr owner if caller['permission_id'] == 1: is_owner = True # Check to see if the admin is removing a flockr owner if removed_person['permission_id'] == 1: raise error.AccessError('You cannot remove rights from Flockr Owner') # Access Error if the caller is not an owner if not is_owner: raise error.AccessError( 'You are not an owner of the channel and cannot remove owners') # Check to see if removed person is an owner is_owner = is_owner_check(removed_person['u_id'], target_channel) # Input Error if the person to be removed is not owner if not is_owner: raise error.InputError('Person to be demoted is not an owner') # Check to see if we are removing ourselves as owner if caller['u_id'] == removed_person['u_id']: # If we are the only person left in the channel then raise error if len(target_channel['all_members']) == 1: raise error.InputError( 'You are the only person in the channel, you cannot remove yourself as owner, please add another member' ) # If we are the only owner in the channel raise error to indicate a new owner must be assigned elif len(target_channel['owner_members']) == 1: raise error.InputError( 'You are the only owner in the channel, please make someone else owner before removing yourself' ) # Otherwise, we can remove self as owner else: remove_helper_func(channel_id, removed_person) return {} # We can remove the person as owner remove_helper_func(channel_id, removed_person) return {}
def message_remove(token, message_id): # Check that the token is valid caller = check_token(token) # Find the message in the message field of data target_message = find_message_in_messages(message_id) # Find the channel the message is in target_channel = find_channel(target_message['channel_id']) # Check to see if the caller has the right to remove the message is_allowed = False # 1) Caller u_id == target_message u_id if caller['u_id'] == target_message['u_id']: is_allowed = True # 2) Caller is channel owner if not is_allowed: is_allowed = is_owner_check(caller['u_id'], target_channel) # 3) Caller is flockr owner if not is_allowed: if caller['permission_id'] == 1: is_allowed = True # If permission is found then remove the message, else access error if is_allowed: for i, message in enumerate(target_channel['messages']): if message['message_id'] == target_message['message_id']: del target_channel['messages'][i] for i, message in enumerate(data['messages']): if message_id == message['message_id']: del data['messages'][i] return {} raise error.AccessError('You are not allowed to remove the message')
def message_sendlater(token, channel_id, message, time_sent): # Check that the token is valid caller = check_token(token) # Capture the current time asap current_time = (datetime.datetime.now()).timestamp() # Find the channel target_channel = find_channel(channel_id) # Check to see if caller is part of that channel is_member = is_member_check(caller['u_id'], target_channel) # Access Error if the person inviting is not within the server if not is_member: raise error.AccessError( 'You are not part of the channel you want to send messages to') # Check the message length for issues if len(message) > 1000 or len(message) < 1 or len(message.strip()) < 1: raise error.InputError( 'The message you are sending is over 1000 characters') # Check the time is not from before current if (time_sent - current_time) < 0: raise error.InputError('Trying to send message in the past') delay = time_sent - current_time threading.Timer(delay, send_message, kwargs={ 'caller': caller, 'message': message, 'target_channel': target_channel, 'channel_id': channel_id }).start()
def standup_send(token, channel_id, message): # check for valid token caller = check_token(token) # check valid channel target_channel = find_channel(channel_id) # check if user is in channel is_member = is_member_check(caller['u_id'], target_channel) if not is_member: raise error.AccessError('You are not part of the channel') # check the message length for issues if len(message) > 1000 or len(message) < 1 or len(message.strip()) < 1: raise error.InputError( 'Invalid message. Please shorten to less than 1000 characters.') # check for active standup standup = standup_active(token, channel_id) if standup['is_active'] is False: raise error.InputError("There is already an active standup in channel") # throw error if message is user trying to start standup if message.startswith('/standup'): raise error.InputError("There is already an active standup in channel") # update standup with message and user's details target_channel['standup']['standup_messages'].append(caller['name_first'] + ': ' + message) return {}
def message_unpin(token, message_id): # check for valid user caller = check_token(token) # check for valid message_id target_message = find_message_in_messages(message_id) if not target_message['is_pinned']: raise error.InputError('Message is not pinned') # Find the channel the message is in target_channel = find_channel(target_message['channel_id']) # Check to see if caller is part of that channel is_member = is_member_check(caller['u_id'], target_channel) if not is_member: raise error.AccessError('You are not part of this channel.') # check user is owner is_allowed = is_owner_check(caller['u_id'], target_channel) if not is_allowed: raise error.AccessError('You do not have permission to unpin message') for message in target_channel['messages']: if message['message_id'] == message_id: message['is_pinned'] = False for message in data['messages']: if message_id == message['message_id']: message['is_pinned'] = False return {}
def message_unreact(token, message_id, react_id): # Make sure react_id is valid thumbs_up = 1 if react_id != thumbs_up: raise error.InputError('Invalid react_id') # check for valid user user = check_token(token) # Find the message in the message field of data target_message = {} for message_value in data['messages']: if message_id == message_value['message_id']: target_message = message_value # InputError if message doesnt exist if target_message == {}: raise error.InputError('Message does not exist') # Find the channel the message is in target_channel = find_channel(target_message['channel_id']) # Remove u_id in messages for react type for reacts in target_message['reacts']: if react_id == reacts['react_id']: reacts['u_ids'].remove(user['u_id']) # update channel['messages'] with react data as well for channel_message in target_channel['messages']: if channel_message['message_id'] == target_message['message_id']: for reacts in channel_message['reacts']: if react_id == reacts['react_id']: reacts['u_ids'].remove(user['u_id']) return {}
def channel_messages(token, channel_id, start): # Check that the token is valid caller = check_token(token) # Find the channel target_channel = find_channel(channel_id) # Check to see if calling is part of that channel is_member = is_member_check(caller['u_id'], target_channel) # Access Error if the person inviting is not within the server if not is_member: raise error.AccessError( 'You are not part of the channel you want details about') # Made it through all checks so now we start building the return # Looping through the message data of the channel message_data = [] number_of_messages = len(target_channel['messages']) message_number = start end = 0 # Check if start is beyond range of messages if start > number_of_messages: raise error.InputError( 'The start value entered is older than all messages') # Check to see if start is the least recent message elif start == (number_of_messages - 1): message = target_channel['messages'][start] if len(message['reacts']) > 0: for reacts in message['reacts']: reacts['is_this_user_reacted'] = False for u_id in reacts['u_ids']: if u_id == caller['u_id']: reacts['is_this_user_reacted'] = True message_data.append(message) return { 'messages': message_data, 'start': start, 'end': -1, } # We can iterate from start until either end or start + 50 else: while (message_number < number_of_messages) and (end <= start + 49): message = target_channel['messages'][message_number] if len(message['reacts']) > 0: for reacts in message['reacts']: reacts['is_this_user_reacted'] = False for u_id in reacts['u_ids']: if u_id == caller['u_id']: reacts['is_this_user_reacted'] = True message_data.append(message) message_number += 1 end += 1 return { 'messages': message_data, 'start': start, 'end': end, }
def user_profile_uploadphoto(token, img_url, x_start, y_start, x_end, y_end): #Check that the token is valid caller = check_token(token) file_path = f'src/static/{caller["u_id"]}.jpeg' urllib.request.urlretrieve(img_url, file_path) try: img = Image.open(file_path) except UnidentifiedImageError: raise error.InputError('Please upload an image') #img = Image.open(BytesIO(response.content)) #Identifies size of image and calculates the size of the crop image width, height = img.size heightv = [y_start, y_end] widthv = [x_start, x_end] #Ensures all values are within the bound of the original image for y_value in heightv: if y_value < 0: raise error.InputError('Please enter non-negative values') if y_value > height: raise error.InputError('Please enter smaller values') for x_value in widthv: if x_value < 0: raise error.InputError('Please enter non-negative values') if x_value > width: raise error.InputError('Please enter smaller values') #Ensures requested width or height is not negative or zero c_width = y_end - y_start c_height = x_end - x_start if (c_width <= 0) or (c_height <= 0): raise error.InputError('Please enter a proper length') #Checks that the image is in jpeg format if img.format.lower() == 'jpeg': cropped = img.crop((x_start, y_start, x_end, y_end)) img.close() cropped.save(file_path) caller[ "profile_img_url"] = request.host_url + f'static/{caller["u_id"]}.jpeg' for channel in data['channels']: for owner in channel['owner_members']: if caller['u_id'] == owner['u_id']: owner[ "profile_img_url"] = request.host_url + f'static/{caller["u_id"]}.jpeg' break for member in channel['all_members']: if caller['u_id'] == member['u_id']: member[ "profile_img_url"] = request.host_url + f'static/{caller["u_id"]}.jpeg' break return {} else: raise error.InputError('Image url is not a JPG')
def auth_logout(token): try: user = check_token(token) except: return {'is_success': False} flag = False if user['token'] == token: for info in data['users']: if info == user: flag = True user['token'] = "False" break return {'is_success': flag}
def channel_join(token, channel_id): # Check that the token is valid caller = check_token(token) # Find the channel target_channel = find_channel(channel_id) # If caller is flockr owner then add them to the channel and make them an owner if caller['permission_id'] == 1: target_channel['all_members'].append({ 'u_id': caller['u_id'], 'name_first': caller['name_first'], 'name_last': caller['name_last'], 'profile_img_url': caller['profile_img_url'] }) target_channel['owner_members'].append({ 'u_id': caller['u_id'], 'name_first': caller['name_first'], 'name_last': caller['name_last'], 'profile_img_url': caller['profile_img_url'] }) return {} # Otherwise, check to see if the channel they are joining is private if not target_channel['is_public']: raise error.AccessError( 'The channel you are trying to join is private') else: # Channel is public so we add their details into the channel list target_channel['all_members'].append({ 'u_id': caller['u_id'], 'name_first': caller['name_first'], 'name_last': caller['name_last'], 'profile_img_url': caller['profile_img_url'] }) return {}
def message_send(token, channel_id, message): # Check that the token is valid caller = check_token(token) # Find the channel target_channel = find_channel(channel_id) # Check to see if caller is part of that channel is_member = is_member_check(caller['u_id'], target_channel) # Access Error if the person inviting is not within the server if not is_member: raise error.AccessError( 'You are not part of the channel you want to send messages to') # Check the message length for issues if len(message) > 1000 or len(message) < 1 or len(message.strip()) < 1: raise error.InputError( 'The message you are sending is over 1000 characters') # message gets added to the channel's message key if len(data['messages']) == 0: message_id = 0 else: message_id = data['messages'][0]['message_id'] + 1 time_created = round((datetime.datetime.now()).timestamp()) channel_message = { 'message_id': message_id, 'u_id': caller['u_id'], 'message': message, 'time_created': time_created, 'reacts': [], 'is_pinned': False, } target_channel['messages'].insert(0, channel_message) # adding data to messages for easier searching message_data = { 'message_id': message_id, 'u_id': caller['u_id'], 'message': message, 'time_created': time_created, 'channel_id': channel_id, 'reacts': [], 'is_pinned': False, } data['messages'].insert(0, message_data) return {'message_id': message_id}
def channels_list(token): # Check that the token is valid caller = check_token(token) u_id = caller['u_id'] channels = {} channel_list = [] channel_info = {} # get all channels info for channel in data['channels']: for member_id in channel['all_members']: if member_id['u_id'] == u_id: channel_info = { 'channel_id': channel['id'], 'name': channel['name'] } channel_list.append(channel_info) channels['channels'] = channel_list return channels
def channel_addowner(token, channel_id, u_id): # Check that the token is valid caller = check_token(token) # Checks that user is part of the flockr added_person = find_with_uid(u_id) # Find the channel target_channel = find_channel(channel_id) # Check to see if caller is an owner is_owner = is_owner_check(caller['u_id'], target_channel) # Access Error if the person calling is not an owner if not is_owner: raise error.AccessError( 'You are not an owner of the channel and cannot add owners') # We know the caller is an owner, now we see if they are adding themselves as owner if added_person['u_id'] == caller['u_id']: raise error.InputError('You are already an owner of this channel') # If we are here then we can proceed to check if the person to be promoted is in the channel is_member = is_member_check(added_person['u_id'], target_channel) # Input Error if the user doesn't exist if not is_member: raise error.InputError('User to be promoted is not in the channel') # We now check if the person to be promoted is already and owner is_owner = is_owner_check(added_person['u_id'], target_channel) if is_owner: raise error.InputError( 'The person you are trying promote is already an owner') # We can now promote the user to owner target_channel['owner_members'].append({ 'u_id': added_person['u_id'], 'name_first': added_person['name_first'], 'name_last': added_person['name_last'], 'profile_img_url': added_person['profile_img_url'] }) return {}
def channel_invite(token, channel_id, u_id): # Check that the token is valid inviter = check_token(token) # Check if user to be added exists within database invitee = find_with_uid(u_id) # Find the channel target_channel = find_channel(channel_id) # Check to see if inviter is part of that channel is_member = is_member_check(inviter['u_id'], target_channel) if not is_member: raise error.AccessError('You are not a member of the channel') # Check to see if invitee is part of that channel is_member = is_member_check(invitee['u_id'], target_channel) if is_member: raise error.InputError('User is already part of the channel') # Made it through all the checks so now we can add the invitee target_channel['all_members'].append({ 'u_id': invitee['u_id'], 'name_first': invitee['name_first'], 'name_last': invitee['name_last'], 'profile_img_url': invitee['profile_img_url'], }) # Also if permission_id is 1, then make them an owner if invitee['permission_id'] == 1: target_channel['owner_members'].append({ 'u_id': invitee['u_id'], 'name_first': invitee['name_first'], 'name_last': invitee['name_last'], 'profile_img_url': invitee['profile_img_url'], }) return {}
def standup_active(token, channel_id): # Check that the token is valid caller = check_token(token) # Find the channel target_channel = find_channel(channel_id) # Check to see if caller is part of that channel is_member = is_member_check(caller['u_id'], target_channel) if not is_member: raise error.AccessError('You are not part of the channel') # check for active standup if target_channel['standup']['is_standup']: return { 'is_active': True, 'time_finish': target_channel['standup']['time_finish'] } return {'is_active': False, 'time_finish': None}
def end_standup(target_channel, token, length): time.sleep(length) # update channel with end standup target_channel['standup']['is_standup'] = False target_channel['standup']['time_finish'] = None # join all messages into standup_messages separated by new line standup_messages = '\n'.join(target_channel['standup']['standup_messages']) # get user caller = check_token(token) # send standup_messages from the user who called the standup send_message(caller, standup_messages, target_channel, target_channel['id']) # clear messages from standup buffer for old_message in target_channel['standup']['standup_messages']: target_channel['standup']['standup_messages'].remove(old_message)
def message_edit(token, message_id, message): caller = check_token(token) # Find the message in the message field of data target_message = find_message_in_messages(message_id) # Find the channel the message is in target_channel = find_channel(target_message['channel_id']) # Check to see if the caller has the right to remove the message is_allowed = False # 1) Caller u_id == target_message u_id if caller['u_id'] == target_message['u_id']: is_allowed = True # 2) Caller is channel owner if not is_allowed: is_allowed = is_owner_check(caller['u_id'], target_channel) # 3) Caller is flockr owner if not is_allowed: if caller['permission_id'] == 1: is_allowed = True if not is_allowed: raise error.AccessError('You do not have permission to edit message') # If the message parsed in all white space or empty, then remove message_length = len(message.strip()) if message_length == 0: message_remove(token, message_id) return {} for message_data in target_channel['messages']: if message_id == message_data['message_id']: message_data['message'] = message for messages in data['messages']: if message_id == messages['message_id']: messages['message'] = message return {}
def channel_details(token, channel_id): # Check that the token is valid caller = check_token(token) # Find the channel target_channel = find_channel(channel_id) # Check to see if calling is part of that channel is_member = is_member_check(caller['u_id'], target_channel) # Access Error if the person inviting is not within the server if not is_member: raise error.AccessError( 'You are not part of the channel you want details about') # Made it through all checks so now we start building the return channel_name = target_channel['name'] # Append owner details channel_owners = [] for owner in target_channel['owner_members']: channel_owners.append({ 'u_id': owner['u_id'], 'name_first': owner['name_first'], 'name_last': owner['name_last'], 'profile_img_url': owner['profile_img_url'] }) # Append member details channel_members = [] for member in target_channel['all_members']: channel_members.append({ 'u_id': member['u_id'], 'name_first': member['name_first'], 'name_last': member['name_last'], 'profile_img_url': member['profile_img_url'] }) return { 'name': channel_name, 'owner_members': channel_owners, 'all_members': channel_members, }
def channels_create(token, name, is_public): # Check the token is valid caller = check_token(token) # Check channel name length if len(name) > 20: raise error.InputError('Channel name is more than 20 characters') # Assigning channel ID, empty = 0 else last ID+1 if len(data['channels']) == 0: channel_id = 0 else: channel_id = data['channels'][-1]['id'] + 1 data['channels'].append({ 'id': channel_id, 'name': name, 'is_public': is_public, 'owner_members': [{ 'u_id': caller['u_id'], 'name_first': caller['name_first'], 'name_last': caller['name_last'], 'profile_img_url': caller['profile_img_url'] }], 'all_members': [{ 'u_id': caller['u_id'], 'name_first': caller['name_first'], 'name_last': caller['name_last'], 'profile_img_url': caller['profile_img_url'] }], 'messages': [], 'standup': { 'is_standup': False, 'time_finish': None }, }) return {'channel_id': channel_id}
def user_profile_setemail(token, email): caller = check_token(token) # remove trailing and leading whitespaces from input email = email.strip() # check for valid email if not email_check(email): raise error.InputError('Entered email is not valid') # check user isn't trying to update the same email if email == caller["email"]: raise error.InputError("Entered email is same as current email.") # check for existing email check_existing_email(email) # update field in user caller["email"] = email return {}
def user_profile_sethandle(token, handle_str): #Check that the token is valid caller = check_token(token) # remove trailing and leading whitespaces from input handle_str = handle_str.strip() handle_str_len = len(handle_str.strip()) if handle_str_len > 20 or handle_str_len < 3: raise error.InputError( 'User handle must be between 3 and 20 characters.') #check that the handle is not already used for other_user in data['users']: if handle_str == other_user['handle_str']: raise error.InputError( 'User handle is already used by another user') # update handle caller['handle_str'] = handle_str return {}
def channel_leave(token, channel_id): # Check that the token is valid caller = check_token(token) # Find the channel target_channel = find_channel(channel_id) # Check to see if inviter is part of that channel is_member = is_member_check(caller['u_id'], target_channel) # Access Error if the person calling is not within the server if not is_member: raise error.AccessError( 'You are not a member of the channel you are trying to leave') # Check if the user is the only owner but other members exist, input error if so is_owner = False for owner in target_channel['owner_members']: if owner['u_id'] == caller['u_id']: is_owner = True if len(target_channel['owner_members']) == 1 and len( target_channel['all_members']) != 1: raise error.InputError( 'Please make another member an owner before leaving') # If the user is an owner, remove them from the owner list if is_owner: for owner in target_channel['owner_members']: if owner['u_id'] == caller['u_id']: target_channel['owner_members'].remove(owner) # Navigate to the user entry in all members and remove them for user in target_channel['all_members']: if user['u_id'] == caller['u_id']: target_channel['all_members'].remove(user) # If there is now no one in the channel, delete the channel if len(target_channel['all_members']) == 0: for i, channel in enumerate(data['channels']): if channel['id'] == channel_id: del data['channels'][i] return {}
def http_user_profile_uploadphoto(): data = request.json user.user_profile_uploadphoto(data['token'], data['img_url'], int(data['x_start']), int(data['y_start']), int(data['x_end']), int(data['y_end'])) caller = other.check_token(data['token']) return send_from_directory(APP.static_folder, f'{caller["u_id"]}.jpeg')
def message_react(token, message_id, react_id): # Make sure react_id is valid thumbs_up = 1 if react_id != thumbs_up: raise error.InputError('Invalid react_id') # check for valid user user = check_token(token) # Find the message in the message field of data target_message = find_message_in_messages(message_id) # Find the channel the message is in target_channel = {} channel_index = 0 for channel in data['channels']: if target_message['channel_id'] == channel['id']: target_channel = channel break channel_index += 1 # Make sure the user is in the channel channel_check = 0 for members in target_channel['all_members']: if user['u_id'] == members['u_id']: channel_check += 1 # InputError if channel does not exist if target_channel == {}: raise error.InputError('You are trying to access an invalid channel') append_flag = 0 # Add react to u_id in messages for react type if react is not found for reacts in target_message['reacts']: if react_id == reacts['react_id']: reacts['u_ids'].append(user['u_id']) append_flag += 1 if append_flag == 1: break else: target_message['reacts'].append({ 'react_id': react_id, 'u_ids': [ user['u_id'], ], 'is_this_user_reacted': False, }) append_flag = 0 # update channel['messages'] with react data as well for channel_message in target_channel['messages']: if channel_message['message_id'] == target_message['message_id']: for reacts in channel_message['reacts']: if react_id == reacts['react_id']: reacts['u_ids'].append(user['u_id']) append_flag += 1 if append_flag == 1: break else: channel_message['reacts'].append({ 'react_id': react_id, 'u_ids': [ user['u_id'], ], 'is_this_user_reacted': False, }) return {}