88import random
99import re
1010
11- CYCLE_DEBOUNCE_TIME = 12 # How long it takes to resfresh wiki titles
11+ CYCLE_DEBOUNCE_TIME : int = 12 # How long it takes to resfresh wiki titles
1212BATCH_SIZE : int = 50 # max titles per request
13+ REAUTHENTICATE_ATTEMPTS : int = (
14+ 3 # The amount of times it will attempt to re-authenticare
15+ )
1316
1417HEADERS : dict [str , str ] = {"User-Agent" : "JumpstartFetcher/1.0" }
1518AUTH : tuple [str ] = (WIKIBOT_USER , WIKIBOT_PASSWORD )
1619
1720client : httpx .AsyncClient = httpx .AsyncClient (headers = HEADERS , auth = AUTH )
21+
1822logger : logging .Logger = logging .getLogger (__name__ )
1923
2024bot_authenticated : bool = False
3943RE_IMAGE : Pattern [str ] = re .compile (r"\[\[Image:[^\]]*\]\]" , re .IGNORECASE )
4044RE_PAGE_TEXT : Pattern [str ] = re .compile (r"\[\[[^\|\]]*\|([^\]]+)\]\]" )
4145RE_PAGE : Pattern [str ] = re .compile (r"\[\[([^\]]+)\]\]" )
42- RE_CSH : Pattern [str ] = re .compile (r"\^\^([^\] ]+)\^\^" )
46+ RE_CSH : Pattern [str ] = re .compile (r"\^\^([^^ ]+)\^\^" )
4347RE_TEMPLATE : Pattern [str ] = re .compile (r"\{\{.*?\}\}" , re .DOTALL )
4448RE_HTML : Pattern [str ] = re .compile (r"<[^>]+>" )
4549RE_BOLD_ITALIC : Pattern [str ] = re .compile (r"''+" )
@@ -89,6 +93,9 @@ def batch_iterable(iterable: list, size: int):
8993 Generator function for splitting up lists into smaller lists
9094 To be frank, found this online when researching about the MediaWiki API
9195
96+ Args:
97+ iterable (list): The iterable to be split up for batches
98+ size (int): the size of the batches
9299 Yields:
93100 A batch split by the requested size
94101 """
@@ -130,6 +137,7 @@ async def auth_bot() -> None:
130137 bot_authenticated = True
131138 logger .info ("Bot was authenticated successfully!" )
132139 else :
140+ bot_authenticated = False
133141 logger .warning ("Bot was unable to authenticate!" )
134142
135143
@@ -172,7 +180,7 @@ def needs_category_refresh(update_time: datetime) -> bool:
172180 update_time (datetime): The datetime to be compared against the cache
173181
174182 Returns:
175- boolean : if the cache needs to be refreshed
183+ bool : if the cache needs to be refreshed
176184 """
177185
178186 if not bot_authenticated :
@@ -186,17 +194,16 @@ def needs_category_refresh(update_time: datetime) -> bool:
186194 )
187195
188196
189- def process_category_page (response : httpx . Response ) -> tuple [list [str ], bool | str ]:
197+ def process_category_page (r_json : dict [ str , str ] ) -> tuple [list [str ], bool | str ]:
190198 """
191199 Processes a wikithoughts response into a list of title pages
192200
193201 Args:
194- respone (httpx.Response ): The response from the wiki to be processed
202+ r_json (dict[str,str] ): The JSON from the wiki to be processed
195203
196204 Returns:
197205 tuple[list[str], bool | str]: The list of titles from the request, along with a possible continutation if needed
198206 """
199- r_json : dict [str , str ] = response .json ()
200207 titles : list [str ] = []
201208 if "query" in r_json :
202209 for page in r_json ["query" ]["categorymembers" ]:
@@ -239,6 +246,9 @@ async def refresh_category_pages() -> list[str]:
239246
240247 headers : dict [str , str ] = headers_formatting ()
241248 # This needs to loop due to mediawiki limitations
249+
250+ failed_authentication_attempts : int = 0
251+
242252 while True :
243253 response : httpx .Response = await client .get (
244254 WIKI_API , params = params , headers = headers
@@ -250,7 +260,30 @@ async def refresh_category_pages() -> list[str]:
250260
251261 elif response .status_code == 200 :
252262 headers_formatting (etag , last_modifed )
253- added , repeat_req = process_category_page (response = response )
263+ r_json : dict [str , str ] = response .json ()
264+
265+ if "error" in r_json and r_json ["error" ].get ("code" ) in (
266+ "readapidenied" ,
267+ "notloggedin" ,
268+ ):
269+ if failed_authentication_attempts > REAUTHENTICATE_ATTEMPTS :
270+ logger .warning (
271+ "Reauthenticating the wikithought bot failed, sending empty response"
272+ )
273+ return []
274+
275+ logger .info (f"Both was unauthenticated, attempting to reauthenticate!" )
276+ await auth_bot ()
277+ if not (bot_authenticated ):
278+ logger .warning (
279+ "Failed to reauthenticate the bot! Attempt: "
280+ + failed_authentication_attempts
281+ )
282+
283+ failed_authentication_attempts += 1
284+ continue
285+
286+ added , repeat_req = process_category_page (r_json )
254287 titles += added
255288
256289 if repeat_req not in (None , False , "" ):
0 commit comments