Bump version to 0.6.5 and enhance update download functionality
Some checks are pending
Tests & Quality Checks / Test on Python 3.11 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.10 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-2 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-2 (push) Waiting to run
Tests & Quality Checks / Build Artifacts (push) Blocked by required conditions
Tests & Quality Checks / Build Artifacts-1 (push) Blocked by required conditions
Some checks are pending
Tests & Quality Checks / Test on Python 3.11 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.10 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-2 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-2 (push) Waiting to run
Tests & Quality Checks / Build Artifacts (push) Blocked by required conditions
Tests & Quality Checks / Build Artifacts-1 (push) Blocked by required conditions
- Updated version number in __init__.py to 0.6.5. - Modified the download_update method in updater.py to accept a progress_callback for tracking download progress. - Implemented chunked downloading in _download_file to report progress via the callback. - Adjusted installer launching logic in updater.py to handle MSI files correctly using msiexec. - Connected download progress signal in main_window.py to update the downloading dialog.
This commit is contained in:
parent
fba25534d9
commit
9609a12ae7
9 changed files with 2930 additions and 2884 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
# Application
|
# Application
|
||||||
APP_NAME=WebDrop Bridge
|
APP_NAME=WebDrop Bridge
|
||||||
APP_VERSION=0.6.4
|
APP_VERSION=0.6.5
|
||||||
|
|
||||||
# Web App
|
# Web App
|
||||||
WEBAPP_URL=file:///./webapp/index.html
|
WEBAPP_URL=file:///./webapp/index.html
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,11 @@
|
||||||
|
## [0.6.5] - 2026-02-25
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
## [0.6.4] - 2026-02-25
|
## [0.6.4] - 2026-02-25
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -2,7 +2,7 @@
|
||||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
|
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
|
||||||
xmlns:ui="http://schemas.microsoft.com/wix/2010/ui"
|
xmlns:ui="http://schemas.microsoft.com/wix/2010/ui"
|
||||||
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
|
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
|
||||||
<Product Id="*" Name="WebDrop Bridge" Language="1033" Version="0.6.3"
|
<Product Id="*" Name="WebDrop Bridge" Language="1033" Version="0.6.5"
|
||||||
Manufacturer="HIM-Tools"
|
Manufacturer="HIM-Tools"
|
||||||
UpgradeCode="12345678-1234-1234-1234-123456789012">
|
UpgradeCode="12345678-1234-1234-1234-123456789012">
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
||||||
"""WebDrop Bridge - Qt-based desktop application for intelligent drag-and-drop file handling."""
|
"""WebDrop Bridge - Qt-based desktop application for intelligent drag-and-drop file handling."""
|
||||||
|
|
||||||
__version__ = "0.6.4"
|
__version__ = "0.6.5"
|
||||||
__author__ = "WebDrop Team"
|
__author__ = "WebDrop Team"
|
||||||
__license__ = "MIT"
|
__license__ = "MIT"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -238,7 +238,7 @@ class UpdateManager:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def download_update(
|
async def download_update(
|
||||||
self, release: Release, output_dir: Optional[Path] = None
|
self, release: Release, output_dir: Optional[Path] = None, progress_callback=None
|
||||||
) -> Optional[Path]:
|
) -> Optional[Path]:
|
||||||
"""Download installer from release assets.
|
"""Download installer from release assets.
|
||||||
|
|
||||||
|
|
@ -279,6 +279,7 @@ class UpdateManager:
|
||||||
self._download_file,
|
self._download_file,
|
||||||
installer_asset["browser_download_url"],
|
installer_asset["browser_download_url"],
|
||||||
output_file,
|
output_file,
|
||||||
|
progress_callback,
|
||||||
),
|
),
|
||||||
timeout=300,
|
timeout=300,
|
||||||
)
|
)
|
||||||
|
|
@ -299,12 +300,13 @@ class UpdateManager:
|
||||||
output_file.unlink()
|
output_file.unlink()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _download_file(self, url: str, output_path: Path) -> bool:
|
def _download_file(self, url: str, output_path: Path, progress_callback=None) -> bool:
|
||||||
"""Download file from URL (blocking).
|
"""Download file from URL (blocking).
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
url: URL to download from
|
url: URL to download from
|
||||||
output_path: Path to save file
|
output_path: Path to save file
|
||||||
|
progress_callback: Optional callable(bytes_downloaded, total_bytes)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if successful, False otherwise
|
True if successful, False otherwise
|
||||||
|
|
@ -312,8 +314,21 @@ class UpdateManager:
|
||||||
try:
|
try:
|
||||||
logger.debug(f"Downloading from {url}")
|
logger.debug(f"Downloading from {url}")
|
||||||
with urlopen(url, timeout=300) as response: # 5 min timeout
|
with urlopen(url, timeout=300) as response: # 5 min timeout
|
||||||
|
total = int(response.headers.get("Content-Length", 0))
|
||||||
|
downloaded = 0
|
||||||
|
chunk_size = 65536 # 64 KB chunks
|
||||||
with open(output_path, "wb") as f:
|
with open(output_path, "wb") as f:
|
||||||
f.write(response.read())
|
while True:
|
||||||
|
chunk = response.read(chunk_size)
|
||||||
|
if not chunk:
|
||||||
|
break
|
||||||
|
f.write(chunk)
|
||||||
|
downloaded += len(chunk)
|
||||||
|
if progress_callback:
|
||||||
|
try:
|
||||||
|
progress_callback(downloaded, total)
|
||||||
|
except Exception:
|
||||||
|
pass # Never let progress errors abort the download
|
||||||
logger.debug(f"Downloaded {output_path.stat().st_size} bytes")
|
logger.debug(f"Downloaded {output_path.stat().st_size} bytes")
|
||||||
return True
|
return True
|
||||||
except URLError as e:
|
except URLError as e:
|
||||||
|
|
@ -421,8 +436,11 @@ class UpdateManager:
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
# Windows: Run MSI installer
|
# Windows: MSI files must be launched via msiexec
|
||||||
logger.info(f"Launching installer: {installer_path}")
|
logger.info(f"Launching installer: {installer_path}")
|
||||||
|
if str(installer_path).lower().endswith(".msi"):
|
||||||
|
subprocess.Popen(["msiexec.exe", "/i", str(installer_path)])
|
||||||
|
else:
|
||||||
subprocess.Popen([str(installer_path)])
|
subprocess.Popen([str(installer_path)])
|
||||||
return True
|
return True
|
||||||
elif platform.system() == "Darwin":
|
elif platform.system() == "Darwin":
|
||||||
|
|
|
||||||
|
|
@ -1519,6 +1519,7 @@ class MainWindow(QMainWindow):
|
||||||
# Connect signals
|
# Connect signals
|
||||||
worker.download_complete.connect(self._on_download_complete)
|
worker.download_complete.connect(self._on_download_complete)
|
||||||
worker.download_failed.connect(self._on_download_failed)
|
worker.download_failed.connect(self._on_download_failed)
|
||||||
|
worker.download_progress.connect(self._on_download_progress)
|
||||||
worker.update_status.connect(self._on_update_status)
|
worker.update_status.connect(self._on_update_status)
|
||||||
worker.finished.connect(thread.quit)
|
worker.finished.connect(thread.quit)
|
||||||
worker.finished.connect(worker.deleteLater)
|
worker.finished.connect(worker.deleteLater)
|
||||||
|
|
@ -1620,6 +1621,16 @@ class MainWindow(QMainWindow):
|
||||||
f"Could not download the update:\n\n{error}\n\nPlease try again later.",
|
f"Could not download the update:\n\n{error}\n\nPlease try again later.",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _on_download_progress(self, downloaded: int, total: int) -> None:
|
||||||
|
"""Forward download progress to the downloading dialog.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
downloaded: Bytes downloaded so far
|
||||||
|
total: Total bytes (0 if unknown)
|
||||||
|
"""
|
||||||
|
if hasattr(self, "downloading_dialog") and self.downloading_dialog:
|
||||||
|
self.downloading_dialog.set_progress(downloaded, total)
|
||||||
|
|
||||||
def _do_install(self, installer_path: Path) -> None:
|
def _do_install(self, installer_path: Path) -> None:
|
||||||
"""Execute the installer.
|
"""Execute the installer.
|
||||||
|
|
||||||
|
|
@ -1718,6 +1729,7 @@ class UpdateDownloadWorker(QObject):
|
||||||
# Define signals at class level
|
# Define signals at class level
|
||||||
download_complete = Signal(Path) # Emits installer_path
|
download_complete = Signal(Path) # Emits installer_path
|
||||||
download_failed = Signal(str) # Emits error message
|
download_failed = Signal(str) # Emits error message
|
||||||
|
download_progress = Signal(int, int) # Emits (bytes_downloaded, total_bytes)
|
||||||
update_status = Signal(str, str) # Emits (status_text, emoji)
|
update_status = Signal(str, str) # Emits (status_text, emoji)
|
||||||
finished = Signal()
|
finished = Signal()
|
||||||
|
|
||||||
|
|
@ -1749,7 +1761,15 @@ class UpdateDownloadWorker(QObject):
|
||||||
# Download with 5 minute timeout (300 seconds)
|
# Download with 5 minute timeout (300 seconds)
|
||||||
logger.info("Starting download with 5-minute timeout")
|
logger.info("Starting download with 5-minute timeout")
|
||||||
installer_path = loop.run_until_complete(
|
installer_path = loop.run_until_complete(
|
||||||
asyncio.wait_for(self.manager.download_update(self.release), timeout=300)
|
asyncio.wait_for(
|
||||||
|
self.manager.download_update(
|
||||||
|
self.release,
|
||||||
|
progress_callback=lambda cur, tot: self.download_progress.emit(
|
||||||
|
cur, tot
|
||||||
|
),
|
||||||
|
),
|
||||||
|
timeout=300,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if not installer_path:
|
if not installer_path:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue