Skip to content

Commit 4facef6

Browse files
authored
Add files via upload
1 parent 46c30f5 commit 4facef6

File tree

1 file changed

+131
-0
lines changed

1 file changed

+131
-0
lines changed

pythoninstall.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import sys
2+
import os
3+
import platform
4+
import subprocess
5+
import urllib.request
6+
from urllib.error import URLError, HTTPError
7+
import re
8+
9+
# Base HTTP URL for downloads and version listing
10+
BASE_HTTP = 'https://www.python.org/ftp/python'
11+
LISTING_URL = BASE_HTTP + '/'
12+
13+
14+
def fetch_all_versions():
15+
"""Fetch all available Python versions by scraping the FTP directory listing."""
16+
try:
17+
with urllib.request.urlopen(LISTING_URL) as resp:
18+
html = resp.read().decode('utf-8', errors='ignore')
19+
except (URLError, HTTPError) as e:
20+
print(f"Error fetching version listing: {e}")
21+
sys.exit(1)
22+
23+
# Find entries like '3.9.18/'
24+
found = re.findall(r'href=["\'](\d+\.\d+\.\d+)/["\']', html)
25+
versions = sorted(set(found), key=lambda v: list(map(int, v.split('.'))))
26+
return versions
27+
28+
29+
def filter_patches(versions, major):
30+
"""Return all patch versions matching the given major (e.g. '3.9')."""
31+
prefix = major + '.'
32+
return [v for v in versions if v.startswith(prefix)]
33+
34+
35+
def download_file(url, dest):
36+
print(f"Downloading {url}...")
37+
try:
38+
urllib.request.urlretrieve(url, dest)
39+
except Exception as e:
40+
print(f"Download failed: {e}")
41+
sys.exit(1)
42+
print(f"Saved to {dest}")
43+
return dest
44+
45+
46+
def install_on_windows(installer_path):
47+
print("Running Windows installer (quiet, all users)...")
48+
try:
49+
subprocess.run([installer_path, '/quiet', 'InstallAllUsers=1', 'PrependPath=1'], check=True)
50+
print("Installation complete.")
51+
except subprocess.CalledProcessError as e:
52+
print(f"Windows installation failed: {e}")
53+
sys.exit(1)
54+
55+
56+
def install_on_linux(source_tar):
57+
print("Installing from source (Linux)...")
58+
work_dir = "/tmp/python_install"
59+
os.makedirs(work_dir, exist_ok=True)
60+
try:
61+
subprocess.run(["tar", "-xf", source_tar, "-C", work_dir], check=True)
62+
src_dir = os.path.join(work_dir, os.listdir(work_dir)[0])
63+
os.chdir(src_dir)
64+
subprocess.run(["./configure", "--enable-optimizations"], check=True)
65+
subprocess.run(["make", "-j$(nproc)"], shell=True, check=True)
66+
subprocess.run(["sudo", "make", "altinstall"], check=True)
67+
print("Linux installation complete.")
68+
except subprocess.CalledProcessError as e:
69+
print(f"Linux installation failed: {e}")
70+
sys.exit(1)
71+
72+
73+
def main():
74+
majors = ['3.13', '3.12', '3.11', '3.10', '3.9', '3.8', '3.7', '3.6', '3.5']
75+
print("Fetching available versions, please wait...")
76+
all_versions = fetch_all_versions()
77+
78+
print("Choose a Python major version to install:")
79+
for idx, ver in enumerate(majors, start=1):
80+
print(f"{idx}. Python {ver}")
81+
choice = input('Enter number: ').strip()
82+
if not choice.isdigit() or not (1 <= int(choice) <= len(majors)):
83+
print("Invalid selection.")
84+
sys.exit(1)
85+
major = majors[int(choice) - 1]
86+
print(f"You chose Python {major}.")
87+
88+
patches = filter_patches(all_versions, major)
89+
if not patches:
90+
print(f"No patch versions found for Python {major}.")
91+
sys.exit(1)
92+
93+
print("1. Install latest patch for this major")
94+
print("2. Choose a specific patch version")
95+
sub = input('Enter option [1-2]: ').strip()
96+
if sub not in ('1', '2'):
97+
print("Invalid option.")
98+
sys.exit(1)
99+
100+
if sub == '1':
101+
target_version = patches[-1]
102+
else:
103+
print("Available patches:")
104+
for idx, p in enumerate(patches, start=1):
105+
print(f"{idx}. {p}")
106+
p_choice = input('Select patch #: ').strip()
107+
if not p_choice.isdigit() or not (1 <= int(p_choice) <= len(patches)):
108+
print("Invalid patch selection.")
109+
sys.exit(1)
110+
target_version = patches[int(p_choice) - 1]
111+
112+
print(f"Preparing to install Python {target_version}...")
113+
system = platform.system()
114+
if system == 'Windows':
115+
filename = f"python-{target_version}-amd64.exe"
116+
url = f"{BASE_HTTP}/{target_version}/{filename}"
117+
dest = os.path.join(os.getcwd(), filename)
118+
download_file(url, dest)
119+
install_on_windows(dest)
120+
elif system == 'Linux':
121+
filename = f"Python-{target_version}.tgz"
122+
url = f"{BASE_HTTP}/{target_version}/{filename}"
123+
dest = os.path.join('/tmp', filename)
124+
download_file(url, dest)
125+
install_on_linux(dest)
126+
else:
127+
print(f"Unsupported OS: {system}")
128+
sys.exit(1)
129+
130+
if __name__ == '__main__':
131+
main()

0 commit comments

Comments
 (0)