예제 #1
0
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))
예제 #2
0
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))
예제 #3
0
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")
예제 #4
0
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
예제 #5
0
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")
예제 #6
0
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)
예제 #7
0
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("")
예제 #8
0
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))
예제 #9
0
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")
예제 #10
0
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")
예제 #11
0
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")
예제 #12
0
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
예제 #13
0
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)
예제 #14
0
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("")
예제 #15
0
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("")