From 40ce9442e4ae60c5144ebd718ccef8f725361f8d Mon Sep 17 00:00:00 2001 From: Flawed <33593723+ff14wed@users.noreply.github.com> Date: Mon, 2 Mar 2026 21:42:18 -0800 Subject: [PATCH] Fix ffxiv_info for maintenance page --- automation/ffxiv_info.py | 111 ++++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 37 deletions(-) diff --git a/automation/ffxiv_info.py b/automation/ffxiv_info.py index 622ab4b..d42c633 100644 --- a/automation/ffxiv_info.py +++ b/automation/ffxiv_info.py @@ -17,8 +17,9 @@ VERSIONS_FILE = os.path.join(BASE_DIR, "automation", "ffxiv_versions_global.json def fetch_url(url, is_json=False): print(f"Fetching {url}...", file=sys.stderr) headers = { - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36", - "accept": "application/json", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8", + "Accept-Language": "en-US,en;q=0.9", } req = urllib.request.Request(url, headers=headers) try: @@ -27,6 +28,22 @@ def fetch_url(url, is_json=False): if is_json: return json.loads(content) return content + except urllib.error.HTTPError as e: + if e.code == 503: + print( + f" Received 503 for {url}. Maintenance mode. Reading body anyway...", + file=sys.stderr, + ) + try: + content = e.read().decode("utf-8") + if is_json: + return json.loads(content) + return content + except Exception: + return None + else: + print(f" HTTP Error {e.code}: {e.reason}", file=sys.stderr) + return None except Exception as e: print(f" Error fetching {url}: {e}", file=sys.stderr) return None @@ -83,23 +100,29 @@ def fetch_latest_thaliak_patch() -> Optional[str]: def parse_lodestone_news_list(html): """ - Parses the Lodestone news category page to extract individual news items. + Parses the Lodestone news list to extract news items (URL, Title, and Timestamp). + Handles the structure found on both the news category and the main landing page. """ if not html: return [] + + # This pattern captures the link and the title following it within the same list item structure. + # It accounts for the multi-line whitespace and optional tags like [Maintenance]. + # Timestamp is optional as fallback pages may not have the JS helper. pattern = re.compile( - r'
(?:]*>.*?)?(?P
]*class="news__list--title"[^>]*>(?P