diff --git a/brainglobe_atlasapi/bg_atlas.py b/brainglobe_atlasapi/bg_atlas.py index 5aafdb22..59d97786 100644 --- a/brainglobe_atlasapi/bg_atlas.py +++ b/brainglobe_atlasapi/bg_atlas.py @@ -204,10 +204,14 @@ def check_latest_version( True if it is, and None if we are offline. """ - if self.remote_version is None: # in this case, we are offline + # Cache remote version to avoid multiple requests + remote_version = self.remote_version + # If we are offline, return None + if remote_version is None: return + local = _version_str_from_tuple(self.local_version) - online = _version_str_from_tuple(self.remote_version) + online = _version_str_from_tuple(remote_version) if local != online: if print_warning: diff --git a/brainglobe_atlasapi/utils.py b/brainglobe_atlasapi/utils.py index 2ef6d0dc..496d98fa 100644 --- a/brainglobe_atlasapi/utils.py +++ b/brainglobe_atlasapi/utils.py @@ -291,7 +291,7 @@ def get_download_size(url: str) -> int: def conf_from_url(url) -> configparser.ConfigParser: - """Read conf file from an URL. And cache a copy in the brainglobe dir. + """Read conf file from a URL. And cache a copy in the brainglobe dir. Parameters ---------- url : str @@ -305,14 +305,17 @@ def conf_from_url(url) -> configparser.ConfigParser: text = requests.get(url).text config_obj = configparser.ConfigParser() config_obj.read_string(text) - cache_path = config.get_brainglobe_dir() / "last_versions.conf" + cache_path: Path = config.get_brainglobe_dir() / "last_versions.conf" - if not cache_path.parent.exists(): - cache_path.parent.mkdir(parents=True, exist_ok=True) - - # Cache the available atlases - with open(cache_path, "w") as f_out: - config_obj.write(f_out) + try: + if not cache_path.parent.exists(): + cache_path.parent.mkdir(parents=True, exist_ok=True) + + # Cache the available atlases + with open(cache_path, "w") as f_out: + config_obj.write(f_out) + except OSError as e: + print(f"Could not update the latest atlas versions cache: {e}") return config_obj diff --git a/tests/atlasapi/test_utils.py b/tests/atlasapi/test_utils.py index 148ead82..50ec993d 100644 --- a/tests/atlasapi/test_utils.py +++ b/tests/atlasapi/test_utils.py @@ -1,3 +1,5 @@ +import os +import sys from unittest import mock import pytest @@ -7,6 +9,9 @@ from brainglobe_atlasapi import utils test_url = "https://gin.g-node.org/BrainGlobe/atlases/raw/master/example_mouse_100um_v1.2.tar.gz" +conf_url = ( + "https://gin.g-node.org/BrainGlobe/atlases/raw/master/last_versions.conf" +) def test_http_check(): @@ -138,3 +143,26 @@ def test_conf_from_file_no_file(temp_path): utils.conf_from_file(conf_path) assert "Last versions cache file not found." == str(e) + + +@pytest.mark.skipif(sys.platform == "win32", reason="Does not run on Windows") +def test_conf_from_url_read_only(temp_path, mocker): + # Test with a valid URL and a non-existing parent folder + mocker.patch( + "brainglobe_atlasapi.utils.config.get_brainglobe_dir" + ).return_value = temp_path + mock_print = mocker.patch("builtins.print") + # Save the current permissions + curr_mode = oct(os.stat(temp_path).st_mode)[-3:] + + # Change the permissions to read-only + temp_path.chmod(0o444) + utils.conf_from_url(conf_url) + + mock_print.assert_called_once_with( + f"Could not update the latest atlas versions cache: [Errno 13] " + f"Permission denied: '{temp_path / 'last_versions.conf'}'" + ) + + # Set the permissions back to the original + temp_path.chmod(int(curr_mode, 8))