def user_profile_uploadphoto(token, img_url, x_start, y_start, x_end, y_end): """ User uploads profile picture. """ database = DataBase() directory = "src/res/avatar/" user_id = str(database.get_account_info(token)['u_id']) try: avatar_file, header = urllib.request.urlretrieve( img_url, directory + user_id + ".jpg") # No use for header header = str(header) except: raise InputError #Error checking image = Image.open(avatar_file) width, height = image.size if width <= x_end or height <= y_end: raise InputError('Cannot crop picture to specified x, y coordinates') file_list = glob.glob(f'{directory}{user_id}*') if imghdr.what(file_list[0]) != 'jpeg': os.remove(file_list[0]) raise InputError('Picture is not jpg') #Implementation avatar_file_cropped = Image.open(avatar_file) avatar_file_cropped = avatar_file_cropped.crop( (x_start, y_start, x_end, y_end)) avatar_file_cropped.save("src/res/avatar/" + str(database.get_account_info(token)['u_id']) + ".jpg")
def channel_messages(token, channel_id, start): """ Obtain message chain for user in a channel. """ # Open database to get info for error testing database = DataBase() channel = database.get_channel_info(channel_id) channel_member = database.get_account_info(token) # Error checking if not channel: raise InputError('Channel does not exist') if channel_member['permissions'] != OWNER_PERMISSIONS: if channel_member['u_id'] not in channel['members_id']: raise AccessError('Not a member in the channel') if start >= len(channel['messages']) and start != 0: raise InputError('Non-existent message') result = {} result['start'] = start # Use slicing and try statement to slice list of messages if start + 50 > len(channel['messages']): result['end'] = -1 else: result['end'] = start + 50 result['messages'] = channel['messages'][start:start + 50] return result
def channels_create(token, name, is_public): """ Create a channel for a user. """ if len(name) > 20: raise InputError database = DataBase() # Get user channel_creator = database.get_account_info(token) # Get Channel ID and change number of channels database.database_dict['no_channels'] += 1 channel_id = database.database_dict['no_channels'] #We assume that channel_id start from 0->1->2->3->4->... new_channel = { 'standup': { 'user_token': None, 'end': None, 'message': "" }, 'creator_token': channel_creator['u_id'], 'name': name, 'channel_id': channel_id, 'is_public': is_public, 'owners_id': [], 'members_id': [], 'no_sent_messages': 0, 'messages': [] } new_channel['members_id'].append(channel_creator['u_id']) new_channel['owners_id'].append(channel_creator['u_id']) database.database_dict['channels'].append(new_channel) database.close() return {'channel_id': channel_id}
def message_send(token, channel_id, message): """ Send message in channel. """ # Raise error if message is too long if len(message) > 1000: raise InputError('Message over 1000 words') database = DataBase() user_id = database.get_account_info(token)['u_id'] channel = database.get_channel_info(channel_id) # Raise error is user_id is not part of channel. if user_id not in channel['members_id']: raise AccessError('Not a channel member') # Create message_id channel_id_str = str(NO_CHANNELS - channel_id) message_id = channel_id_str + str(channel['no_sent_messages']).zfill(5) message_id += str(user_id) message_id = int(message_id) # Create message_dict dt = datetime.now() timestamp = int(dt.replace(tzinfo=timezone.utc).timestamp()) message_dict = {} message_dict['message_id'] = message_id message_dict['u_id'] = user_id message_dict['message'] = message message_dict['time_created'] = timestamp message_dict['reacts'] = [{'react_id': 1, 'u_ids': [], 'is_this_user_reacted': False}] message_dict['is_pinned'] = False channel['messages'] = [message_dict] + channel['messages'] channel['no_sent_messages'] += 1 database.close() return { 'message_id': message_id, }
def test_user_profile_sethandle_failed_already_exists(user_init): user_profile_sethandle(user_init[1]["token"], "new_handle1") data = DataBase() user_dict = data.get_account_info(user_init[1]["token"]) print(user_dict) with pytest.raises(InputError): user_profile_sethandle(user_init[0]["token"], "new_handle1")
def test_perm_change_access_error(other_init): database = DataBase() admin = database.get_account_info(other_init[0]['token']) admin['permissions'] = 2 database.close() with pytest.raises(AccessError): admin_userpermission_change(other_init[0]['token'], other_init[1]['u_id'], 1)
def test_perm_change(other_init): database = DataBase() admin = database.get_account_info(other_init[0]['token']) admin['permissions'] = 1 database.close() result = admin_userpermission_change(other_init[0]['token'], other_init[1]['u_id'], 1) assert result == {}
def test_user_profile_uploadphoto(user_init): user_profile_uploadphoto( user_init[0]['token'], "https://secure.aspca.org/files/aspca/p2p-campaign-images/user-2660231/guide-dogs_025-11.jpg", 0, 0, 1000, 1000) database = DataBase() fname = "src/res/avatar/" + str( database.get_account_info(user_init[0]['token'])['u_id']) + ".jpg" assert os.path.isfile(fname)
def user_profile_setemail(token, email): """ Change email. """ database = DataBase() user_profile = database.get_account_info(token) if not validate_email(email): raise InputError('Email can\'t be used') user_profile['email'] = email return {}
def message_react(token, message_id, react_id): """ Let users react to messages. """ database = DataBase() channel_id = str(message_id) channel_id = NO_CHANNELS - int(channel_id[0:5]) channel_msgs = database.get_channel_messages(channel_id) message_index = find_message_index(message_id, channel_msgs) msg = channel_msgs[message_index] channel_member_id = database.get_account_info(token)['u_id'] if react_id != 1 or channel_member_id in msg['reacts'][react_id-1]['u_ids']: raise InputError # Add react react = channel_msgs[message_index]['reacts'][react_id - 1] react['is_this_user_reacted'] = True react['u_ids'].append(database.get_account_info(token)['u_id']) database.close() return {}
def user_profile_setname(token, name_first, name_last): """ user sets name. """ database = DataBase() user_profile = database.get_account_info(token) if not validate_names(name_first, name_last): raise InputError user_profile['name_first'] = name_first user_profile['name_last'] = name_last database.close() return {}
def message_unreact(token, message_id, react_id): """ User unreacts to message. """ database = DataBase() channel_id = str(message_id) channel_id = NO_CHANNELS - int(channel_id[0:5]) channel_msgs = database.get_channel_messages(channel_id) message_index = find_message_index(message_id, channel_msgs) #Error checking msg = channel_msgs[message_index] channel_member_id = database.get_account_info(token)['u_id'] if react_id != 1 or channel_member_id not in msg['reacts'][react_id-1]['u_ids']: raise InputError('Not valid react or member hasn\'t reacted') react = msg['reacts'][react_id - 1] if not react['is_this_user_reacted']: raise InputError('No reacts have been made') #Implementation react['u_ids'].remove(database.get_account_info(token)['u_id']) if not react['u_ids']: react['is_this_user_reacted'] = False database.close() return {}
def user_profile_sethandle(token, handle_str): """ Let user modify handle. """ if len(handle_str) > 20 or len(handle_str) < 3: raise InputError('Illegible handle') database = DataBase() user_profile = database.get_account_info(token) users = database.database_dict['users'] for user in users: if handle_str == user['handle_str']: raise InputError('Handle already exists') user_profile['handle_str'] = handle_str database.close() return {}
def channels_list(token): """ Return the user the list of channels they are in. """ # Open database database = DataBase() channel_member = database.get_account_info(token) channel_member_u_id = channel_member['u_id'] # Get member_channels member_channels = [] for channel in database.database_dict['channels']: if channel_member_u_id in channel['members_id']: member_channels.append(channel) member_channels = make_channels_list(member_channels) return {'channels': member_channels}
def search(token, query_str): """ Searches messages for query_str """ database = DataBase() user_id = database.get_account_info(token)['u_id'] channels = database.database_dict['channels'] messages_list = [] for channel in channels: messages = channel['messages'] if user_id in channel['members_id']: for message in messages: if query_str in message['message']: messages_list.append(message) database.close() return {'messages': messages_list}
def admin_userpermission_change(token, u_id, permission_id): """ Change user permissions. """ database = DataBase() user = database.get_info_from_id(u_id) admin = database.get_account_info(token) # Error checking if not user or (permission_id != USER_PERMISSIONS and permission_id != OWNER_PERMISSIONS): raise InputError if admin['permissions'] != OWNER_PERMISSIONS: raise AccessError user['permissions'] = permission_id database.close() return {}
def channel_removeowner(token, channel_id, u_id): """ Remove the ownwer of channel with user with valid channel ownership. """ # Get info for error checking database = DataBase() channel = database.get_channel_info(channel_id) channel_member = database.get_account_info(token) # Check for errors if not channel or u_id not in channel['owners_id']: raise InputError('Channel does not exist or user is not an owner') if (channel_member['u_id'] not in channel['owners_id'] and channel_member['permissions'] != OWNER_PERMISSIONS): raise AccessError('Not an owner of this channel') # Update database channel['owners_id'].remove(u_id) database.close() return {}
def channel_join(token, channel_id): """ Add valid user to channel. """ # Get info from database for error checking database = DataBase() channel = database.get_channel_info(channel_id) joining_member = database.get_account_info(token) # Error checking if not channel: raise InputError('Channel does not exist') if joining_member['permissions'] != OWNER_PERMISSIONS: if not channel['is_public']: raise AccessError('Channel is private') # Update database channel['members_id'].append(joining_member['u_id']) database.close() return {}
def channel_addowner(token, channel_id, u_id): """ Add channel ownwers for user with valid channel ownership. """ # Get info for error checking database = DataBase() channel = database.get_channel_info(channel_id) channel_member = database.get_account_info(token) # Error checking if not channel or u_id in channel['owners_id']: raise InputError('Channel does not exist or user is not an owner') if channel_member['permissions'] != OWNER_PERMISSIONS: if channel_member['u_id'] not in channel['owners_id']: raise AccessError('Not an owner of the channel') # Update database channel['owners_id'].append(u_id) database.close() return {}
def channel_leave(token, channel_id): """ Remove user from channel with valid token. """ # Get info from database for error checking database = DataBase() channel = database.get_channel_info(channel_id) channel_member = database.get_account_info(token) # Error checking if not channel: raise InputError('Channel does not exist') if channel_member['permissions'] != OWNER_PERMISSIONS: if channel_member['u_id'] not in channel['members_id']: raise AccessError('Not a member in the channel') # Change database channel['members_id'].remove(channel_member['u_id']) database.close() return {}
def message_remove(token, message_id): """ Remove message in channel """ database = DataBase() user_id = database.get_account_info(token)['u_id'] channel_id = str(message_id) channel_id = NO_CHANNELS - int(channel_id[0:5]) channel = database.get_channel_info(channel_id) channel_msgs = database.get_channel_messages(channel_id) message_user_id = int(str(message_id)[10:]) # Check users allowed to delete messages if user_id not in channel['owners_id'] and user_id != message_user_id: raise AccessError('Not a member of channel') # Check if message exists to delete in list message_index = find_message_index(message_id, channel_msgs) channel_msgs.pop(message_index) database.close() return {}
def channel_invite(token, channel_id, u_id): """ Invite registered users to channels. """ # Open database and gather channel info and member info database = DataBase() channel = database.get_channel_info(channel_id) channel_member = database.get_account_info(token) add_member = database.get_info_from_id(u_id) # Error testing if not channel or not add_member: raise InputError('Channel doesn\'t exist or member doesn\'t exist') if channel_member['permissions'] != OWNER_PERMISSIONS: if channel_member['u_id'] not in channel['members_id']: raise AccessError('Not a member in the channel') # Update database channel['members_id'].append(u_id) database.close() return {}
def channel_details(token, channel_id): """ Obtain channel details from database with a valid token. """ # Open database amd gather important channel info for error checking database = DataBase() channel = database.get_channel_info(channel_id) channel_member = database.get_account_info(token) # Error checking if not channel: raise InputError('Channel does not exist') if channel_member['permissions'] != OWNER_PERMISSIONS: if channel_member['u_id'] not in channel['members_id']: raise AccessError('Not a member in the channel') result = {} result['name'] = channel['name'] result['owner_members'] = make_user_list(channel['owners_id']) result['all_members'] = make_user_list(channel['members_id']) return result
def message_unpin(token, message_id): """ Unpin messages. """ database = DataBase() channel_id = str(message_id) channel_id = NO_CHANNELS - int(channel_id[0:5]) channel_msgs = database.get_channel_messages(channel_id) message_index = find_message_index(message_id, channel_msgs) # Error checking msg = channel_msgs[message_index] channel = database.get_channel_info(channel_id) channel_member_id = database.get_account_info(token)['u_id'] if channel_member_id not in channel['members_id']: raise AccessError('Not a member in the channel') if not msg['is_pinned']: raise InputError('Message is already unpinnned') # Unpin messages channel_msgs[message_index]['is_pinned'] = False database.close() return {}
def message_sendlater(token, channel_id, message, time_sent): ''' Send message at set time Time_sent can be both integer and timestring ''' #Error checking database = DataBase() channel = database.get_channel_info(channel_id) channel_member = database.get_account_info(token) if not channel or len(message) > 1000 or time_sent < 0: raise InputError if channel_member['u_id'] not in channel['members_id']: raise AccessError('Not a member in the channel') #Implementation with concurrent.futures.ThreadPoolExecutor(1) as exe: def sleep_for(secs): time.sleep(secs) return 1 exe.submit(sleep_for, time_sent) future = exe.submit(message_send, token, channel_id, message) return_val = future.result() return return_val
def message_edit(token, message_id, message): """ Edit messages or delete them. """ # Get channel which message_id attaches itself too database = DataBase() user_id = database.get_account_info(token)['u_id'] channel_id = str(message_id) channel_id = NO_CHANNELS - int(channel_id[0:5]) channel = database.get_channel_info(channel_id) message_user_id = int(str(message_id)[10:]) message_index = find_message_index(message_id, channel['messages']) # Error handling if user_id not in channel['owners_id'] and user_id != message_user_id: raise AccessError('Not member of channel') # Edit or delete message if message: channel['messages'][message_index]['message'] = message else: channel['messages'].pop(message_index) database.close() return {}