Skip to content

Commit 1ac4ae1

Browse files
committed
- Fix missing answer bug in question panel
- Format code - Add question search URL in Utility class - Add answer search URL in Utility class - Insert dynamic emojis which searching
1 parent 9d97db3 commit 1ac4ae1

File tree

1 file changed

+78
-50
lines changed

1 file changed

+78
-50
lines changed

src/arguments/utility.py

Lines changed: 78 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
import webbrowser
1212
from pygments import highlight
1313
from pygments.lexers.markup import MarkdownLexer
14-
from pygments.formatters import Terminal256Formatter
14+
from pygments.lexers.html import HtmlLexer
15+
from pygments.formatters import TerminalFormatter
1516

1617
from .error import SearchError
1718
from .save import SaveSearchResults
@@ -35,63 +36,67 @@
3536

3637
console = Console()
3738

38-
class Questions_Panel_stackoverflow():
39+
class QuestionsPanel_stackoverflow():
3940
def __init__(self):
40-
self.questions_data = [] # list( list( question_title, question_link, question_id )... )
41+
self.questions_data = [] # list( list( question_title, question_id, question_link )... )
4142
self.answer_data = defaultdict(lambda: False) # dict( question_id:list( body, link )) corresponding to self.questions_data
42-
self.batch_ques_id = ""
4343
self.line_color = "bold red"
4444
self.heading_color = "bold blue"
45-
self.search_content_url = "https://api.stackexchange.com/"
45+
self.utility = Utility()
4646

4747
def populate_question_data(self, questions_list):
48-
""" Function to populate question data property
49-
Creates batch_id request to stackexchange API and
50-
Stores the returned data data in the following format:
51-
list( list( question_title, question_link, question_id ) )
5248
"""
53-
for question_id in questions_list:
54-
self.batch_ques_id += str(question_id) + ";"
55-
try:
56-
resp = requests.get(
57-
f"{self.search_content_url}/2.2/questions/{self.batch_ques_id[:-1]}?order=desc&sort=votes&site=stackoverflow&filter=!--1nZwsgqvRX"
58-
)
59-
except:
60-
SearchError("Search Failed", "Try connecting to the internet")
61-
sys.exit()
49+
Function to populate question data property
50+
Creates batch request to stackexchange API and to get question details of
51+
questions with id in the list. Stores the returned data data in the following format:
52+
list( list( question_title, question_link, question_id ) )
53+
"""
54+
with console.status("Getting the questions..."):
55+
try:
56+
resp = requests.get(
57+
self.utility.get_batch_ques_url(questions_list)
58+
)
59+
except:
60+
SearchError("Search Failed", "Try connecting to the internet")
61+
sys.exit()
6262
json_ques_data = resp.json()
6363
self.questions_data = [[item['title'], item['question_id'], item['link']] for item in json_ques_data["items"]]
6464

65-
def populate_answer_data(self):
66-
""" Function to populate answer data property
67-
Creates batch_id request to stackexchange API and
68-
Stores the returned data data in the following format:
69-
list( list( question_title, question_link, question_id ) )
65+
def populate_answer_data(self, questions_list):
7066
"""
71-
try:
72-
resp = requests.get(
73-
f"{self.search_content_url}/2.2/questions/{self.batch_ques_id[:-1]}/answers?order=desc&sort=votes&site=stackoverflow&filter=!--1nZwsgqvRX"
74-
)
75-
except:
76-
SearchError("Search Failed", "Try connecting to the internet")
77-
sys.exit()
78-
json_ans_data = resp.json()
79-
for item in json_ans_data["items"]:
80-
self.answer_data[item['question_id']] = item['body_markdown']
81-
82-
def return_formatted_ans(self, id):
67+
Function to populate answer data property
68+
Creates batch request to stackexchange API to get ans of questions with
69+
question id in the list. Stores the returned data data in the following format:
70+
dict( question_id:list( body, link ) )
71+
"""
72+
with console.status("Searching answers..."):
73+
try:
74+
resp = requests.get(
75+
self.utility.get_batch_ans_url(questions_list)
76+
)
77+
except:
78+
SearchError("Search Failed", "Try connecting to the internet")
79+
sys.exit()
80+
json_ans_data = resp.json()
81+
for item in json_ans_data["items"]:
82+
if not(self.answer_data[item['question_id']]):
83+
self.answer_data[item['question_id']] = item['body_markdown']
84+
85+
# Sometimes the StackExchange API fails to deliver some answers. The below code is to fetch them
86+
failed_ques_id = [question[1] for question in self.questions_data if not(self.answer_data[question[1]])]
87+
if not(len(failed_ques_id) == 0):
88+
self.populate_answer_data(failed_ques_id)
89+
90+
def return_formatted_ans(self, ques_id):
8391
# This function uses pygments lexers ad formatters to format the content in the preview screen
84-
body_markdown = self.answer_data[int(id)]
92+
body_markdown = self.answer_data[int(ques_id)]
8593
if(body_markdown):
8694
body_markdown = str(body_markdown)
87-
body_markdown = body_markdown.replace("&", "&")
88-
body_markdown = body_markdown.replace("&lt;", "<")
89-
body_markdown = body_markdown.replace("&gt;", ">")
90-
body_markdown = body_markdown.replace("&quot;", "\"")
91-
body_markdown = body_markdown.replace("&apos;", "\'")
92-
body_markdown = body_markdown.replace("&#39;", "\'")
95+
xml_markup_replacement = [("&amp;", "&"), ("&lt;", "<"), ("&gt;", ">"), ("&quot;", "\""), ("&apos;", "\'"), ("&#39;", "\'")]
96+
for convert_from, convert_to in xml_markup_replacement:
97+
body_markdown = body_markdown.replace(convert_from, convert_to)
9398
lexer = MarkdownLexer()
94-
formatter = Terminal256Formatter(bg="light")
99+
formatter = TerminalFormatter()
95100
highlighted = highlight(body_markdown, lexer, formatter)
96101
else:
97102
highlighted = "Answer not viewable. Press enter to open in a browser"
@@ -103,18 +108,22 @@ def navigate_questions_panel(self):
103108
console.print("[yellow] Use arrow keys to navigate. 'q' or 'Esc' to quit. 'Enter' to open in a browser")
104109
console.print()
105110
options = ["|".join(map(str, question)) for question in self.questions_data]
106-
question_menu = TerminalMenu(options, preview_command=self.return_formatted_ans)
111+
question_menu = TerminalMenu(options, preview_command=self.return_formatted_ans, preview_size=0.75, )
107112
quitting = False
108113
while not(quitting):
109114
options_index = question_menu.show()
110115
try:
111-
options_choice = options[options_index]
116+
question_link = self.questions_data[options_index][2]
112117
except Exception:
113118
return
114119
else:
115-
question_link = self.questions_data[options_index][2]
116120
webbrowser.open(question_link)
117121

