Skip to content
Draft
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
26 changes: 2 additions & 24 deletions src/sas/qtgui/Utilities/NewVersion/NewVersionAvailable.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
import webbrowser
from copy import copy

import requests
from packaging.version import Version, parse
from packaging.version import parse
from PySide6.QtCore import QSize
from PySide6.QtGui import QIcon
from PySide6.QtWidgets import (
Expand All @@ -19,8 +18,8 @@
)

from sas import config
from sas.system import web
from sas.system.version import __version__ as current_version_string
from sas.system.web import get_current_release_version

logger = logging.getLogger("NewVersionAvailable")

Expand Down Expand Up @@ -83,27 +82,6 @@ def cancel(self):
self.close()


def get_current_release_version() -> tuple[str, str, Version] | None:
""" Get the current version from the server """
try:
response = requests.get(web.update_url, timeout=config.UPDATE_TIMEOUT)
# Will throw Exception if the HTTP status code returned isn't success
# (2xx)
response.raise_for_status()
version_info = response.json()
logger.info("Connected to www.sasview.org. Received: %s", version_info)

version_string = version_info["version"]
url = version_info["download_url"]

return version_string, url, parse(version_string)

except Exception as ex:
logger.info("Failed to get version number %s", ex)
return None



def maybe_prompt_new_version_download() -> QDialog | None:
""" If a new version is available, and Show a dialog prompting the user to download """

Expand Down
13 changes: 11 additions & 2 deletions src/sas/system/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import webbrowser
from pathlib import Path

from sas.system.web import get_current_release_version

logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -75,8 +77,15 @@ def _online_url(self, relative_path: Path, fragment: str = "") -> str:
"""Construct the online documentation URL for the current version."""
from sas.system.version import __version__

version = _release_version(__version__)
base = f"https://www.sasview.org/docs/v{version}"
release_version = get_current_release_version()
active_version = _release_version(__version__)

# The base URL is different for the latest version of docs.
if release_version == active_version:
base = "https://www.sasview.org/docs/"
else:
base = f"https://www.sasview.org/docs/old_docs/{active_version}"

url = f"{base}/{relative_path.as_posix()}"
if fragment:
url += "#" + fragment
Expand Down
30 changes: 30 additions & 0 deletions src/sas/system/web.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
import logging

import requests
from packaging.version import Version, parse

from sas.system import config

logger = logging.getLogger("Web Configuration")

class WebLinks:
def __init__(self):
self.nist_url = "https://www.nist.gov/ncnr"
Expand All @@ -22,5 +31,26 @@ def __init__(self):

self.help_email = "help@sasview.org"


def get_current_release_version() -> tuple[str, str, Version] | None:
""" Get the current version from the server """
try:
response = requests.get(web.update_url, timeout=config.UPDATE_TIMEOUT)
# Will throw Exception if the HTTP status code returned isn't success
# (2xx)
response.raise_for_status()
version_info = response.json()
logger.info("Connected to www.sasview.org. Received: %s", version_info)

version_string = version_info["version"]
url = version_info["download_url"]

return version_string, url, parse(version_string)

except Exception as ex:
logger.info("Failed to get version number %s", ex)
return None


web = WebLinks()

32 changes: 17 additions & 15 deletions test/system/utest_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

from sas.system._help import _HelpSystem, _release_version

TEST_VERSION = '4.2.2'


class PosixTestPath(PurePosixPath):
"""Pure POSIX path with the minimal filesystem API used by _HelpSystem."""
Expand Down Expand Up @@ -38,34 +40,34 @@ def setup_method(self):

@patch("sas.system._help.HELP_SYSTEM")
def test_online_url_basic(self, _mock):
with patch("sas.system.version.__version__", "6.1.2"):
with patch("sas.system.version.__version__", TEST_VERSION):
url = self.hs._online_url(
Path("user/qtgui/Perspectives/Fitting/fitting_help.html")
)
assert url == (
"https://www.sasview.org/docs/v6.1.2"
f"https://www.sasview.org/docs/old_docs/{TEST_VERSION}"
"/user/qtgui/Perspectives/Fitting/fitting_help.html"
)

def test_online_url_dev_version(self):
with patch("sas.system.version.__version__", "6.1.2.dev159+g77be83657"):
with patch("sas.system.version.__version__", f"{TEST_VERSION}.dev159+g77be83657"):
url = self.hs._online_url(
Path("user/qtgui/Perspectives/Fitting/fitting_help.html")
)
assert url.startswith("https://www.sasview.org/docs/v6.1.2/")
assert url.startswith(f"https://www.sasview.org/docs/old_docs/{TEST_VERSION}/")
assert "+g77be83657" not in url
assert ".dev159" not in url

