Make the Apple script compatible with the way update.py now works, which is 'product' oriented, meaning the script will be called once for each product. To minimize the impacts the responses are now cached to avoid rate-limiting by support.apple.com. Version patterns have also been moved to product's auto configuration to make future changes simpler.
57 lines
2.7 KiB
Python
57 lines
2.7 KiB
Python
import logging
|
|
import re
|
|
import sys
|
|
|
|
from bs4 import BeautifulSoup
|
|
from common import dates, endoflife, http, releasedata
|
|
|
|
"""Fetches and parses version and release date information from Apple's support website."""
|
|
|
|
URLS = [
|
|
"https://support.apple.com/en-us/HT201222", # latest
|
|
"https://support.apple.com/kb/HT213078", # 2018-2019
|
|
"https://support.apple.com/kb/HT213077", # 2016-2017
|
|
"https://support.apple.com/kb/HT209441", # 2015
|
|
"https://support.apple.com/kb/HT205762", # 2014
|
|
"https://support.apple.com/kb/HT205759", # 2013
|
|
"https://support.apple.com/kb/HT204611", # 2011 to 2012
|
|
# Apple still links to the following articles, but they are 404:
|
|
"http://web.archive.org/web/20230404214605_/https://support.apple.com/en-us/HT5165", # 2010
|
|
"http://web.archive.org/web/20230327200842_/https://support.apple.com/en-us/HT4218", # 2008-2009
|
|
"http://web.archive.org/web/20230204234533_/https://support.apple.com/en-us/HT1263", # 2005-2007
|
|
]
|
|
|
|
DATE_PATTERN = re.compile(r"\b\d+\s[A-Za-z]+\s\d+\b")
|
|
METHOD = 'apple'
|
|
|
|
p_filter = sys.argv[1] if len(sys.argv) > 1 else None
|
|
m_filter = sys.argv[2] if len(sys.argv) > 2 else None
|
|
for config in endoflife.list_configs(p_filter, METHOD, m_filter):
|
|
with releasedata.ProductData(config.product) as product_data:
|
|
# URLs are cached to avoid rate limiting by support.apple.com.
|
|
soups = [BeautifulSoup(response.text, features="html5lib") for response in http.fetch_urls(URLS, cache=True)]
|
|
|
|
for soup in soups:
|
|
versions_table = soup.find(id="tableWraper")
|
|
versions_table = versions_table if versions_table else soup.find('table', class_="gb-table")
|
|
|
|
for row in versions_table.findAll("tr")[1:]:
|
|
cells = row.findAll("td")
|
|
version_text = cells[0].get_text().strip()
|
|
date_text = cells[2].get_text().strip()
|
|
|
|
date_match = DATE_PATTERN.search(date_text)
|
|
if not date_match:
|
|
logging.info(f"ignoring version {version_text} ({date_text}), date pattern don't match")
|
|
continue
|
|
|
|
date_str = date_match.group(0).replace("Sept ", "Sep ")
|
|
date = dates.parse_date(date_str)
|
|
for version_pattern in config.include_version_patterns:
|
|
for version_str in version_pattern.findall(version_text):
|
|
version = product_data.get_version(version_str)
|
|
if not version or version.date() > date:
|
|
product_data.declare_version(version_str, date)
|
|
else:
|
|
logging.info(f"ignoring version {version_str} ({date}) for {product_data.name}")
|