def message_unpin(token, message_id): """Given a message within a channel, remove it's mark as unpinned""" # Validate token if not validator.is_valid_token(token): raise ValueError(INVALID_TOKEN) # Decode token u_id = jwt_handler.decode_token(token) user = database.get_user_by_id(u_id) message = database.get_message_by_id(message_id) if message is None: raise ValueError(MESSAGE_UNPIN_NOT_EXIST) channel = database.get_channel_by_id(message["channel_id"]) if user["permission"] not in [OWNER, ADMIN] \ and u_id not in channel["owner_ids"]: raise AccessError(MESSAGE_UNPIN_NO_AUTH) # Checking data if u_id not in channel["auth_ids"]: raise AccessError(CHANNEL_CANT_VIEW_DETAIL) if message["is_pinned"] is False: raise ValueError(MESSAGE_NOT_PINNED) # Unpinning message database.update_message_by_id(message_id, {"is_pinned": False}) return {}
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 """ # Validate token if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) # Decode token u_id = jwt_handler.decode_token(token) user = database.get_user_by_id(u_id) message = database.get_message_by_id(message_id) if message is None: raise ValueError(MESSAGE_PIN_NOT_EXIST) channel = database.get_channel_by_id(message["channel_id"]) if user["permission"] not in [OWNER, ADMIN] \ and u_id not in channel["owner_ids"]: raise ValueError(MESSAGE_PIN_NO_AUTH) # Checking data if u_id not in channel["auth_ids"]: raise AccessError(CHANNEL_CANT_VIEW_DETAIL) if message["is_pinned"] is True: raise ValueError(MESSAGE_ALREADY_PINNED) # Pinning message database.update_message_by_id(message_id, {"is_pinned": True}) return {}
def channel_removeowner(token, channel_id, u_id): """Remove user with user id u_id an owner of this channel""" # Convert channel_id and u_id to integer channel_id = int(channel_id) u_id = int(u_id) # Validate token, channel and user if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) if not validator.is_valid_channel(channel_id): raise ValueError(INVALID_CHANNEL) if not validator.is_valid_user(u_id): raise ValueError(INVALID_USER) # Locate channel and user in database channel = database.get_channel_by_id(channel_id) auth_user_id = jwt_handler.decode_token(token) auth_user = database.get_user_by_id(auth_user_id) owner_list = channel["owner_ids"] if auth_user["permission"] not in [OWNER, ADMIN] or\ auth_user_id not in channel["owner_ids"]: raise AccessError(CHANNEL_DEL_OWNER_NO_AUTH) # Check that the added_user is currently an owner if u_id not in owner_list: raise ValueError(CHANNEL_NOT_OWNER) # Remove user from owner_ids owner_list.remove(u_id) database.update_channel_by_id(channel_id, { "owner_ids": owner_list }) return {}
def admin_userpermission_change(token, u_id, permission_id): """Given a User by their user ID, set their permissions to new permissions described by permission_id""" permission_id = int(permission_id) # Check validity if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) if not validator.is_valid_user(u_id): raise ValueError(INVALID_USER) if permission_id not in [OWNER, ADMIN, MEMBER]: raise ValueError(INVALID_PERM_ID) # Get users user_acting = database.get_user_by_id(jwt_handler.decode_token(token)) user_target = database.get_user_by_id(u_id) # Check that token has valid permissions for this permission id, then make # the change if user_acting["permission"] == OWNER: # Owners can do anything database.update_user_by_id(u_id, {"permission": permission_id}) elif user_acting["permission"] == ADMIN and\ user_target["permission"] != OWNER and\ permission_id != OWNER: database.update_user_by_id(u_id, {"permission": permission_id}) else: raise AccessError(NO_PERMISSION) return {}
def channel_join(token, channel_id): """Given a channel_id of a channel that the authorised user can join, adds them to that channel""" # Validate token and channel ID if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) if not validator.is_valid_channel(channel_id): raise ValueError(INVALID_CHANNEL) # Convert token to u_id u_id = jwt_handler.decode_token(token) user = database.get_user_by_id(u_id) # Locate channel in database channel = database.get_channel_by_id(channel_id) # If channel is private if not channel["is_public"] and user["permission"] == MEMBER: # If the user is not an admin/owner raise AccessError(CHANNEL_CANT_VIEW_DETAIL) # Add user to authorised users in channel auth_list = channel["auth_ids"] if u_id not in auth_list: auth_list.append(u_id) database.update_channel_by_id(channel_id, { "auth_ids": auth_list }) else: raise ValueError(CHANNEL_ALREADY_JOINED) return {}
def message_edit(token, message_id, message): """Given a message, update it's text with new text""" # Validate token if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) # If the message is empty, perform deletion instead if message == "": return message_remove(token, message_id) if not validator.is_valid_message(message): raise ValueError(INVALID_MESSAGE) # Convert token to u_id u_id = jwt_handler.decode_token(token) user = database.get_user_by_id(u_id) message_dict = database.get_message_by_id(message_id) if message_dict is None: raise ValueError(MESSAGE_EDIT_NOT_EXIST) channel_id = message_dict["channel_id"] channel = database.get_channel_by_id(channel_id) # Check if user can edit this message if u_id == message_dict["u_id"] or user["permission"] in [OWNER, ADMIN] \ or u_id in channel["owner_ids"]: database.update_message_by_id(message_id, {"message": message}) return {} raise AccessError(MESSAGE_EDIT_NO_AUTH)
def channel_invite(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""" # Convert channel_id and u_id to integer channel_id = int(channel_id) u_id = int(u_id) # Validate token, channel and user if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) if not validator.is_valid_channel(channel_id): raise ValueError(INVALID_CHANNEL) if not validator.is_valid_user(u_id): raise ValueError(INVALID_USER) # Find invitor invitor_id = jwt_handler.decode_token(token) # Locate channel in database channel = database.get_channel_by_id(channel_id) # Check that the invitor is authorised auth_list = channel["auth_ids"] if invitor_id not in auth_list: raise AccessError(CHANNEL_INV_NO_AUTH) if u_id in auth_list: raise ValueError(CHANNEL_ALREADY_JOINED) auth_list.append(u_id) database.update_channel_by_id(channel_id, { "auth_ids": auth_list }) return {}
def message_sendlater(token, channel_id, message, time_sent): """ Send a message from authorised_user to the channel specified by channel_id """ # Validate data if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) if not validator.is_valid_message(message): raise ValueError(INVALID_MESSAGE) # Convert token to u_id u_id = jwt_handler.decode_token(token) # Check channel exists channel = database.get_channel_by_id(channel_id) if channel is None: raise ValueError(INVALID_CHANNEL) # Read time_sent time_to_send = json_time_translator.timestamp_to_datetime(time_sent) # Check time_to_send is not in the past if time_to_send <= datetime.utcnow(): raise ValueError(MESSAGE_TIME_INVALID) if u_id not in channel["auth_ids"]: raise AccessError(MESSAGE_SEND_NO_AUTH) # Create message message_id = database.add_message({ "u_id": u_id, "message": message, "channel_id": int(channel_id), "time_created": json_time_translator.datetime_to_json(time_to_send), "is_pinned": False, "reacts": [] }) # Insert into channel's list of messages in order of time message_id_list = channel["messages"] inserted = False for i in reversed(range(len(message_id_list))): json_time = database.get_message_by_id( message_id_list[i])["time_created"] timestamp = json_time_translator.json_to_timestamp(json_time) if timestamp <= int(float(time_sent)): message_id_list.insert(i + 1, message_id) inserted = True break if inserted is False: message_id_list.insert(0, message_id) database.update_channel_by_id(channel_id, {"messages": message_id_list}) return {"message_id": message_id}
def message_react(token, message_id, react_id): """ Given a message within a channel the authorised user is part of, add a "react" to that particular message """ # Validate if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) # Decode token u_id = jwt_handler.decode_token(token) # Change react_id to an integer if not isinstance(react_id, int): react_id = int(react_id) if not isinstance(message_id, int): message_id = int(message_id) # Validate data message = database.get_message_by_id(message_id) channel = database.get_channel_by_id(message["channel_id"]) if u_id not in channel["auth_ids"]: raise AccessError(CHANNEL_CANT_VIEW_DETAIL) if react_id != 1: print(react_id) raise ValueError(INVALID_REACT) react_id_exists = False for react in message["reacts"]: if react_id == react["react_id"]: react_id_exists = True if u_id in react["u_id"]: raise ValueError(MESSAGE_ALREADY_REACTED) break # Add react to message react_list = message["reacts"] if not react_id_exists: react_list.append({"react_id": react_id, "u_id": [u_id]}) else: for react in react_list: if react_id == react["react_id"]: react["u_id"].append(u_id) break database.update_message_by_id(message_id, {"reacts": react_list}) return {}
def auth_passwordreset_request(email): """Given an email address, if the user is a registered user, send's them a an email containing a specific secret code, that when entered in auth_passwordreset_reset, shows that the user trying to reset the password is the one who got sent this email.""" # Validate data users = database.get_all_users() if validator.is_unique_email(email): raise ValueError(EMAIL_NOT_FOUND) for user in users: if user["email"] == email: # Deletes previous reset code if user["pw_reset_code"] != "": code_generator.delete_reset_code(user["pw_reset_code"]) reset_code_str = code_generator.generate_code() database.update_user_by_id(user["u_id"], {"pw_reset_code": reset_code_str}) # Sends email with reset_code mail = Mail(current_app) try: msg = Message("Password reset from COMP1531", sender="*****@*****.**", recipients=[email]) msg.body = reset_code_str mail.send(msg) except Exception as excp: print(str(excp)) return {}
def channel_leave(token, channel_id): """Given a channel ID, the user removed as a member of this channel""" # Validate token and channel ID if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) if not validator.is_valid_channel(channel_id): raise ValueError(INVALID_CHANNEL) # Convert token to u_id u_id = jwt_handler.decode_token(token) # Locate channel channel = database.get_channel_by_id(channel_id) # Validate user is in channel auth_list = channel["auth_ids"] if u_id not in auth_list: raise AccessError(NOT_IN_CHANNEL) # Remove user from auth_list auth_list.remove(u_id) database.update_channel_by_id(channel_id, { "auth_ids": auth_list }) # If owner, remove from owner_list owner_list = channel["owner_ids"] if u_id in owner_list: owner_list.remove(u_id) database.update_channel_by_id(channel_id, { "owner_ids": owner_list }) return {}
def message_remove(token, message_id): """ Given a message_id for a message, this message is removed from the chxnel """ # Validate token if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) if not isinstance(message_id, int): message_id = int(message_id) # Convert token to u_id u_id = jwt_handler.decode_token(token) # Check u_id is authorised user = database.get_user_by_id(u_id) message = database.get_message_by_id(message_id) if message is None: raise ValueError(MESSAGE_REMOVE_NOT_EXIST) channel_id = message["channel_id"] channel = database.get_channel_by_id(channel_id) # if sender of message if u_id == message["u_id"] or\ user["permission"] in [OWNER, ADMIN] or\ u_id in channel["owner_ids"]: # Delete message from database database.delete_message_by_id(message_id) # Delete message from channel channel["messages"].remove(message_id) database.update_channel_by_id(channel_id, channel) return {} raise AccessError(MESSAGE_EDIT_NO_AUTH)
def standup_start(token, channel_id, length): """Will return standup finish time if user and channel are both valid""" # Check valid token if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) length = int(length) # Check channel existence channel = database.get_channel_by_id(channel_id) if channel is None: raise ValueError(INVALID_CHANNEL) # Check user is member of channel u_id = jwt_handler.decode_token(token) if u_id not in channel["auth_ids"]: raise AccessError(CHANNEL_CANT_VIEW_DETAIL) # Check the startup is not currently active in this channel old_time_end = database.get_standup_finish_time(channel_id) if old_time_end is not None and\ json_time_translator.json_to_datetime(old_time_end) >= datetime.utcnow(): raise ValueError(STANDUP_RUNNING) # Check for non-zero length if length <= 0: raise ValueError(STANDUP_TIME_INVALID) # Set channel standup_end to now+X min and add finish time to database time_end_datetime = datetime.utcnow() + timedelta(seconds=length) time_end_json = json_time_translator.datetime_to_json(time_end_datetime) # Move old standup messages database.move_standup_to_unused_by_id(channel_id) database.update_standup_by_id(channel_id, { "time_finish": time_end_json, "length": length }) time_end_timestamp = int( json_time_translator.datetime_to_timestamp(time_end_datetime)) # Start threaded timer standup_timer_start(token, channel_id, length) return {"time_finish": time_end_timestamp}
def message_unreact(token, message_id, react_id): """ Given a message within a channel the authorised user is part of, remove a "react" to that particular message """ # Validate if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) # Decode token u_id = jwt_handler.decode_token(token) # Change react_id to an integer if not isinstance(react_id, int): react_id = int(react_id) if not isinstance(message_id, int): message_id = int(message_id) # Validate data message = database.get_message_by_id(message_id) channel = database.get_channel_by_id(message["channel_id"]) if u_id not in channel["auth_ids"]: raise AccessError(CHANNEL_CANT_VIEW_DETAIL) if react_id != 1: print(react_id) raise ValueError(INVALID_REACT) react_list = message["reacts"] react_found = False for react in react_list: if react_id == react["react_id"] and u_id in react["u_id"]: react_found = True break if not react_found: raise ValueError(MESSAGE_NOT_REACTED) # Remove react from message for react in react_list: if react_id == react["react_id"]: react["u_id"].remove(u_id) database.update_message_by_id(message_id, {"reacts": react_list}) return {}
def user_profiles_uploadphoto(token, img_url, x_start, y_start, x_end, y_end): """Given a URL of an image on the internet, crops the image within bounds (x_start, y_start) and (x_end, y_end). Position (0,0) is the top left.""" # Check valid token if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) x_start = int(x_start) y_start = int(y_start) x_end = int(x_end) y_end = int(y_end) if img_url[-3:].lower() != "jpg" and img_url[-4:].lower() != "jpeg": raise ValueError(IMAGE_NOT_JPG) # Save Image file_name = json_time_translator.datetime_to_timestamp(datetime.utcnow()) local_url = f"server_files/static/{file_name}" try: urlretrieve(img_url, local_url + ".jpg") except Exception: raise ValueError(IMAGE_CANT_FETCH) image_object = Image.open(local_url + ".jpg") width, height = image_object.size if not 0 <= x_start < width or not 0 < x_end <= width or not \ 0 <= y_start < height or not 0 < y_end <= height: raise ValueError(INVALID_COORDINATES) if x_end <= x_start or y_end <= y_start: raise ValueError(INVALID_CROP) cropped = image_object.crop((x_start, y_start, x_end, y_end)) cropped.save(local_url + "_crop.jpg") # Change current user's profile image u_id = jwt_handler.decode_token(token) database.update_user_by_id(u_id, { "profile_img_url": f"http://127.0.0.1:5001/static/{file_name}_crop.jpg" }) return {}
def channel_addowner(token, channel_id, u_id): """Make user with user id u_id an owner of this channel""" # Convert channel_id and u_id to integer channel_id = int(channel_id) u_id = int(u_id) # Validate token, channel and user if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) if not validator.is_valid_channel(channel_id): raise ValueError(INVALID_CHANNEL) if not validator.is_valid_user(u_id): raise ValueError(INVALID_USER) # Locate channel and user in database channel = database.get_channel_by_id(channel_id) auth_user_id = jwt_handler.decode_token(token) auth_user = database.get_user_by_id(auth_user_id) # Check auth_user permissions if auth_user["permission"] not in [OWNER, ADMIN] or\ auth_user_id not in channel["owner_ids"]: raise AccessError(CHANNEL_ADD_OWNER_NO_AUTH) # Add user to auth_ids auth_list = channel["auth_ids"] if u_id not in auth_list: auth_list.append(u_id) database.update_channel_by_id(channel_id, { "auth_ids": auth_list }) # Add user to owner_ids owner_list = channel["owner_ids"] if u_id in owner_list: raise ValueError(CHANNEL_ALREADY_OWNER) owner_list.append(u_id) database.update_channel_by_id(channel_id, { "owner_ids": owner_list }) return {}
def standup_send(token, channel_id, message): """Adds message to standup buffer if standup is currently active""" # Check valid token if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) # Check channel existence channel = database.get_channel_by_id(channel_id) if channel is None: raise ValueError(INVALID_CHANNEL) # Check user is member of channel u_id = jwt_handler.decode_token(token) if u_id not in channel["auth_ids"]: raise AccessError(CHANNEL_CANT_VIEW_DETAIL) # Check the startup is not currently active in this channel old_time_end = database.get_standup_finish_time(channel_id) if old_time_end is None or\ json_time_translator.json_to_datetime(old_time_end) < datetime.utcnow(): raise ValueError(STANDUP_NOT_RUNNING) # Check valid message if not validator.is_valid_message(message): raise ValueError(INVALID_MESSAGE) # Save message database.add_standup_message( channel_id, { "u_id": u_id, "message": message, "time_created": json_time_translator.datetime_to_json(datetime.utcnow()), }) return {}
def auth_login(email, password): """Given a registered users' email and password and generates a valid token for the user to remain authenticated""" # Validate data if not validator.is_valid_email(email): raise ValueError(INVALID_EMAIL) # Loop searches within the user database users = database.get_all_users() for user in users: # Checks if email matches an email if user["email"] == email: # Checks if password matches the email's password if user["password"] != password: raise ValueError(WRONG_PASS) # Creates a new token for the user token = jwt_handler.encode_u_id(user["u_id"]) token_list = user["tokens"] token_list.append(token) # Updates the json file database.update_user_by_id(user["u_id"], {"tokens": token_list}) return {"u_id": user["u_id"], "token": token} raise ValueError(EMAIL_NOT_FOUND)
def user_profile_sethandle(token, handle_str): """Update the authorised user's handle (i.e. display name)""" # Check valid token if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) u_id = jwt_handler.decode_token(token) # Check valid handle if not validator.is_valid_handle(handle_str): raise ValueError(INVALID_HANDLE) # Check if handle is already in use if not validator.is_unique_handle(handle_str): raise ValueError(NOT_UNIQUE_HANDLE) # Update the database with new changes database.update_user_by_id(u_id, { "handle": handle_str }) return {}
def user_profile_setemail(token, email): """Update the authorised user's email address""" # Check valid token if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) u_id = jwt_handler.decode_token(token) # Check valid email if not validator.is_valid_email(email): raise ValueError(INVALID_EMAIL) # Check that email is not already in use if not validator.is_unique_email(email): raise ValueError(NOT_UNIQUE_EMAIL) # Update the database with new changes database.update_user_by_id(u_id, { "email": email }) return {}
def auth_passwordreset_reset(reset_code, new_password): """Given a reset code for a user, set that user's new password to the password provided""" # Validate data if not validator.is_valid_password(new_password): raise ValueError(INVALID_PASS) # Ignore reset_code if reset_code == "": raise ValueError(EMPTY_RESET_CODE) users = database.get_all_users() reset_code_found = False for user in users: if user["pw_reset_code"] == reset_code: reset_code_found = True database.update_user_by_id(user["u_id"], { "password": new_password, "pw_reset_code": "" }) code_generator.delete_reset_code(reset_code) if not reset_code_found: raise ValueError(INVALID_RESET_CODE) return {}
def channel_details(token, channel_id): """Given a Channel with ID channel_id that the authorised user is part of, provide basic details about the channel""" # Validate token and channel if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) if not validator.is_valid_channel(channel_id): raise ValueError(INVALID_CHANNEL) # Find user in database u_id = jwt_handler.decode_token(token) # Locate in database channel = database.get_channel_by_id(channel_id) user = database.get_user_by_id(u_id) # Check user is authorised if u_id not in channel["auth_ids"] and user["permission"] == MEMBER: raise AccessError(CHANNEL_CANT_VIEW_DETAIL) # Compile channel details owner_list = channel["owner_ids"] auth_list = channel["auth_ids"] owner_list_with_details = [] auth_list_with_details = [] for owner_id in owner_list: owner = database.get_user_by_id(owner_id) owner_list_with_details.append({ "u_id": owner_id, "name_first": owner["name_first"], "name_last": owner["name_last"], "profile_img_url": owner["profile_img_url"]}) for auth_id in auth_list: auth = database.get_user_by_id(auth_id) auth_list_with_details.append({ "u_id": auth_id, "name_first": auth["name_first"], "name_last": auth["name_last"], "profile_img_url": auth["profile_img_url"]}) return { "name": channel["name"], "owner_members": owner_list_with_details, "all_members": auth_list_with_details }
def user_profile_setname(token, name_first, name_last): """Update the authorised user's first and last name""" # Check valid token if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) u_id = jwt_handler.decode_token(token) # Check Valid input Name if not validator.is_valid_name(name_first) or not validator.is_valid_name(name_last): raise ValueError(INVALID_NAME) # Update the database with new changes database.update_user_by_id(u_id, { "name_first": name_first, "name_last": name_last }) return {}
def standup_active(token, channel_id): """Adds message to standup buffer if standup is currently active""" # Check valid token if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) # Check channel existence channel = database.get_channel_by_id(channel_id) if channel is None: raise ValueError(INVALID_CHANNEL) is_active = is_standup_running(channel_id) time_finish = None if is_active: time_finish = int( json_time_translator.json_to_timestamp( database.get_standup_finish_time(channel_id))) return {"is_active": is_active, "time_finish": time_finish}
def user_profile(token, u_id): """For a valid user, returns information about their email, first name, last name, and handle""" # Check valid token if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) # Check u_id is valid if not validator.is_valid_user(u_id): raise ValueError(INVALID_USER) # Return user profile user = database.get_user_by_id(u_id) return { "email": user["email"], "name_first": user["name_first"], "name_last": user["name_last"], "handle_str": user["handle"], "profile_img_url": user["profile_img_url"] }
def channels_create(token, name, is_public): """Creates a new channel with that name that is either a public or private channel""" # Convert is_public to boolean is_public = is_public.lower() in ("true", "yes", "t", "1") # Validate token & data if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) if not validator.is_valid_channel_name(name): raise ValueError(CHANNEL_LONG_NAME) # Convert token to u_id u_id = jwt_handler.decode_token(token) # Create channel and get ID channel_id = database.add_channel({ "name": name, "messages": [], "is_public": is_public, "owner_ids": [u_id], "auth_ids": [u_id] }) return {"channel_id": channel_id}
def channel_messages(token, channel_id, start): """Given a Channel with ID channel_id that the authorised user is 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.""" # Convert 'start' to an integer start = int(start) # Validate token and channel ID if not validator.is_valid_token(token): raise AccessError(INVALID_TOKEN) if not validator.is_valid_channel(channel_id): raise ValueError(INVALID_CHANNEL) # Locate channel channel = database.get_channel_by_id(channel_id) # Validate that token user is in channel u_id = jwt_handler.decode_token(token) if u_id not in channel["auth_ids"]: raise AccessError(CHANNEL_CANT_VIEW_MSG) # Validate messages exist total_messages = len(channel['messages']) if total_messages <= 0: return { "messages": [], "start": start, "end": -1 } # Validate start point if start > (total_messages - 1) or start < 0: raise ValueError(CHANNEL_NO_MORE_MSG) # Find index for the most recent message (reference list backwards) start_index = len(channel['messages']) - 1 - start # Get all recent messages up to 50 messages = [] end = start + 49 for msg_num in range(50): index = start_index - msg_num # If there are less than 50 msgs if index < 0: end = -1 break # Get message object message_id = channel['messages'][index] message = database.get_message_by_id(message_id) # If message is sent later or not there if message is None or\ json_time_translator.json_to_datetime(message["time_created"]) >= datetime.utcnow(): continue # Create output-able list of reacts react_list = [] reacted_ids = [] all_reacts = database.get_all_reacts(message_id) react_id = 1 for react in all_reacts: is_this_user_reacted = False if react["react_id"] == react_id: reacted_ids.extend(react["u_id"]) if u_id in react["u_id"]: is_this_user_reacted = True # Only add the reaction if it has at least one count of a user react_list.append({ "react_id": react_id, "u_ids": reacted_ids, "is_this_user_reacted": is_this_user_reacted }) # print(message["time_created"]) # print(json_time_translator.json_to_datetime(message["time_created"])) # print(json_time_translator.json_to_timestamp(message["time_created"])) # Append to file messages.append({ "message_id": message_id, "u_id": message["u_id"], "message": message["message"], "time_created": json_time_translator.json_to_timestamp(message["time_created"]), "reacts": react_list, "is_pinned": message["is_pinned"] }) return { "messages": messages, "start": start, "end": end }
def auth_register(email, password, name_first, name_last): """Given a user's first and last name, email address, and password, create a new account for them and return a new token for authentication in their session. A handle is generated that is the concatentation of a lowercase-only first name and last name. If the concatenation is longer than 20 characters, it is cutoff at 20 characters. If the handle is already taken, you may modify the handle in any way you see fit to make it unique.""" # Validate data if not validator.is_valid_name(name_first): raise ValueError(INVALID_NAME_FIRST) if not validator.is_valid_name(name_last): raise ValueError(INVALID_NAME_LAST) if not validator.is_valid_email(email): raise ValueError(INVALID_EMAIL) if not validator.is_unique_email(email): raise ValueError(NOT_UNIQUE_EMAIL) if not validator.is_valid_password(password): raise ValueError(INVALID_PASS) # Set permission to MEMBER perm = constants.MEMBER # If no members, permission is OWNER if len(database.get_all_users()) == 0: perm = constants.OWNER # user["handle"] handling if len(name_first + name_last) > 20: handle = [] temp = (name_first + name_last).lower() for x in range(0, 20): handle.append(temp[x]) handle_str = "".join(handle) else: handle_str = (name_first + name_last).lower() users = database.get_all_users() index = 0 for user in users: if user["handle"][0:len(handle_str)] == handle_str: index += 1 if index > 0: handle_str = handle_str + str(index) u_id = database.add_user({ "tokens": [], "name_first": name_first, "name_last": name_last, "handle": handle_str, "email": email, "password": password, "permission": perm, "pw_reset_code": "", "profile_img_url": "http://127.0.0.1:5001/static/default.jpg" }) token = jwt_handler.encode_u_id(u_id) user = database.get_user_by_id(u_id) token_list = user["tokens"] token_list.append(token) database.update_user_by_id(u_id, {"tokens": token_list}) return {"token": token}