Apply various minor refactorings
Improve readability and fix a few Python warnings (line too long, exception too broad...) through various minor refactorings.
This commit is contained in:
@@ -16,9 +16,9 @@ URLS = [
|
|||||||
"https://support.apple.com/kb/HT1263", # 2005-2007
|
"https://support.apple.com/kb/HT1263", # 2005-2007
|
||||||
]
|
]
|
||||||
|
|
||||||
# If you are changing these, please
|
# If you are changing these, please use
|
||||||
# use https://gist.githubusercontent.com/captn3m0/e7cb1f4fc3c07a5da0296ebda2b33e15/raw/5747e42ad611ec9ffdb7a2d1c0e3946bb87ab6d7/apple.txt as your corpus
|
# https://gist.githubusercontent.com/captn3m0/e7cb1f4fc3c07a5da0296ebda2b33e15/raw/5747e42ad611ec9ffdb7a2d1c0e3946bb87ab6d7/apple.txt
|
||||||
# to validate your changes
|
# as your corpus to validate your changes
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"macos": [
|
"macos": [
|
||||||
# This covers Sierra and beyond
|
# This covers Sierra and beyond
|
||||||
|
|||||||
24
src/cos.py
24
src/cos.py
@@ -3,6 +3,7 @@ from bs4 import BeautifulSoup
|
|||||||
from common import endoflife
|
from common import endoflife
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
DATE_FORMAT = '%b %d, %Y'
|
||||||
REGEX = r"^(cos-\d+-\d+-\d+-\d+)"
|
REGEX = r"^(cos-\d+-\d+-\d+-\d+)"
|
||||||
|
|
||||||
|
|
||||||
@@ -16,34 +17,35 @@ def fetch_all_milestones():
|
|||||||
|
|
||||||
|
|
||||||
def fetch_milestone(channel):
|
def fetch_milestone(channel):
|
||||||
url = "https://cloud.google.com/container-optimized-os/docs/release-notes/m{}".format(channel)
|
url = f"https://cloud.google.com/container-optimized-os/docs/release-notes/m{channel}"
|
||||||
# Retry as Google Docs often returns SSL errors.
|
# Retry as Google Docs often returns SSL errors.
|
||||||
response = endoflife.fetch_url(url, retry_count=10)
|
response = endoflife.fetch_url(url, retry_count=10)
|
||||||
return BeautifulSoup(response, features="html5lib")
|
return BeautifulSoup(response, features="html5lib")
|
||||||
|
|
||||||
|
|
||||||
|
def parse_date(d):
|
||||||
|
# If the date begins with a >3 letter month name, trim it to just 3 letters
|
||||||
|
# Strip out the Date: section from the start
|
||||||
|
d = re.sub(r'(?:Date\: )?(\w{3})(?:\w{1,4})? (\d{1,2}), (\d{4})', r'\1 \2, \3', d)
|
||||||
|
return datetime.strptime(d, DATE_FORMAT).strftime('%Y-%m-%d')
|
||||||
|
|
||||||
|
|
||||||
def parse_soup_for_versions(soup):
|
def parse_soup_for_versions(soup):
|
||||||
"""Takes soup, and returns a dictionary of versions and their release dates
|
"""Takes soup, and returns a dictionary of versions and their release dates
|
||||||
"""
|
"""
|
||||||
versions = {}
|
versions = {}
|
||||||
for article in soup.find_all('article', class_='devsite-article'):
|
for article in soup.find_all('article', class_='devsite-article'):
|
||||||
def parse_date(d):
|
|
||||||
# If the date begins with a >3 letter month name, trim it to just 3 letters
|
|
||||||
# Strip out the Date: section from the start
|
|
||||||
d = re.sub(r'(?:Date\: )?(\w{3})(?:\w{1,4})? (\d{1,2}), (\d{4})', r'\1 \2, \3', d)
|
|
||||||
return datetime.strptime(d, date_format).strftime('%Y-%m-%d')
|
|
||||||
# h2 contains the date, which we parse
|
# h2 contains the date, which we parse
|
||||||
for heading in article.find_all(['h2', 'h3']):
|
for heading in article.find_all(['h2', 'h3']):
|
||||||
version = heading.get('data-text')
|
version = heading.get('data-text')
|
||||||
m = re.match(REGEX, version)
|
m = re.match(REGEX, version)
|
||||||
if m:
|
if m:
|
||||||
version = m.group(1)
|
version = m.group(1)
|
||||||
date_format = '%b %d, %Y'
|
|
||||||
try:
|
try:
|
||||||
# The first row is the header, so we pick the first td in the second row
|
# 1st row is the header, so pick the first td in the 2nd row
|
||||||
d = heading.find_next('tr').find_next('tr').find_next('td').text
|
d = heading.find_next('tr').find_next('tr').find_next('td').text
|
||||||
except:
|
except AttributeError:
|
||||||
# In some older releases, it is mentioned as Date: [Date] in the text
|
# In some older releases, it is mentioned as Date: [Date]
|
||||||
d = heading.find_next('i').text
|
d = heading.find_next('i').text
|
||||||
try:
|
try:
|
||||||
date = parse_date(d)
|
date = parse_date(d)
|
||||||
@@ -51,7 +53,7 @@ def parse_soup_for_versions(soup):
|
|||||||
d = heading.find_previous('h2').get('data-text')
|
d = heading.find_previous('h2').get('data-text')
|
||||||
date = parse_date(d)
|
date = parse_date(d)
|
||||||
versions[version] = date
|
versions[version] = date
|
||||||
print("%s: %s" % (version, date))
|
print(f"{version}: {date}")
|
||||||
|
|
||||||
return versions
|
return versions
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ def clone_repository():
|
|||||||
ret_code = call(f"git {git_opts} pull --depth 1 origin master", shell=True)
|
ret_code = call(f"git {git_opts} pull --depth 1 origin master", shell=True)
|
||||||
exit(-ret_code) if ret_code < 0 else None
|
exit(-ret_code) if ret_code < 0 else None
|
||||||
|
|
||||||
|
|
||||||
def extract_major_releases(releases):
|
def extract_major_releases(releases):
|
||||||
child = subprocess.Popen(
|
child = subprocess.Popen(
|
||||||
f"grep -RhE -A 1 '<define-tag pagetitle>Debian [0-9]+.+</q> released' {REPO_DIR}/english/News "
|
f"grep -RhE -A 1 '<define-tag pagetitle>Debian [0-9]+.+</q> released' {REPO_DIR}/english/News "
|
||||||
@@ -48,8 +49,8 @@ def extract_major_releases(releases):
|
|||||||
is_release_line = False
|
is_release_line = False
|
||||||
else:
|
else:
|
||||||
date = line
|
date = line
|
||||||
print(f"{version}: {date}")
|
|
||||||
releases[version] = date
|
releases[version] = date
|
||||||
|
print(f"{version}: {date}")
|
||||||
is_release_line = True
|
is_release_line = True
|
||||||
|
|
||||||
|
|
||||||
@@ -75,11 +76,11 @@ def extract_point_releases(releases):
|
|||||||
|
|
||||||
print(f"::group::{PRODUCT}")
|
print(f"::group::{PRODUCT}")
|
||||||
clone_repository()
|
clone_repository()
|
||||||
releases = {}
|
all_releases = {}
|
||||||
extract_major_releases(releases)
|
extract_major_releases(all_releases)
|
||||||
extract_point_releases(releases)
|
extract_point_releases(all_releases)
|
||||||
endoflife.write_releases(PRODUCT, dict(
|
endoflife.write_releases(PRODUCT, dict(
|
||||||
# sort by date then version (desc)
|
# sort by date then version (desc)
|
||||||
sorted(releases.items(), key=lambda x: (x[1], x[0]), reverse=True)
|
sorted(all_releases.items(), key=lambda x: (x[1], x[0]), reverse=True)
|
||||||
))
|
))
|
||||||
print("::endgroup::")
|
print("::endgroup::")
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ def fetch_releases(distrowatch_id, regex, template):
|
|||||||
headline = table.select_one("td.NewsHeadline a[href]").get_text().strip()
|
headline = table.select_one("td.NewsHeadline a[href]").get_text().strip()
|
||||||
date = table.select_one("td.NewsDate").get_text()
|
date = table.select_one("td.NewsDate").get_text()
|
||||||
for v in get_versions_from_headline(regex, headline, l_template):
|
for v in get_versions_from_headline(regex, headline, l_template):
|
||||||
print("%s: %s" % (v, date))
|
print(f"{v}: {date}")
|
||||||
releases[v] = date
|
releases[v] = date
|
||||||
return releases
|
return releases
|
||||||
|
|
||||||
@@ -52,6 +52,6 @@ def update_product(product_name, configs):
|
|||||||
|
|
||||||
p_filter = sys.argv[1] if len(sys.argv) > 1 else None
|
p_filter = sys.argv[1] if len(sys.argv) > 1 else None
|
||||||
for product, configs in endoflife.list_products(METHOD, p_filter).items():
|
for product, configs in endoflife.list_products(METHOD, p_filter).items():
|
||||||
print("::group::%s" % product)
|
print(f"::group::{product}")
|
||||||
update_product(product, configs)
|
update_product(product, configs)
|
||||||
print("::endgroup::")
|
print("::endgroup::")
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ def parse_platforms_page():
|
|||||||
d = datetime.strptime(date, "%B %d, %Y").strftime("%Y-%m-%d")
|
d = datetime.strptime(date, "%B %d, %Y").strftime("%Y-%m-%d")
|
||||||
k8s_version = ".".join(data[0].text.split(".")[:-1])
|
k8s_version = ".".join(data[0].text.split(".")[:-1])
|
||||||
eks_version = data[1].text.replace(".", "-")
|
eks_version = data[1].text.replace(".", "-")
|
||||||
version = "%s-%s" % (k8s_version, eks_version)
|
version = f"{k8s_version}-{eks_version}"
|
||||||
all_versions[version] = d
|
all_versions[version] = d
|
||||||
print("%s: %s" % (version, d))
|
print(f"{version}: {d}")
|
||||||
print("::endgroup::")
|
print("::endgroup::")
|
||||||
return all_versions
|
return all_versions
|
||||||
|
|
||||||
|
|||||||
@@ -6,21 +6,25 @@ from common import endoflife
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
"""Fetch Firefox versions with their dates from https://www.mozilla.org/en-US/firefox/releases/"""
|
"""Fetch Firefox versions with their dates from https://www.mozilla.org/"""
|
||||||
|
|
||||||
URL = "https://www.mozilla.org/en-US/firefox/releases/"
|
URL = "https://www.mozilla.org/en-US/firefox/releases/"
|
||||||
PRODUCT = "firefox"
|
PRODUCT = "firefox"
|
||||||
|
|
||||||
DATE_REGEX = r"(January|Jan|February|Feb|March|Mar|April|Apr|May|June|Jun|July|Jul|August|Aug|September|Sept|October|Oct|November|Nov|December|Dec)\s+\d{1,2}(st|nd|rd|th)?,\s+\d{4}"
|
DATE_REGEX = r"(January|Jan|February|Feb|March|Mar|April|Apr|May|June|Jun|July|Jul|August|Aug|September|Sept|October|Oct|November|Nov|December|Dec)\s+\d{1,2}(st|nd|rd|th)?,\s+\d{4}"
|
||||||
VERSION_REGEX = r"\d+(\.\d+)*"
|
VERSION_REGEX = r"\d+(\.\d+)*"
|
||||||
|
|
||||||
class UnsupportedReleasePageError(Exception):
|
|
||||||
"Raised when a firefox release page is not supported"
|
class UnsupportedPageError(Exception):
|
||||||
|
"""Raised when a firefox release page is not supported"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InvalidPageVariantError(Exception):
|
class InvalidPageVariantError(Exception):
|
||||||
"Raised when an invalid variant is passed to get_version_and_date"
|
"""Raised when an invalid variant is passed to get_version_and_date"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def format_date(unformatted_date: str) -> str:
|
def format_date(unformatted_date: str) -> str:
|
||||||
""" Format date from July 11, 2002 to 2002-07-11 """
|
""" Format date from July 11, 2002 to 2002-07-11 """
|
||||||
date = re.sub(r'(\d)(st|nd|rd|th)', r'\1', unformatted_date)
|
date = re.sub(r'(\d)(st|nd|rd|th)', r'\1', unformatted_date)
|
||||||
@@ -32,7 +36,8 @@ def format_date(unformatted_date: str) -> str:
|
|||||||
pass
|
pass
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def get_version_and_date_varant_1(soup: BeautifulSoup) -> Tuple[str, str]:
|
|
||||||
|
def get_version_and_date_variant_1(soup: BeautifulSoup) -> Tuple[str, str]:
|
||||||
""" Version matching for firefox versions >= 28.0 (usually) """
|
""" Version matching for firefox versions >= 28.0 (usually) """
|
||||||
# get version
|
# get version
|
||||||
version = soup.find("div", class_="c-release-version").get_text()
|
version = soup.find("div", class_="c-release-version").get_text()
|
||||||
@@ -41,7 +46,8 @@ def get_version_and_date_varant_1(soup: BeautifulSoup) -> Tuple[str, str]:
|
|||||||
unformatted_date = soup.find("p", class_="c-release-date").get_text()
|
unformatted_date = soup.find("p", class_="c-release-date").get_text()
|
||||||
date = format_date(unformatted_date)
|
date = format_date(unformatted_date)
|
||||||
|
|
||||||
return (version, date)
|
return version, date
|
||||||
|
|
||||||
|
|
||||||
def get_version_and_date_variant_2(soup: BeautifulSoup) -> Tuple[str, str]:
|
def get_version_and_date_variant_2(soup: BeautifulSoup) -> Tuple[str, str]:
|
||||||
""" Version matching for firefox versions >= 10.0 (usually) """
|
""" Version matching for firefox versions >= 10.0 (usually) """
|
||||||
@@ -60,7 +66,8 @@ def get_version_and_date_variant_2(soup: BeautifulSoup) -> Tuple[str, str]:
|
|||||||
unformatted_date = unformatted_date_match.group()
|
unformatted_date = unformatted_date_match.group()
|
||||||
date = format_date(unformatted_date)
|
date = format_date(unformatted_date)
|
||||||
|
|
||||||
return (version, date)
|
return version, date
|
||||||
|
|
||||||
|
|
||||||
def get_version_and_date_variant_3(soup: BeautifulSoup) -> Tuple[str, str]:
|
def get_version_and_date_variant_3(soup: BeautifulSoup) -> Tuple[str, str]:
|
||||||
""" Version matching for firefox versions >= 3.0 (usually) """
|
""" Version matching for firefox versions >= 3.0 (usually) """
|
||||||
@@ -79,22 +86,27 @@ def get_version_and_date_variant_3(soup: BeautifulSoup) -> Tuple[str, str]:
|
|||||||
unformatted_date = unformatted_date_match.group()
|
unformatted_date = unformatted_date_match.group()
|
||||||
date = format_date(unformatted_date)
|
date = format_date(unformatted_date)
|
||||||
|
|
||||||
return (version, date)
|
return version, date
|
||||||
|
|
||||||
|
|
||||||
def get_version_and_date(release_page: str, release_version: str) -> Tuple[str, str]:
|
def get_version_and_date(release_page: str, release_version: str) -> Tuple[str, str]:
|
||||||
""" Get version and date from the given release page """
|
""" Get version and date from the given release page """
|
||||||
major = int(release_version.split(".")[0])
|
major = int(release_version.split(".")[0])
|
||||||
|
|
||||||
# firefox release pages for versions <3.0 don't include release dates so we
|
# firefox release pages for versions <3.0 don't include release dates, so we
|
||||||
# can't match these versions for now.
|
# can't match these versions for now.
|
||||||
# example: https://www.mozilla.org/en-US/firefox/2.0/releasenotes/
|
# example: https://www.mozilla.org/en-US/firefox/2.0/releasenotes/
|
||||||
if major < 3:
|
if major < 3:
|
||||||
raise UnsupportedReleasePageError("Unsupported release page: %s" % release_page)
|
raise UnsupportedPageError(f"Unsupported release page: {release_page}")
|
||||||
|
|
||||||
# Firefox release pages come in 3 different variants. Unforunately, there is no
|
# Firefox release pages come in 3 different variants. Unfortunately, there
|
||||||
# consistent way to determine which variant a page is (say, by version number), so
|
# is no consistent way to determine which variant a page is (say, by version
|
||||||
# we have to try each variant until we find one that works.
|
# number), so we have to try each variant until we find one that works.
|
||||||
functions = [get_version_and_date_varant_1, get_version_and_date_variant_2, get_version_and_date_variant_3]
|
functions = [
|
||||||
|
get_version_and_date_variant_1,
|
||||||
|
get_version_and_date_variant_2,
|
||||||
|
get_version_and_date_variant_3
|
||||||
|
]
|
||||||
soup = make_bs_request(release_page)
|
soup = make_bs_request(release_page)
|
||||||
|
|
||||||
for function in functions:
|
for function in functions:
|
||||||
@@ -103,13 +115,15 @@ def get_version_and_date(release_page: str, release_version: str) -> Tuple[str,
|
|||||||
except (InvalidPageVariantError, AttributeError, IndexError):
|
except (InvalidPageVariantError, AttributeError, IndexError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
raise UnsupportedReleasePageError("Unable to find version and date for %s" % release_page)
|
raise UnsupportedPageError(f"Unable to find version and date from {release_page}")
|
||||||
|
|
||||||
|
|
||||||
def make_bs_request(url: str) -> BeautifulSoup:
|
def make_bs_request(url: str) -> BeautifulSoup:
|
||||||
# requests to www.mozilla.org often time out, retry in case of failures
|
# requests to www.mozilla.org often time out, retry in case of failures
|
||||||
response = endoflife.fetch_url(url, timeout=10, retry_count=5)
|
response = endoflife.fetch_url(url, timeout=10, retry_count=5)
|
||||||
return BeautifulSoup(response, features="html5lib")
|
return BeautifulSoup(response, features="html5lib")
|
||||||
|
|
||||||
|
|
||||||
def fetch_releases():
|
def fetch_releases():
|
||||||
releases = {}
|
releases = {}
|
||||||
soup = make_bs_request(URL)
|
soup = make_bs_request(URL)
|
||||||
@@ -126,13 +140,14 @@ def fetch_releases():
|
|||||||
for future in concurrent.futures.as_completed(future_to_url):
|
for future in concurrent.futures.as_completed(future_to_url):
|
||||||
try:
|
try:
|
||||||
(version, date) = future.result()
|
(version, date) = future.result()
|
||||||
print("%s: %s" % (version, date))
|
print(f"{version}: {date}")
|
||||||
releases[version] = date
|
releases[version] = date
|
||||||
except UnsupportedReleasePageError:
|
except UnsupportedPageError:
|
||||||
print("Unsupported release page: %s" % future_to_url[future])
|
print(f"Unsupported release page: {future_to_url[future]}")
|
||||||
|
|
||||||
return releases
|
return releases
|
||||||
|
|
||||||
|
|
||||||
print(f"::group::{PRODUCT}")
|
print(f"::group::{PRODUCT}")
|
||||||
releases = fetch_releases()
|
releases = fetch_releases()
|
||||||
endoflife.write_releases(PRODUCT, dict(
|
endoflife.write_releases(PRODUCT, dict(
|
||||||
|
|||||||
@@ -43,9 +43,10 @@ query($endCursor: String) {
|
|||||||
|
|
||||||
|
|
||||||
def fetch_releases(repo_id, regex):
|
def fetch_releases(repo_id, regex):
|
||||||
"""Returns this repository releases using https://docs.github.com/en/rest/releases/releases#list-releases.
|
"""Returns this repository releases using
|
||||||
Only the first page is fetched: there are rate limit rules in place on the GitHub API, and the most recent
|
https://docs.github.com/en/rest/releases/releases#list-releases. Only the
|
||||||
releases are sufficient.
|
first page is fetched: there are rate limit rules in place on the GitHub
|
||||||
|
API, and the most recent releases are sufficient.
|
||||||
"""
|
"""
|
||||||
releases = {}
|
releases = {}
|
||||||
regex = [regex] if not isinstance(regex, list) else regex
|
regex = [regex] if not isinstance(regex, list) else regex
|
||||||
@@ -59,7 +60,7 @@ def fetch_releases(repo_id, regex):
|
|||||||
version = match.group(1)
|
version = match.group(1)
|
||||||
date = raw_date.split("T")[0]
|
date = raw_date.split("T")[0]
|
||||||
releases[version] = date
|
releases[version] = date
|
||||||
print("%s: %s" % (version, date))
|
print(f"{version}: {date}")
|
||||||
|
|
||||||
return releases
|
return releases
|
||||||
|
|
||||||
@@ -76,6 +77,6 @@ def update_product(product_name, configs):
|
|||||||
|
|
||||||
p_filter = sys.argv[1] if len(sys.argv) > 1 else None
|
p_filter = sys.argv[1] if len(sys.argv) > 1 else None
|
||||||
for product, configs in endoflife.list_products(METHOD, p_filter).items():
|
for product, configs in endoflife.list_products(METHOD, p_filter).items():
|
||||||
print("::group::%s" % product)
|
print(f"::group::{product}")
|
||||||
update_product(product, configs)
|
update_product(product, configs)
|
||||||
print("::endgroup::")
|
print("::endgroup::")
|
||||||
|
|||||||
24
src/gke.py
24
src/gke.py
@@ -5,42 +5,44 @@ from datetime import datetime
|
|||||||
|
|
||||||
# https://regex101.com/r/zPxBqT/1
|
# https://regex101.com/r/zPxBqT/1
|
||||||
REGEX = r"\d.\d+\.\d+-gke\.\d+"
|
REGEX = r"\d.\d+\.\d+-gke\.\d+"
|
||||||
|
CHANNELS = ['nochannel', 'stable', 'regular', 'rapid']
|
||||||
|
|
||||||
|
|
||||||
def fetch_channel(channel):
|
def fetch_channel(channel):
|
||||||
url = "https://cloud.google.com/kubernetes-engine/docs/release-notes-{}".format(channel)
|
url = f"https://cloud.google.com/kubernetes-engine/docs/release-notes-{channel}"
|
||||||
response = endoflife.fetch_url(url)
|
response = endoflife.fetch_url(url)
|
||||||
return BeautifulSoup(response, features="html5lib")
|
return BeautifulSoup(response, features="html5lib")
|
||||||
|
|
||||||
"""
|
|
||||||
Takes soup, and returns a dictionary of versions and their release dates
|
|
||||||
"""
|
|
||||||
def parse_soup_for_versions(soup):
|
def parse_soup_for_versions(soup):
|
||||||
""" Parse the soup """
|
"""Takes soup, and returns a dictionary of versions and their release dates
|
||||||
|
"""
|
||||||
versions = {}
|
versions = {}
|
||||||
for section in soup.find_all('section', class_='releases'):
|
for section in soup.find_all('section', class_='releases'):
|
||||||
# h2 contains the date, which we parse
|
# h2 contains the date, which we parse
|
||||||
for h2 in section.find_all('h2'):
|
for h2 in section.find_all('h2'):
|
||||||
date = h2.get('data-text')
|
date = h2.get('data-text')
|
||||||
date = datetime.strptime(date, '%B %d, %Y').strftime('%Y-%m-%d')
|
date = datetime.strptime(date, '%B %d, %Y').strftime('%Y-%m-%d')
|
||||||
# The div next to the h2 contains the notes about changes made on that date
|
# The div next to the h2 contains the notes about changes made
|
||||||
|
# on that date
|
||||||
next_div = h2.find_next('div')
|
next_div = h2.find_next('div')
|
||||||
# New releases are noted in a nested list, so we look for that
|
# New releases are noted in a nested list, so we look for that
|
||||||
# and parse it using the version regex
|
# and parse it using the version regex
|
||||||
for li in next_div.find_all('li'):
|
for li in next_div.find_all('li'):
|
||||||
# If the <li> text contains with "versions are now available:", get the <ul> inside the li
|
# If the <li> text contains with "versions are now available:",
|
||||||
|
# get the <ul> inside the li
|
||||||
if "versions are now available" in li.text:
|
if "versions are now available" in li.text:
|
||||||
ul = li.find('ul')
|
ul = li.find('ul')
|
||||||
for version in re.findall(REGEX, ul.text):
|
for version in re.findall(REGEX, ul.text):
|
||||||
versions[version] = date
|
versions[version] = date
|
||||||
print("%s: %s" % (version, date))
|
print(f"{version}: {date}")
|
||||||
return versions
|
return versions
|
||||||
|
|
||||||
CHANNELS = ['nochannel', 'stable', 'regular', 'rapid']
|
|
||||||
|
|
||||||
for channel in CHANNELS:
|
for channel in CHANNELS:
|
||||||
soup = fetch_channel(channel)
|
soup = fetch_channel(channel)
|
||||||
print("::group::GKE - {}".format(channel))
|
print(f"::group::GKE - {channel}")
|
||||||
versions = parse_soup_for_versions(soup)
|
versions = parse_soup_for_versions(soup)
|
||||||
name = 'gke' if channel == 'nochannel' else 'gke-{}'.format(channel)
|
name = 'gke' if channel == 'nochannel' else f'gke-{channel}'
|
||||||
endoflife.write_releases(name, versions)
|
endoflife.write_releases(name, versions)
|
||||||
print("::endgroup::")
|
print("::endgroup::")
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import re
|
|||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
from common import endoflife
|
from common import endoflife
|
||||||
|
|
||||||
"""Fetch HAProxy versions with their dates from https://www.haproxy.org/download/.
|
"""Fetch HAProxy versions with their dates from https://www.haproxy.org/.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
PRODUCT = "haproxy"
|
PRODUCT = "haproxy"
|
||||||
@@ -51,11 +51,11 @@ def print_releases(releases):
|
|||||||
|
|
||||||
|
|
||||||
print(f"::group::{PRODUCT}")
|
print(f"::group::{PRODUCT}")
|
||||||
cycles = fetch_cycles()
|
all_cycles = fetch_cycles()
|
||||||
releases = fetch_releases(cycles)
|
all_releases = fetch_releases(all_cycles)
|
||||||
print_releases(releases)
|
print_releases(all_releases)
|
||||||
endoflife.write_releases(PRODUCT, dict(
|
endoflife.write_releases(PRODUCT, dict(
|
||||||
# sort by date then version (desc)
|
# sort by date then version (desc)
|
||||||
sorted(releases.items(), key=lambda x: (x[1], x[0]), reverse=True)
|
sorted(all_releases.items(), key=lambda x: (x[1], x[0]), reverse=True)
|
||||||
))
|
))
|
||||||
print("::endgroup::")
|
print("::endgroup::")
|
||||||
|
|||||||
12
src/java.py
12
src/java.py
@@ -18,11 +18,12 @@ PRODUCT = "java"
|
|||||||
URL = "https://www.java.com/releases/"
|
URL = "https://www.java.com/releases/"
|
||||||
|
|
||||||
|
|
||||||
def fetch_releases(releases):
|
def fetch_releases():
|
||||||
session = HTMLSession()
|
session = HTMLSession()
|
||||||
r = session.get('https://www.java.com/releases/')
|
r = session.get('https://www.java.com/releases/')
|
||||||
r.html.render(sleep=1, scrolldown=3)
|
r.html.render(sleep=1, scrolldown=3)
|
||||||
|
|
||||||
|
releases = {}
|
||||||
previous_date = None
|
previous_date = None
|
||||||
for row in r.html.find('#released tr'):
|
for row in r.html.find('#released tr'):
|
||||||
version_cell = row.find('td.anchor', first=True)
|
version_cell = row.find('td.anchor', first=True)
|
||||||
@@ -35,13 +36,14 @@ def fetch_releases(releases):
|
|||||||
releases[version] = date
|
releases[version] = date
|
||||||
previous_date = date
|
previous_date = date
|
||||||
|
|
||||||
|
return releases
|
||||||
|
|
||||||
|
|
||||||
print(f"::group::{PRODUCT}")
|
print(f"::group::{PRODUCT}")
|
||||||
releases = {}
|
all_releases = fetch_releases()
|
||||||
fetch_releases(releases)
|
all_releases.pop('1.0_alpha') # only version we don't want, regex not needed
|
||||||
releases.pop('1.0_alpha') # that's the only version we do not want, regex not needed
|
|
||||||
endoflife.write_releases(PRODUCT, dict(
|
endoflife.write_releases(PRODUCT, dict(
|
||||||
# sort by date then version (desc)
|
# sort by date then version (desc)
|
||||||
sorted(releases.items(), key=lambda x: (x[1], x[0]), reverse=True)
|
sorted(all_releases.items(), key=lambda x: (x[1], x[0]), reverse=True)
|
||||||
))
|
))
|
||||||
print("::endgroup::")
|
print("::endgroup::")
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ def fetch_releases(package_identifier):
|
|||||||
if valid_version(version):
|
if valid_version(version):
|
||||||
date = datetime.datetime.utcfromtimestamp(row["timestamp"] / 1000).strftime("%Y-%m-%d")
|
date = datetime.datetime.utcfromtimestamp(row["timestamp"] / 1000).strftime("%Y-%m-%d")
|
||||||
releases[version] = date
|
releases[version] = date
|
||||||
print("%s: %s" % (version, date))
|
print(f"{version}: {date}")
|
||||||
|
|
||||||
start += 100
|
start += 100
|
||||||
if data["response"]["numFound"] <= start:
|
if data["response"]["numFound"] <= start:
|
||||||
@@ -58,6 +58,6 @@ def update_product(product_name, configs):
|
|||||||
|
|
||||||
p_filter = sys.argv[1] if len(sys.argv) > 1 else None
|
p_filter = sys.argv[1] if len(sys.argv) > 1 else None
|
||||||
for product, configs in endoflife.list_products(METHOD, p_filter).items():
|
for product, configs in endoflife.list_products(METHOD, p_filter).items():
|
||||||
print("::group::%s" % product)
|
print(f"::group::{product}")
|
||||||
update_product(product, configs)
|
update_product(product, configs)
|
||||||
print("::endgroup::")
|
print("::endgroup::")
|
||||||
|
|||||||
@@ -43,10 +43,8 @@ def update_product(product_name, configs):
|
|||||||
endoflife.write_releases(product_name, releases)
|
endoflife.write_releases(product_name, releases)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
p_filter = sys.argv[1] if len(sys.argv) > 1 else None
|
p_filter = sys.argv[1] if len(sys.argv) > 1 else None
|
||||||
for product, configs in endoflife.list_products(METHOD, p_filter).items():
|
for product, configs in endoflife.list_products(METHOD, p_filter).items():
|
||||||
print("::group::%s" % product)
|
print(f"::group::{product}")
|
||||||
update_product(product, configs)
|
update_product(product, configs)
|
||||||
print("::endgroup::")
|
print("::endgroup::")
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ from bs4 import BeautifulSoup
|
|||||||
from common import endoflife
|
from common import endoflife
|
||||||
|
|
||||||
URL = "https://www.paloaltonetworks.com/services/support/end-of-life-announcements/end-of-life-summary"
|
URL = "https://www.paloaltonetworks.com/services/support/end-of-life-announcements/end-of-life-summary"
|
||||||
|
|
||||||
ID_MAPPING = {
|
ID_MAPPING = {
|
||||||
"pan-os-panorama": "pan-os",
|
"pan-os-panorama": "pan-os",
|
||||||
"globalprotect": "pan-gp",
|
"globalprotect": "pan-gp",
|
||||||
@@ -36,7 +35,7 @@ def update_releases(html_identifier, file):
|
|||||||
try:
|
try:
|
||||||
month, date, year = td_list[1].get_text().split("/")
|
month, date, year = td_list[1].get_text().split("/")
|
||||||
abs_date = f"{year}-{month:0>2}-{date:0>2}"
|
abs_date = f"{year}-{month:0>2}-{date:0>2}"
|
||||||
except Exception:
|
except ValueError:
|
||||||
# A few dates have 1st, 2nd, 4th etc. Fix that:
|
# A few dates have 1st, 2nd, 4th etc. Fix that:
|
||||||
d = td_list[1].get_text()
|
d = td_list[1].get_text()
|
||||||
d = re.sub(r'(\w+) (\d{1,2})(?:\w{2}), (\d{4})', r'\1 \2, \3', d)
|
d = re.sub(r'(\w+) (\d{1,2})(?:\w{2}), (\d{4})', r'\1 \2, \3', d)
|
||||||
@@ -44,7 +43,7 @@ def update_releases(html_identifier, file):
|
|||||||
abs_date = date.strftime("%Y-%m-%d")
|
abs_date = date.strftime("%Y-%m-%d")
|
||||||
|
|
||||||
versions[version] = abs_date
|
versions[version] = abs_date
|
||||||
print("%s: %s" % (version, abs_date))
|
print(f"{version}: {abs_date}")
|
||||||
|
|
||||||
endoflife.write_releases(file, versions)
|
endoflife.write_releases(file, versions)
|
||||||
print("::endgroup::")
|
print("::endgroup::")
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import datetime
|
|
||||||
import json
|
import json
|
||||||
from common import endoflife
|
from common import endoflife
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
PHP_MAJOR_VERSIONS = [4, 5, 7, 8]
|
PHP_MAJOR_VERSIONS = [4, 5, 7, 8]
|
||||||
|
|
||||||
@@ -10,9 +10,9 @@ PHP_MAJOR_VERSIONS = [4, 5, 7, 8]
|
|||||||
# we return it as YYYY-MM-DD
|
# we return it as YYYY-MM-DD
|
||||||
def parse_date(date_str):
|
def parse_date(date_str):
|
||||||
try:
|
try:
|
||||||
return datetime.datetime.strptime(date_str, "%d %b %Y").strftime("%Y-%m-%d")
|
return datetime.strptime(date_str, "%d %b %Y").strftime("%Y-%m-%d")
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return datetime.datetime.strptime(date_str, "%d %B %Y").strftime("%Y-%m-%d")
|
return datetime.strptime(date_str, "%d %B %Y").strftime("%Y-%m-%d")
|
||||||
|
|
||||||
|
|
||||||
def fetch_versions(major_version):
|
def fetch_versions(major_version):
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ def fetch_releases(pypi_id, regex):
|
|||||||
if not isinstance(regex, list):
|
if not isinstance(regex, list):
|
||||||
regex = [regex]
|
regex = [regex]
|
||||||
|
|
||||||
url = "https://pypi.org/pypi/%s/json" % pypi_id
|
url = f"https://pypi.org/pypi/{pypi_id}/json"
|
||||||
response = endoflife.fetch_url(url)
|
response = endoflife.fetch_url(url)
|
||||||
data = json.loads(response)
|
data = json.loads(response)
|
||||||
for version in data["releases"]:
|
for version in data["releases"]:
|
||||||
@@ -29,7 +29,7 @@ def fetch_releases(pypi_id, regex):
|
|||||||
if matches and R:
|
if matches and R:
|
||||||
d = datetime.fromisoformat(R[0]["upload_time"]).strftime("%Y-%m-%d")
|
d = datetime.fromisoformat(R[0]["upload_time"]).strftime("%Y-%m-%d")
|
||||||
releases[version] = d
|
releases[version] = d
|
||||||
print("%s: %s" % (version, d))
|
print(f"{version}: {d}")
|
||||||
|
|
||||||
return releases
|
return releases
|
||||||
|
|
||||||
@@ -46,6 +46,6 @@ def update_product(product_name, configs):
|
|||||||
|
|
||||||
p_filter = sys.argv[1] if len(sys.argv) > 1 else None
|
p_filter = sys.argv[1] if len(sys.argv) > 1 else None
|
||||||
for product, configs in endoflife.list_products(METHOD, p_filter).items():
|
for product, configs in endoflife.list_products(METHOD, p_filter).items():
|
||||||
print("::group::%s" % product)
|
print(f"::group::{product}")
|
||||||
update_product(product, configs)
|
update_product(product, configs)
|
||||||
print("::endgroup::")
|
print("::endgroup::")
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ for db, url in dbs.items():
|
|||||||
# Must match both the 'Supported XXX minor versions' and
|
# Must match both the 'Supported XXX minor versions' and
|
||||||
# 'Supported XXX major versions' to have correct release dates
|
# 'Supported XXX major versions' to have correct release dates
|
||||||
if len(columns) > 3:
|
if len(columns) > 3:
|
||||||
r = r"(?P<v>\d+(?:\.\d+)*)" # https://regex101.com/r/BY1vwV/1
|
r = r"(?P<v>\d+(?:\.\d+)*)" # https://regex101.com/r/BY1vwV/1
|
||||||
m = re.search(r, columns[0].text.strip(), flags=re.IGNORECASE)
|
m = re.search(r, columns[0].text.strip(), flags=re.IGNORECASE)
|
||||||
if m:
|
if m:
|
||||||
version = m.group("v")
|
version = m.group("v")
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ for tr in soup.findAll("tr"):
|
|||||||
version += ".%s" % m["minor2"]
|
version += ".%s" % m["minor2"]
|
||||||
date = td_list[1].get_text()
|
date = td_list[1].get_text()
|
||||||
versions[version] = date
|
versions[version] = date
|
||||||
print("%s: %s" % (version, date))
|
print(f"{version}: {date}")
|
||||||
|
|
||||||
endoflife.write_releases('redhat', versions)
|
endoflife.write_releases('redhat', versions)
|
||||||
print("::endgroup::")
|
print("::endgroup::")
|
||||||
|
|||||||
@@ -25,12 +25,12 @@ for tr in soup.findAll("tr"):
|
|||||||
td_list[1].get_text().strip(), "%B %d, %Y"
|
td_list[1].get_text().strip(), "%B %d, %Y"
|
||||||
)
|
)
|
||||||
# The date is a suffix (May 23rd, 2020)
|
# The date is a suffix (May 23rd, 2020)
|
||||||
except Exception as e:
|
except ValueError as e:
|
||||||
x = td_list[1].get_text().split(",")
|
x = td_list[1].get_text().split(",")
|
||||||
date = datetime.datetime.strptime(x[0][:-2] + x[1], "%B %d %Y")
|
date = datetime.datetime.strptime(x[0][:-2] + x[1], "%B %d %Y")
|
||||||
abs_date = date.strftime("%Y-%m-%d")
|
abs_date = date.strftime("%Y-%m-%d")
|
||||||
versions[version] = abs_date
|
versions[version] = abs_date
|
||||||
print("%s: %s" % (version, abs_date))
|
print(f"{version}: {abs_date}")
|
||||||
|
|
||||||
endoflife.write_releases('ros', versions)
|
endoflife.write_releases('ros', versions)
|
||||||
print("::endgroup::")
|
print("::endgroup::")
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import json
|
|
||||||
import mwparserfromhell
|
import mwparserfromhell
|
||||||
import re
|
import re
|
||||||
from common import endoflife
|
from common import endoflife
|
||||||
@@ -19,7 +18,7 @@ for tr in wikicode.ifilter_tags(matches=lambda node: node.tag == "tr"):
|
|||||||
maybe_date = items[1].__strip__()
|
maybe_date = items[1].__strip__()
|
||||||
if re.match(r"\d{4}-\d{2}-\d{2}", maybe_date):
|
if re.match(r"\d{4}-\d{2}-\d{2}", maybe_date):
|
||||||
versions[maybe_version] = maybe_date
|
versions[maybe_version] = maybe_date
|
||||||
print("%s: %s" % (maybe_version, maybe_date))
|
print(f"{maybe_version}: {maybe_date}")
|
||||||
|
|
||||||
endoflife.write_releases('unrealircd', versions)
|
endoflife.write_releases('unrealircd', versions)
|
||||||
print("::endgroup::")
|
print("::endgroup::")
|
||||||
|
|||||||
Reference in New Issue
Block a user