def search_select_posts(): """Allows user to search for posts and select one of the results Returns: (post_row, bool): The first value in the tuple is the row entry of the selected post, or None if user exits. The second value in the tuple is True if a user wants to logout and False otherwise """ # Search posts while (True): print("Enter keywords separated by a comma:") keywords = request_input() if keywords[0] == "/back": return None, False elif keywords[0] == "/logout": return None, True results = db.search_posts(keywords) if len(results) > 0: break print("No results found for keywords:", str(keywords), "\n") continue # List results print("Showing results for keywords", str(keywords)) print("Enter the index of the post to excute an action on that post:") min_i, max_i = get_indices_range(results=results) print("") print_search_results(results, min_i, max_i) # Select posts while (True): action = request_input()[0] if action == "more": if len(results) <= max_i: print("No more results are available") continue # Increment the min and max min_i, max_i = get_indices_range(results=results, old_min=min_i, old_max=max_i) print_search_results(results, min_i, max_i) elif action == "/back": return None, False elif action == "/logout": return None, True elif is_index(action, results): # Note: User input index starts at 1 return results[int(action) - 1], False else: print_invalid_option(max_option=len(results))
def search_select_questions(): """Allows user to search for questions and select one of the results Returns: post_row: Row entry of the selected post, or None if user exits. """ while (True): print("Enter keywords separated by a comma:") keywords = request_input() if keywords[0] == "/back": return None results = db.search_questions(keywords) if len(results) > 0: break print("No results found for keywords:", str(keywords), "\n") continue # List results print("Showing " + str(len(results)) + " results for keywords", str(keywords)) print("Enter the index of the post to excute an action on that post:") min_i, max_i = get_indices_range(results=results) print("") print_search_results(results, min_i, max_i) # Select posts while (True): action = request_input()[0] if action == "more": if len(results) <= max_i: print("No more results are available") continue # Increment the min and max min_i, max_i = get_indices_range( results=results, old_min=min_i, old_max=max_i ) print_search_results(results, min_i, max_i) elif action == "/back": return None elif is_index(action, results): # Note: User input index starts at 1 return results[int(action) - 1] else: print_invalid_option(max_option=len(results))
def signup(): """Allows user to sign up for a new account Returns: (str): The uid of the signed-up user, None if signup failed """ print("Sign-up") print("To return to the main screen, type `/back`") while (True): print("Enter: ID, Name, City") sign_up_values = request_input(expected_len=3, logout_allowed=False) if not sign_up_values: continue if sign_up_values[0] == "/back": return None if len(sign_up_values[0]) > 4: print("ID must be less than 5 characters") continue while (True): password = get_password() if password == "": print("Password cannot be empty. Please try again.") else: break # Attempt to sign up sign_up_success = db.sign_up(*sign_up_values, password) if sign_up_success: return sign_up_values[0] else: print("Sign up failed, please try again")
def login(): """Allows user to login into an existing account Returns: (str): The uid of the logged in user, None if login failed (bool): True if user is priviledged, False if user is not priviledged, None if login failed """ print("To return to the main screen, type `/back`") while (True): print("Enter: ID") login_values = request_input(expected_len=1, logout_allowed=False) if not login_values: continue if login_values[0] == "/back": return None, None # Attempt to login login_success = db.login(*login_values, get_password()) if login_success: # Check if user is privileged is_privileged = db.check_privilege(login_values[0]) return login_values[0], is_privileged else: print( "Please try again\n") # db.login handles some messaging before
def post_question(): """Allows user to post a question by inputting the required fields Returns: """ print("Post Question") while (True): title_text = input("Enter title: ") to_return = keyword_input_validate(title_text) if to_return: return if title_text.strip() == "": print("\nTitle cannot be empty, please try again.") continue break body_text = input("Enter body: ") to_return = keyword_input_validate(body_text) if to_return: return print("Enter tags seperated by comma: ") tags_text = request_input() if tags_text[0] == "/back": return post_success = db.post_question(title_text, body_text, uid, tags_text) if post_success: print("Question successfully posted") else: print("Question failed to post")
def logged_in(uid_param): """The execution loop for a user Args: uid_param (str): The uid of the user """ global uid uid = uid_param print("To exit program type `/exit` at any point") print("In any submenu or input, type `/back` to return up a level.") while (True): print_options(["Post a question", "Search for questions"]) action = request_input()[0] if action == "/back": print("Already at the top-level menu.") # Post a Question elif (action == "1"): post_question() print("") # Search for posts elif (action == "2"): post = search_select_questions() if post is not None: question_action(post) # Invalid selection else: print_invalid_option(max_option=2)
def question_action(post): """The execution loop of a user to take post actions on selected question Args: post (post_row): The post on which post_actions are being executed """ db.increment_question_view_count(post) print_all_post_details(post) # Setup post action options pa_actions = ["Answer question", "See answers", "Vote"] while(True): print_options(pa_actions) action = request_input()[0] if action == "/back": return # Post action-answer elif (action == "1"): post_answer(post) # Post action-see answers elif (action == "2"): answer = see_question_answers(post) if answer is not None: answer_action(answer) # Post action-vote elif (action == "3"): post_vote(post) # Invalid selection else: print_invalid_option() print("")
def see_question_answers(post): """Get and view answers to given question Args: post (dict): Post to view answers on """ results = db.get_answers_to_question(post) print("Showing " + str(len(results)) + " answers to post",) print("Enter the index of the post to excute an action on that post:") min_i, max_i = get_indices_range(results=results) print("") accepted_answer_id = post.get("AcceptedAnswerId") if accepted_answer_id: # Move accepted answer to first position for i in range(len(results)): if results[i]["Id"] == accepted_answer_id: accepted_answer_idx = i break accepted_answer = results.pop(i) results.insert(0, accepted_answer) # Only need to print on the first display of results print_search_results(results, min_i, max_i, answer=True, accepted_id=accepted_answer_id) # Select posts while (True): action = request_input()[0] if action == "more": if len(results) <= max_i: print("No more results are available") continue # Increment the min and max min_i, max_i = get_indices_range( results=results, old_min=min_i, old_max=max_i ) print_search_results(results, min_i, max_i, answer=True) elif action == "/back": return None elif is_index(action, results): # Note: User input index starts at 1 return results[int(action) - 1] else: print_invalid_option(max_option=len(results))
def post_answer(post): """ Post an answer to a question Args: post (dict): Question to post an answer to """ print("Enter the body of the answer:") body = request_input()[0] post_success = db.post_answer(post["Id"], body, uid) if post_success: print("Answer successfully posted") else: print("Answer failed to post")
def give_badge(poster_uid): """Allows user to select and give a badge to the poster Args: poster_uid (str): The uid of the poster who is being given a badge Returns: (bool): True if the user chooses to logout, None otherwise """ results = db.get_badges() if results is None: print("Failed to retrieve list of badges") return print("Give poster a badge") print("Choose a badge to give to the user:"******"") print_badges(results, min_i, max_i) # Select badge while (True): action = request_input()[0] if action == "more": if len(results) <= max_i: print("No more results are available") continue # Increment the min and max min_i, max_i = get_indices_range(results=results, old_min=min_i, old_max=max_i) print_badges(results, min_i, max_i) elif action == "/back": return elif action == "/logout": return True elif is_index(action, results): break else: print_invalid_option(max_option=len(results)) # Note: User input index starts at 1 give_badge_success = db.give_badge(poster_uid, results[int(action) - 1][0]) if give_badge_success: print("The badge was successfully given to the poster") else: print("Failed to give the badge to the poster")
def mark_as_accepted(pid): """Allows user to mark a selected answer as accepted Args: pid (str): The pid of the answer which is being accepted Returns: (bool): True if the user chooses to logout, None otherwise """ question = db.get_question_of_answer(pid) if question is None: print("Failed to find the question of this answer") return if question[1] is not None: if question[1] == pid: print("This answer is already marked as accepted") return print("Mark answer as accepted") print("The answer's question already has an accepted answer.") print_options( ["Cancel and go back", "Replace current accepted answer"]) while True: action = request_input()[0] if action == "/logout": return True if action == "1" or action == "/back": print("The operation was cancelled") return elif action == "2": break else: print_invalid_option(2) mark_accepted_success = db.mark_accepted(pid, question[0]) if mark_accepted_success: print("The answer was successfully marked as accepted") else: print("Failed to mark the answer as accepted")
def logged_in(uid_param, is_privileged_param): """The execution loop for a user once logged in Args: uid_param (str): The uid of the logged in user is_privileged_param (bool): True if privileged user, False otherwise """ global uid uid = uid_param global is_privileged is_privileged = is_privileged_param print("Now logged in. To log out, type `/logout` at anytime.") print("In any submenu or input, type `/back` to return up a level.") while (True): print_options(["Post a question", "Search posts"]) action = request_input()[0] logout = None if action == "/back": print("Already at the top-level menu. To logout, type `/logout`.") elif (action == "/logout"): logout = True # Post a Question elif (action == "1"): logout = post_question() print("") # Search for posts elif (action == "2"): post, logout = search_select_posts() if not logout and post is not None: logout = post_action(post) # Invalid selection else: print_invalid_option(max_option=2) if logout: return
def login_or_signup(): """The execution loop for a user to login or signup Returns: (str): The uid of the logged in user, None if login/signup failed (bool): True if user is priviledged, False if user is not priviledged, None if login/signup failed """ print("To exit program type `/exit` at any point") print_options(["Login", "Sign-up"]) while (True): action = request_input()[0] # Login if action == '1': return login() # Sign up elif action == '2': return signup(), False # Invalid selection else: print_invalid_option(max_option=2)
def answer_action(post): """The execution loop of a user to take answer actions on selected post Args: post (post_row): The post on which post_actions are being executed """ # Setup post action options pa_actions = ["Vote"] while(True): print_options(pa_actions) action = request_input()[0] if action == "/back": return # Post action-vote elif (action == "1"): post_vote(post) return # Invalid selection else: print_invalid_option() print("")
def post_action(post): """The execution loop of a user to take post actions on selected post Args: post (post_row): The post on which post_actions are being executed Returns: (bool): True if the user chooses to logout, None otherwise """ # Get post info pid = post[0] # Checking answer count to determine post type is_question = True if post[7] is not None else False # Setup post action options pa_actions = [ "Answer question", "Vote on post", "Mark answer as accepted", "Give poster a badge", "Add tag to post", "Edit post" ] skip_actions = pa_actions[2:] if not is_privileged else [] if is_question: skip_actions.append(pa_actions[2]) else: skip_actions.append(pa_actions[0]) while (True): print("Selected post pid is:", pid) print_options(pa_actions, skip_actions) action = request_input()[0] logout = None if action == "/back": return elif action == "/logout": logout = True # Post action-answer elif (action == "1") and is_question: logout = post_answer(pid) # Post action-vote elif (action == "2"): post_vote(pid) # Post action-mark as accepted elif (action == "3") and is_privileged and not is_question: logout = mark_as_accepted(pid) # Post action-give a badge elif (action == "4") and is_privileged: logout = give_badge(post[4]) if logout: return True # Post post action-add a tag elif (action == "5") and is_privileged: logout = add_tag(pid) # Post action-edit: elif (action == "6") and is_privileged: logout = edit_post(pid) # Invalid selection else: print_invalid_option() if logout: # Either True, False or None return True print("")