1414
1515if TYPE_CHECKING :
1616 from collections .abc import Mapping , Sequence
17+ from http .cookies import Morsel
1718 from logging import Logger
1819 from typing import Final
1920
2021
2122__all__ : "Sequence[str]" = (
2223 "fetch_community_group_members_count" ,
2324 "fetch_community_group_members_list" ,
25+ "fetch_url_content_with_session" ,
2426 "is_id_a_community_group_member" ,
2527)
2628
2729
2830logger : "Final[Logger]" = logging .getLogger ("TeX-Bot" )
2931
30-
3132BASE_SU_PLATFORM_WEB_HEADERS : "Final[Mapping[str, str]]" = {
3233 "Cache-Control" : "no-cache" ,
3334 "Pragma" : "no-cache" ,
3435 "Expires" : "0" ,
3536}
3637
37- BASE_SU_PLATFORM_WEB_COOKIES : "Final[ Mapping[str, str] ]" = {
38+ BASE_SU_PLATFORM_WEB_COOKIES : "Mapping[str, str]" = {
3839 ".AspNet.SharedCookie" : settings ["SU_PLATFORM_ACCESS_COOKIE" ],
3940}
4041
4344_membership_list_cache : set [int ] = set ()
4445
4546
46- async def fetch_community_group_members_list () -> set [int ]:
47- """
48- Make a web request to fetch your community group's full membership list.
49-
50- Returns a set of IDs.
51- """
47+ async def fetch_url_content_with_session (url : str ) -> str :
48+ """Fetch the HTTP content at the given URL, using a shared aiohttp session."""
49+ global BASE_SU_PLATFORM_WEB_COOKIES # noqa: PLW0603
5250 async with (
5351 aiohttp .ClientSession (
5452 headers = BASE_SU_PLATFORM_WEB_HEADERS , cookies = BASE_SU_PLATFORM_WEB_COOKIES
5553 ) as http_session ,
56- http_session .get (url = MEMBERS_LIST_URL , ssl = GLOBAL_SSL_CONTEXT ) as http_response ,
54+ http_session .get (url = url , ssl = GLOBAL_SSL_CONTEXT ) as http_response ,
5755 ):
58- response_html : str = await http_response .text ()
56+ returned_asp_cookie : Morsel [str ] | None = http_response .cookies .get (
57+ ".AspNet.SharedCookie"
58+ )
59+ if returned_asp_cookie is not None and (
60+ returned_asp_cookie .value != BASE_SU_PLATFORM_WEB_COOKIES [".AspNet.SharedCookie" ]
61+ ):
62+ logger .info ("SU platform access cookie was updated by the server; updating local." )
63+ BASE_SU_PLATFORM_WEB_COOKIES = {
64+ ".AspNet.SharedCookie" : returned_asp_cookie .value ,
65+ }
66+ return await http_response .text ()
5967
60- parsed_html : BeautifulSoup = BeautifulSoup (markup = response_html , features = "html.parser" )
68+
69+ async def fetch_community_group_members_list () -> set [int ]:
70+ """
71+ Make a web request to fetch your community group's full membership list.
72+
73+ Returns a set of IDs.
74+ """
75+ parsed_html : BeautifulSoup = BeautifulSoup (
76+ markup = await fetch_url_content_with_session (MEMBERS_LIST_URL ), features = "html.parser"
77+ )
6178
6279 member_ids : set [int ] = set ()
6380
@@ -72,7 +89,7 @@ async def fetch_community_group_members_list() -> set[int]:
7289
7390 if filtered_table is None :
7491 logger .warning ("Membership table with ID %s could not be found." , table_id )
75- logger .debug (response_html )
92+ logger .debug (parsed_html )
7693 continue
7794
7895 if isinstance (filtered_table , bs4 .NavigableString ):
@@ -97,7 +114,7 @@ async def fetch_community_group_members_list() -> set[int]:
97114 if not member_ids : # NOTE: this should never be possible, because to fetch the page you need to have admin access, which requires being a member.
98115 NO_MEMBERS_MESSAGE : Final [str ] = "No members were found in either membership table."
99116 logger .warning (NO_MEMBERS_MESSAGE )
100- logger .debug (response_html )
117+ logger .debug (parsed_html )
101118 raise MSLMembershipError (message = NO_MEMBERS_MESSAGE )
102119
103120 _membership_list_cache .clear ()
0 commit comments