33
33
FAQEntry ,
34
34
FRDPEntry ,
35
35
ParamDocEntry ,
36
+ ReadmeSection ,
36
37
WikiPage ,
37
38
)
38
39
from .github import GitHub
@@ -43,13 +44,14 @@ class Search:
43
44
def __init__ (self ,github_auth :str ,github_user_agent :str = USER_AGENT )-> None :
44
45
self .__lock = asyncio .Lock ()
45
46
self ._docs :List [DocEntry ]= []
47
+ self ._readme :List [ReadmeSection ]= []
46
48
self ._official :Dict [str ,str ]= {}
47
49
self ._wiki :List [WikiPage ]= []
48
50
self ._snippets :List [CodeSnippet ]= []
49
51
self ._faq :List [FAQEntry ]= []
50
52
self ._design_patterns :List [FRDPEntry ]= []
51
53
self .github = GitHub (auth = github_auth ,user_agent = github_user_agent )
52
- self ._httpx_client = httpx .AsyncClient ()
54
+ self ._httpx_client = httpx .AsyncClient (headers = DEFAULT_HEADERS )
53
55
54
56
async def initialize (
55
57
self ,application :Application [Any ,Any ,Any ,Any ,Any ,JobQueue ]
@@ -76,6 +78,7 @@ async def update_job(self, context: ContextTypes.DEFAULT_TYPE) -> None:
76
78
)
77
79
async with self .__lock :
78
80
await asyncio .gather (
81
+ context .application .create_task (self .update_readme ()),
79
82
context .application .create_task (self .update_docs ()),
80
83
context .application .create_task (self .update_wiki ()),
81
84
context .application .create_task (self .update_wiki_code_snippets ()),
@@ -108,7 +111,7 @@ async def update_job(self, context: ContextTypes.DEFAULT_TYPE) -> None:
108
111
self .multi_search_combinations .cache_clear ()# pylint:disable=no-member
109
112
110
113
async def _update_official_docs (self )-> None :
111
- response = await self ._httpx_client .get (url = OFFICIAL_URL , headers = DEFAULT_HEADERS )
114
+ response = await self ._httpx_client .get (url = OFFICIAL_URL )
112
115
official_soup = BeautifulSoup (response .content ,"html.parser" )
113
116
for anchor in official_soup .select ("a.anchor" ):
114
117
if "-" not in anchor ["href" ]:
@@ -173,8 +176,26 @@ async def update_docs(self) -> None:
173
176
)
174
177
)
175
178
179
+ async def update_readme (self )-> None :
180
+ response = await self ._httpx_client .get (url = DOCS_URL ,follow_redirects = True )
181
+ readme_soup = BeautifulSoup (response .content ,"html.parser" )
182
+ self ._readme = []
183
+
184
+ # parse section headers from readme
185
+ for tag in ["h1" ,"h2" ,"h3" ,"h4" ,"h5" ]:
186
+ for headline in readme_soup .select (tag ):
187
+ # check if element is inside a hidden div - special casing for the
188
+ # "Hidden Headline" we include for furo
189
+ if headline .find_parent ("div" ,attrs = {"style" :"display: none" }):
190
+ continue
191
+ self ._readme .append (
192
+ ReadmeSection (
193
+ name = str (headline .contents [0 ]).strip (),anchor = headline .find ("a" )["href" ]
194
+ )
195
+ )
196
+
176
197
async def update_wiki (self )-> None :
177
- response = await self ._httpx_client .get (url = WIKI_URL , headers = DEFAULT_HEADERS )
198
+ response = await self ._httpx_client .get (url = WIKI_URL )
178
199
wiki_soup = BeautifulSoup (response .content ,"html.parser" )
179
200
self ._wiki = []
180
201
@@ -195,9 +216,7 @@ async def update_wiki(self) -> None:
195
216
self ._wiki .append (WikiPage (category = "Code Resources" ,name = "Examples" ,url = EXAMPLES_URL ))
196
217
197
218
async def update_wiki_code_snippets (self )-> None :
198
- response = await self ._httpx_client .get (
199
- url = WIKI_CODE_SNIPPETS_URL ,headers = DEFAULT_HEADERS
200
- )
219
+ response = await self ._httpx_client .get (url = WIKI_CODE_SNIPPETS_URL )
201
220
code_snippet_soup = BeautifulSoup (response .content ,"html.parser" )
202
221
self ._snippets = []
203
222
for headline in code_snippet_soup .select (
@@ -211,7 +230,7 @@ async def update_wiki_code_snippets(self) -> None:
211
230
)
212
231
213
232
async def update_wiki_faq (self )-> None :
214
- response = await self ._httpx_client .get (url = WIKI_FAQ_URL , headers = DEFAULT_HEADERS )
233
+ response = await self ._httpx_client .get (url = WIKI_FAQ_URL )
215
234
faq_soup = BeautifulSoup (response .content ,"html.parser" )
216
235
self ._faq = []
217
236
for headline in faq_soup .select ("div#wiki-body h3" ):
@@ -223,7 +242,7 @@ async def update_wiki_faq(self) -> None:
223
242
)
224
243
225
244
async def update_wiki_design_patterns (self )-> None :
226
- response = await self ._httpx_client .get (url = WIKI_FRDP_URL , headers = DEFAULT_HEADERS )
245
+ response = await self ._httpx_client .get (url = WIKI_FRDP_URL )
227
246
frdp_soup = BeautifulSoup (response .content ,"html.parser" )
228
247
self ._design_patterns = []
229
248
for headline in frdp_soup .select ("div#wiki-body h3,div#wiki-body h2" ):
@@ -244,9 +263,10 @@ async def search(
244
263
)-> Optional [List [BaseEntry ]]:
245
264
"""Searches all available entries for appropriate results. This includes:
246
265
266
+ * readme sections
247
267
* wiki pages
248
268
* FAQ entries
249
- * Design Pattern entries entries
269
+ * Design Pattern entries
250
270
* Code snippets
251
271
* examples
252
272
* documentation
@@ -312,6 +332,7 @@ async def search(
312
332
async with self .__lock :
313
333
if not search_entries :
314
334
search_entries = itertools .chain (
335
+ self ._readme ,
315
336
self ._wiki ,
316
337
self .github .all_examples ,
317
338
self ._faq ,