Skip to content

Instantly share code, notes, and snippets.

@Jackenmen
Last active July 13, 2022 21:54
Show Gist options
  • Save Jackenmen/8d90f81737e8c7eb834e6a392f028abc to your computer and use it in GitHub Desktop.
Save Jackenmen/8d90f81737e8c7eb834e6a392f028abc to your computer and use it in GitHub Desktop.
Little script for fetching metadata from ALL Ubuntu repositories and search for available Python versions.
import gzip
import os
import sys
from io import BytesIO
from pathlib import Path
import requests
from debian import deb822
cwd = Path("processed")
cwd.mkdir(exist_ok=True)
os.chdir(cwd)
ARCHES = (
"amd64",
# "i386",
)
CHANNELS = (
"main",
"universe",
# "restricted",
# "multiverse",
)
POCKETS = (
"release",
"security",
"updates",
# "backports",
# "proposed",
)
def get_base_repository_url(dist_name: str, *, revert: bool = False) -> str:
supported_url = "http://archive.ubuntu.com/ubuntu/dists"
data = ubuntu_releases[dist_name]
is_supported = data["Supported"] == "1"
if revert:
is_supported = not is_supported
if is_supported:
return f"{supported_url}/{dist_name}"
return f"http://old-releases.ubuntu.com/ubuntu/dists/{dist_name}"
def get_packages_url(base_url: str, pocket: str, channel: str, arch: str) -> str:
pocket_url = f"{base_url}{f'-{pocket}' if pocket != 'release' else ''}"
return f"{pocket_url}/{channel}/binary-{arch}/Packages.gz"
def fetch_repos():
for dist_name in ubuntu_releases:
revert = False
base_url = get_base_repository_url(dist_name, revert=revert)
for pocket in POCKETS:
pocket_url = f"{base_url}{f'-{pocket}' if pocket != 'release' else ''}"
for channel in CHANNELS:
for arch in ARCHES:
current = f"{dist_name}_{pocket}_{channel}_binary-{arch}"
url = get_packages_url(base_url, pocket, channel, arch)
print(f"Procesing {current}... {url}")
resp = requests.get(url)
if resp.status_code != 200 and not revert:
revert = True
base_url = get_base_repository_url(dist_name, revert=revert)
url = get_packages_url(base_url, pocket, channel, arch)
resp = requests.get(url)
if resp.status_code != 200:
print(" ! Received non-200 response")
continue
with gzip.open(BytesIO(requests.get(url).content)) as gz_fp:
with open(f"{current}.txt", "wb") as txt_fp:
txt_fp.write(gz_fp.read())
def find_pythons():
results = {}
for file in Path.cwd().iterdir():
print(f"Procesing {file.name}...")
dist_name, _ = file.stem.split("_", maxsplit=1)
with file.open(encoding="utf-8", errors="replace") as fp:
for data in deb822.Packages.iter_paragraphs(fp):
found_versions = results.setdefault(dist_name, set())
found_versions.update(x for x in range(12) if data["Package"] == f"python3.{x}")
parts = []
for dist_name, data in ubuntu_releases.items():
found_versions = ", ".join(f"3.{x}" for x in sorted(results.get(dist_name, []))) or "None"
parts.append(f"Ubuntu {data['Version']} ({data['Name']}): {found_versions}")
print("\n".join(parts))
COMMANDS = {
"fetch-repos": fetch_repos,
"find-pythons": find_pythons,
}
try:
command = COMMANDS[sys.argv[1]]
except IndexError:
print("You need to choose a command to run (valid commands: fetch-repos, find-pythons)")
sys.exit(1)
except KeyError:
print(f"{sys.argv[1]!r} is not a valid command! (valid commands: fetch-repos, find-pythons)")
sys.exit(1)
ubuntu_releases = {}
for release_info in requests.get("https://changelogs.ubuntu.com/meta-release").text.strip().split("\n\n"):
data = dict(line.split(": ", maxsplit=1) for line in release_info.split("\n"))
ubuntu_releases[data["Dist"]] = data
command()
python-debian==0.1.43
requests==2.27.1
@Jackenmen
Copy link
Author

Example output:

Ubuntu 04.10 (Warty Warthog): None
Ubuntu 05.04 (Hoary  Hedgehog): None
Ubuntu 05.10 (Breezy Badger): None
Ubuntu 6.06 LTS (Dapper Drake): None
Ubuntu 6.10 (Edgy Eft): None
Ubuntu 7.04 (Feisty Fawn): None
Ubuntu 7.10 (Gutsy Gibbon): None
Ubuntu 8.04 LTS (Hardy Heron): None
Ubuntu 8.10 (Intrepid Ibex): 3.0
Ubuntu 9.04 (Jaunty Jackalope): 3.0
Ubuntu 9.10 (Karmic Koala): 3.0, 3.1
Ubuntu 10.04.4 LTS (Lucid Lynx): 3.1
Ubuntu 10.10 (Maverick Meerkat): 3.1
Ubuntu 11.04 (Natty Narwhal): 3.1, 3.2
Ubuntu 11.10 (Oneiric Ocelot): 3.2
Ubuntu 12.04.5 LTS (Precise Pangolin): 3.2
Ubuntu 12.10 (Quantal Quetzal): 3.2, 3.3
Ubuntu 13.04 (Raring Ringtail): 3.3
Ubuntu 13.10 (Saucy Salamander): 3.3
Ubuntu 14.04.6 LTS (Trusty Tahr): 3.4, 3.5
Ubuntu 14.10 (Utopic Unicorn): 3.4
Ubuntu 15.04 (Vivid Vervet): 3.4
Ubuntu 15.10 (Wily Werewolf): 3.4, 3.5
Ubuntu 16.04.7 LTS (Xenial Xerus): 3.5
Ubuntu 16.10 (Yakkety Yak): 3.5, 3.6
Ubuntu 17.04 (Zesty Zapus): 3.5, 3.6
Ubuntu 17.10 (Artful Aardvark): 3.6, 3.7
Ubuntu 18.04.6 LTS (Bionic Beaver): 3.6, 3.7, 3.8
Ubuntu 18.10 (Cosmic Cuttlefish): 3.6, 3.7
Ubuntu 19.04 (Disco Dingo): 3.7, 3.8
Ubuntu 19.10 (Eoan Ermine): 3.7, 3.8
Ubuntu 20.04.4 LTS (Focal Fossa): 3.8, 3.9
Ubuntu 20.10 (Groovy Gorilla): 3.8, 3.9
Ubuntu 21.04 (Hirsute Hippo): 3.9, 3.10
Ubuntu 21.10 (Impish Indri): 3.9, 3.10
Ubuntu 22.04 LTS (Jammy Jellyfish): 3.9, 3.10

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment