|
2 | 2 | import requests |
3 | 3 | from rich.console import Console |
4 | 4 | import sys as sys |
| 5 | +import os |
| 6 | +import time |
| 7 | +from collections import defaultdict |
5 | 8 |
|
6 | 9 | from .error import SearchError |
7 | 10 | from .save import SaveSearchResults |
@@ -42,7 +45,6 @@ def __get_search_url(self, question, tags): |
42 | 45 | def make_request(self, que, tag: str): |
43 | 46 | """ |
44 | 47 | This function uses the requests library to make the rest api call to the stackexchange server. |
45 | | -
|
46 | 48 | :param que: The user questions that servers as a question in the api. |
47 | 49 | :type que: String |
48 | 50 | :param tag: The tags that user wants for searching the relevant answers. For e.g. TypeError might be for multiple languages so is tag is used as "Python" then the api will return answers based on the tags and question. |
@@ -75,57 +77,97 @@ def get_ans(self, questions_list): |
75 | 77 | This function prints the answer to the queries |
76 | 78 | (question and tags) provided by the user. It does so |
77 | 79 | in the following manner : |
| 80 | + 1) Gets the details of all the relavant question and stores their title, link and id in "question_data" list. [See line 104] |
| 81 | + 2) I have introduced the concept of active question, i.e. , the question whose answer is currently being displayed. |
| 82 | + 3) The index of the active question in "question_data" array is stored in "question_posx" |
| 83 | + 2) By Default, shows the answer to the first question. Creates an breakable infinite loop asking the user asnwer to which question he wants to see. |
| 84 | + 4) The value of "question_posx" changes according to user input, displaying answer to different questions in "questions_data" list. |
| 85 | + 3) The answers to the questions requested by the user are stored in cache for faster access time during subsequent calls. |
| 86 | + """ |
| 87 | + |
| 88 | + """ Create batch request to get details of all the questions """ |
| 89 | + batch_ques_id = "" |
| 90 | + for question_id in questions_list: |
| 91 | + batch_ques_id += str(question_id) + ";" |
| 92 | + print(batch_ques_id) |
78 | 93 |
|
79 | | - 1) Takes in account only th first question id from the |
80 | | - list of question ids |
81 | | -
|
82 | | - 2) Tries to get a response from the url obtained by appending |
83 | | - question id to the search_content_url variable |
| 94 | + try: |
| 95 | + resp = requests.get( |
| 96 | + f"{self.search_content_url}/2.2/questions/{batch_ques_id[:-1]}?order=desc&sort=votes&site=stackoverflow&filter=!--1nZwsgqvRX" |
| 97 | + ) |
| 98 | + except: |
| 99 | + SearchError("Search Failed", "Try connecting to the internet") |
| 100 | + sys.exit() |
| 101 | + json_ques_data = resp.json() |
84 | 102 |
|
85 | | - 3) Use the data received from the above request and loop |
86 | | - through it to print the answer |
| 103 | + """ Store the received questions data into the following data format |
| 104 | + list( list( question_title, question_link, question_id ) ) |
87 | 105 | """ |
88 | | - ans = [] |
89 | | - for questions in range(1): |
90 | | - try: |
91 | | - resp = requests.get( |
92 | | - f"{self.search_content_url}/2.2/questions/{questions_list[questions]}/answers?order=desc&sort=votes&site=stackoverflow&filter=!--1nZwsgqvRX" |
93 | | - ) |
94 | | - except: |
95 | | - SearchError("\U0001F613 Search Failed", "\U0001F4BB Try connecting to the internet") |
96 | | - sys.exit() |
97 | | - json_ans_data = resp.json() |
98 | | - |
99 | | - for data in json_ans_data["items"]: |
100 | | - output_content = [ |
101 | | - colored( |
102 | | - "--------------------------------------------------------", |
103 | | - 'red'), data["body_markdown"], |
104 | | - f"\U0001F517 Link to the answer:{data['link']}" |
105 | | - ] |
106 | | - |
| 106 | + questions_data = [[item['title'], item['link'], item['question_id']] for item in json_ques_data["items"] ] |
| 107 | + |
| 108 | + os.system('cls' if os.name == 'nt' else 'clear') # Clear terminal |
| 109 | + |
| 110 | + downloaded_questions_cache = defaultdict(lambda: False) # cache array to store the requested answers. Format of storage { question_id:[answer_body, answer_link] } |
| 111 | + |
| 112 | + question_posx = 0 # Stores the currently showing question index in questions_data |
| 113 | + while True: |
| 114 | + os.system('cls' if os.name == 'nt' else 'clear') |
| 115 | + |
| 116 | + console.rule('[bold blue] Relevant Questions', style="bold red") |
| 117 | + for idx, question_data in enumerate(questions_data): # Printing all the questions. The active question is printed GREEN. |
| 118 | + if question_posx == idx: |
| 119 | + console.print("[green]{}. {} | {}".format(idx+1, question_data[0], question_data[1])) |
| 120 | + else: |
| 121 | + console.print("{}. {} | {}".format(idx+1, question_data[0], question_data[1])) |
| 122 | + |
| 123 | + console.rule("[bold blue] Answer of question {}".format(question_posx+1), style="bold red") |
| 124 | + current_question_id = questions_data[question_posx][2] # Gets the question_id of active question |
| 125 | + if(downloaded_questions_cache[current_question_id]): # Searches for the id in cache. If present then prints it |
| 126 | + output_content = downloaded_questions_cache[current_question_id] |
107 | 127 | for output_index, output_text in enumerate(output_content): |
108 | 128 | """ |
109 | 129 | Loop through the output_text and print the element |
110 | | - if it is the last one, the text[0] is printed |
| 130 | + if it the last one, the text[0] is printed |
111 | 131 | along with text[-1] |
112 | 132 |
|
113 | 133 | if text is markdown , render the markdown |
114 | 134 | """ |
115 | 135 | if output_index == len(output_content) - 1: |
116 | | - console.print(output_text) |
117 | | - |
118 | | - console.print(output_content[0]) |
| 136 | + console.print("Link to the answer: " + output_text) |
119 | 137 | break |
120 | 138 |
|
121 | 139 | if output_index == len(output_content) - 2: |
122 | | - renderer = MarkdownRenderer(output_text) |
123 | | - |
| 140 | + MarkdownRenderer(output_text) |
124 | 141 | continue |
125 | 142 |
|
126 | 143 | console.print(output_text) |
127 | | - ans.append(json_ans_data["items"]) |
128 | | - return ans |
| 144 | + |
| 145 | + else: # If the cache has no entry for the said question id, the downloads the answer |
| 146 | + try: # and makes an entry for it in the said format [Line 110] and restarts the loop. |
| 147 | + resp = requests.get( |
| 148 | + f"{self.search_content_url}/2.2/questions/{current_question_id}/answers?order=desc&sort=votes&site=stackoverflow&filter=!--1nZwsgqvRX" |
| 149 | + ) |
| 150 | + except: |
| 151 | + SearchError("Search Failed", "Try connecting to the internet") |
| 152 | + sys.exit() |
| 153 | + json_ans_data = resp.json() |
| 154 | + print(json_ans_data["items"]) |
| 155 | + most_upvoted = json_ans_data["items"][0] |
| 156 | + downloaded_questions_cache[current_question_id] = [most_upvoted["body_markdown"], most_upvoted['link']] |
| 157 | + del most_upvoted |
| 158 | + continue |
| 159 | + |
| 160 | + console.rule("[bold blue]", style="bold red", align="right") |
| 161 | + while True: |
| 162 | + posx = int(input("Enter the question number you want to view (Press 0 to quit): ")) - 1 # Asks the user for next question number. Makes it the active question and loop restarts |
| 163 | + if (posx == -1): # Press 0 to exit |
| 164 | + return |
| 165 | + elif (0<=posx<len(questions_data)): |
| 166 | + question_posx = posx |
| 167 | + break |
| 168 | + else: |
| 169 | + console.print("Please enter a valid question number") |
| 170 | + continue |
129 | 171 |
|
130 | 172 | # Get an access token and extract to a JSON file "access_token.json" |
131 | 173 | @classmethod |
|
0 commit comments