122+
def display_panel(self, questions_list):
123+
self.populate_question_data(questions_list)
124+
self.populate_answer_data(questions_list)
125+
self.navigate_questions_panel()
126+
118127
class Utility():
119128
def __init__(self):
120129
# the parent url
@@ -128,6 +137,22 @@ def __get_search_url(self, question, tags):
128137
"""
129138
return f"{self.search_content_url}/2.2/search/advanced?order=desc&sort=relevance&tagged={tags}&title={question}&site=stackoverflow"
130139

140+
def get_batch_ques_url(self, ques_id_list):
141+
"""
142+
Returns URL which contains ques_ids which can be use to get
143+
get the details of all the corresponding questions
144+
"""
145+
batch_ques_id = ""
146+
for question_id in ques_id_list:
147+
batch_ques_id += str(question_id) + ";"
148+
return f"{self.search_content_url}/2.2/questions/{batch_ques_id[:-1]}?order=desc&sort=votes&site=stackoverflow&filter=!--1nZwsgqvRX"
149+
150+
def get_batch_ans_url(self, ques_id_list):
151+
batch_ques_id = ""
152+
for question_id in ques_id_list:
153+
batch_ques_id += str(question_id) + ";"
154+
return f"{self.search_content_url}/2.2/questions/{batch_ques_id[:-1]}/answers?order=desc&sort=votes&site=stackoverflow&filter=!--1nZwsgqvRX"
155+
131156
def make_request(self, que, tag: str):
132157
"""
133158
This function uses the requests library to make the rest api call to the stackexchange server.
@@ -159,10 +184,13 @@ def get_que(self, json_data):
159184
return que_id
160185

161186
def get_ans(self, questions_list):
162-
stackoverflow_panel = Questions_Panel_stackoverflow()
163-
stackoverflow_panel.populate_question_data(questions_list)
164-
stackoverflow_panel.populate_answer_data()
165-
stackoverflow_panel.navigate_questions_panel()
187+
"""
188+
This Function creates QuestionsPanel_stackoverflow class which supports
189+
Rendering, navigation, searching and redirecting capabilities
190+
"""
191+
stackoverflow_panel = QuestionsPanel_stackoverflow()
192+
stackoverflow_panel.display_panel(questions_list)
193+
# Support for reddit searching can also be implemented from here
166194

167195
# Get an access token and extract to a JSON file "access_token.json"
168196
@classmethod

0 commit comments

Comments
 (0)