def test_online_url_with_fragment(self):
with patch("sas.system.version.__version__", "6.1.2"):
with patch("sas.system.version.__version__", TEST_VERSION):
url = self.hs._online_url(
Path("user/qtgui/Perspectives/Fitting/fitting_help.html"),
"simultaneous-fits",
)
assert url.endswith("fitting_help.html#simultaneous-fits")

def test_online_url_uses_posix_separators(self):
with patch("sas.system.version.__version__", "6.1.2"):
with patch("sas.system.version.__version__", TEST_VERSION):
url = self.hs._online_url(
Path("user") / "qtgui" / "Perspectives" / "Fitting" / "fitting_help.html"
)
Expand Down Expand Up @@ -110,19 +112,19 @@ def test_local_docs_with_fragment(self, mock_wb, tmp_path):
def test_online_fallback_when_local_missing(self, mock_wb, tmp_path):
"""When local docs don't exist, fall back to online URL."""
self.hs.path = tmp_path # empty dir — no docs
with patch("sas.system.version.__version__", "6.1.2"):
with patch("sas.system.version.__version__", TEST_VERSION):
self.hs.show_help("user/fitting.html")

opened_url = mock_wb.open.call_args[0][0]
assert opened_url == (
"https://www.sasview.org/docs/v6.1.2/user/fitting.html"
f"https://www.sasview.org/docs/old_docs/{TEST_VERSION}/user/fitting.html"
)

@patch("sas.system._help.webbrowser")
def test_online_fallback_no_absolute_path_leak(self, mock_wb, tmp_path):
"""The online URL must never contain the local filesystem path."""
self.hs.path = tmp_path
with patch("sas.system.version.__version__", "6.1.2"):
with patch("sas.system.version.__version__", TEST_VERSION):
self.hs.show_help("user/fitting.html")

opened_url = mock_wb.open.call_args[0][0]
Expand All @@ -134,24 +136,24 @@ def test_online_fallback_no_absolute_path_leak(self, mock_wb, tmp_path):
def test_online_fallback_when_path_is_none(self, mock_wb):
"""When HELP_SYSTEM.path is None, fall back to online."""
self.hs.path = None
with patch("sas.system.version.__version__", "6.1.2"):
with patch("sas.system.version.__version__", TEST_VERSION):
self.hs.show_help("user/fitting.html")

opened_url = mock_wb.open.call_args[0][0]
assert opened_url.startswith("https://www.sasview.org/docs/v6.1.2/")
assert opened_url.startswith(f"https://www.sasview.org/docs/old_docs/{TEST_VERSION}/")

@patch("sas.system._help.webbrowser")
def test_absolute_path_stripped_for_online(self, mock_wb, tmp_path):
"""If an absolute path under HELP_SYSTEM.path is passed, the local
root should be stripped when building the online fallback URL."""
self.hs.path = tmp_path # empty — no local docs
absolute_url = tmp_path / "user" / "fitting.html"
with patch("sas.system.version.__version__", "6.1.2"):
with patch("sas.system.version.__version__", TEST_VERSION):
self.hs.show_help(str(absolute_url))

opened_url = mock_wb.open.call_args[0][0]
assert opened_url == (
"https://www.sasview.org/docs/v6.1.2/user/fitting.html"
f"https://www.sasview.org/docs/old_docs/{TEST_VERSION}/user/fitting.html"
)

@patch("sas.system._help.webbrowser")
Expand All @@ -161,12 +163,12 @@ def test_posix_absolute_path_stripped_for_online(self, mock_wb):
absolute_url = "/tmp/sasview-docs/user/fitting.html"

with patch("sas.system._help.Path", PosixTestPath):
with patch("sas.system.version.__version__", "6.1.2"):
with patch("sas.system.version.__version__", TEST_VERSION):
self.hs.show_help(absolute_url)

opened_url = mock_wb.open.call_args[0][0]
assert opened_url == (
"https://www.sasview.org/docs/v6.1.2/user/fitting.html"
f"https://www.sasview.org/docs/old_docs/{TEST_VERSION}/user/fitting.html"
)

@patch("sas.system._help.webbrowser")
Expand Down
Loading