Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 57 additions & 17 deletions Windows-Integrate/download_packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,29 @@

# Retry settings
MAX_RETRIES = 5
RETRY_DELAY = 10 # seconds
RETRY_DELAY = 3 # seconds

def download_pkg_file(url, save_path):
"""Simple direct download for .pkg.tar.zst files."""
"""Robust streaming download for .pkg.tar.zst files."""
if os.path.exists(save_path):
print(f"File already exists: {save_path}, skipping download.")
return

print(f"Downloading {url}...")

for attempt in range(1, MAX_RETRIES + 1):
try:
response = requests.get(url, headers=HEADERS, stream=True)
response.raise_for_status()
with open(save_path, "wb") as file:
file.write(response.content)
with requests.get(url, headers=HEADERS, stream=True, timeout=30) as response:
response.raise_for_status()

with open(save_path, "wb") as file:
for chunk in response.iter_content(chunk_size=1024 * 1024):
if chunk:
file.write(chunk)

print(f"Downloaded successfully: {save_path}")
return

except requests.exceptions.RequestException as e:
print(f"Attempt {attempt}/{MAX_RETRIES} failed: {e}")
if attempt < MAX_RETRIES:
Expand All @@ -51,35 +57,69 @@ def download_pkg_file(url, save_path):
print(f"Download failed: {url}")

def download_exe_file(url, save_path):
"""Resumable download for large .exe files (KiCad installers) with retry support."""
temp_path = save_path + ".part" # Temporary file for incomplete downloads
resume_header = {}
"""Download .exe files with safe resume handling."""

temp_path = save_path + ".part"

# If final file already exists → skip
if os.path.exists(save_path):
print(f"{save_path} already downloaded.")
return

# If partial file exists → check size
resume_header = {}
if os.path.exists(temp_path):
downloaded_size = os.path.getsize(temp_path)
resume_header["Range"] = f"bytes={downloaded_size}-"
print(f"Resuming download for {save_path} from byte {downloaded_size}...")

try:
# Get total file size from server
response = requests.head(url, headers=HEADERS)
total_size = int(response.headers.get('content-length', 0))

# If already fully downloaded → rename
if downloaded_size >= total_size:
os.rename(temp_path, save_path)
print(f"Recovered completed file: {save_path}")
return

resume_header["Range"] = f"bytes={downloaded_size}-"
print(f"Resuming from {downloaded_size} bytes...")

except:
print("Resume check failed. Restarting download.")
os.remove(temp_path)

else:
print(f"Starting download for {save_path}...")
print(f"Starting fresh download: {save_path}")

# Download logic
for attempt in range(1, MAX_RETRIES + 1):
try:
with requests.get(url, headers={**HEADERS, **resume_header}, stream=True) as response:
with requests.get(url, headers={**HEADERS, **resume_header}, stream=True, timeout=30) as response:

# If server rejects range → restart download
if response.status_code == 416:
print("Server rejected resume. Restarting download...")
if os.path.exists(temp_path):
os.remove(temp_path)
return download_exe_file(url, save_path)

response.raise_for_status()

with open(temp_path, "ab") as file:
for chunk in response.iter_content(chunk_size=1024 * 1024): # Download in 1MB chunks
mode = "ab" if "Range" in resume_header else "wb"

with open(temp_path, mode) as file:
for chunk in response.iter_content(chunk_size=1024 * 1024):
if chunk:
file.write(chunk)

os.rename(temp_path, save_path) # Rename to final file
os.rename(temp_path, save_path)
print(f"Downloaded successfully: {save_path}")
return

except requests.exceptions.RequestException as e:
print(f"Attempt {attempt}/{MAX_RETRIES} failed: {e}")
if attempt < MAX_RETRIES:
print(f"Retrying in {RETRY_DELAY} seconds...")
time.sleep(RETRY_DELAY)
else:
print(f"Download failed: {url}")
Expand Down
25 changes: 17 additions & 8 deletions Windows-Integrate/ghdl_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
DOWNLOAD_DIR = os.path.join(INSTALL_DIR, "Tool-Manager", "Download")
MSYS_DIR = os.path.join(INSTALL_DIR, "MSYS", "mingw64")
GHDL_DIR = os.path.join(INSTALL_DIR, "GHDL")
BASE_DIR = r"C:\FOSSEE\Tool-Manager"
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
INFO_JSON = os.path.join(BASE_DIR, "information.json")

# Available GHDL versions (first entry is the latest)
Expand All @@ -23,13 +23,21 @@
GHDL_PACKAGES = {v: f"ghdl-v{v}.pkg.tar.zst" for v in GHDL_VERSIONS}

def get_installed_version():
"""Get the installed GHDL version using 'ghdl --version'."""
ghdl_path = os.path.join(MSYS_DIR, "bin", "ghdl.exe")

print("Checking GHDL path:", ghdl_path)

if not os.path.exists(ghdl_path):
print("GHDL NOT FOUND")
return "Unknown"

try:
result = subprocess.run(["ghdl", "--version"], capture_output=True, text=True, check=True)
version_line = result.stdout.splitlines()[0] # Get the first line of output
version = version_line.split()[1] # Extract version number (e.g., "4.1.0")
return version
except (subprocess.CalledProcessError, FileNotFoundError, IndexError):
result = subprocess.run([ghdl_path, "--version"], capture_output=True, text=True)
print("OUTPUT:", result.stdout)
version_line = result.stdout.splitlines()[0]
return version_line.split()[1]
except Exception as e:
print("ERROR:", e)
return "Unknown"

def update_information_json(version):
Expand Down Expand Up @@ -121,6 +129,8 @@ def extract_zst(self, archive_path, extract_path):
tar.extractall(path=extract_path)

def install_ghdl(self):
shutil.rmtree(GHDL_DIR, ignore_errors=True)

"""Installs the selected GHDL version."""
version = self.version_dropdown.currentText()
package_name = GHDL_PACKAGES[version]
Expand Down Expand Up @@ -158,7 +168,6 @@ def install_ghdl(self):
shutil.copytree(os.path.join(extract_dir, "mingw64", "lib"), os.path.join(GHDL_DIR, "lib"), dirs_exist_ok=True)

# Remove old GHDL directory
shutil.rmtree(GHDL_DIR, ignore_errors=True)

# Cleanup
shutil.rmtree(extract_dir, ignore_errors=True)
Expand Down
2 changes: 1 addition & 1 deletion Windows-Integrate/kicad_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
INSTALL_DIR = r"C:\FOSSEE"
DOWNLOAD_DIR = os.path.join(INSTALL_DIR, "Tool-Manager", "Download")
KICAD_DIR = os.path.join(INSTALL_DIR, "KiCad")
BASE_DIR = r"C:\FOSSEE\Tool-Manager"
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
INFO_JSON = os.path.join(BASE_DIR, "information.json")

# Available KiCad versions for the user to choose (displayed as 7.0.11 and 8.0.9)
Expand Down
Loading