From 230cf99f069e6f74de039067bf0e03132e7b7302 Mon Sep 17 00:00:00 2001 From: stanislas Date: Tue, 4 Mar 2025 00:06:09 +0100 Subject: [PATCH] save a file to alocal folder and make it executable --- majordome/__init__.py | 2 +- majordome/github_service.py | 18 +-------- majordome/local_files.py | 17 +++++++++ logging.conf => majordome/logging.conf | 0 majordome/main.py | 16 ++++++++ tests/conftest.py | 26 +++++++++++-- tests/local_files_test.py | 51 ++++++++++++++++++++++++++ tests/main_test.py | 13 +++++++ 8 files changed, 122 insertions(+), 21 deletions(-) create mode 100644 majordome/local_files.py rename logging.conf => majordome/logging.conf (100%) create mode 100644 majordome/main.py create mode 100644 tests/local_files_test.py create mode 100644 tests/main_test.py diff --git a/majordome/__init__.py b/majordome/__init__.py index 7007b3e..25d4ff0 100644 --- a/majordome/__init__.py +++ b/majordome/__init__.py @@ -1,5 +1,5 @@ import logging.config from pathlib import Path -current_path = Path.cwd() +current_path = Path(__file__).parent logging.config.fileConfig(str(current_path / "logging.conf")) diff --git a/majordome/github_service.py b/majordome/github_service.py index 086a2bf..ee6d388 100644 --- a/majordome/github_service.py +++ b/majordome/github_service.py @@ -31,10 +31,7 @@ class GithubConnector: if response.ok: logger.debug("Latest release found") return response.json()[0] - logger.error( - "Failed to get latest release from Github. Response code was: %s", - response.status_code, - ) + raise NoReleaseFound( f"No release found on Github for the repo {repo} from owner {owner}" ) @@ -59,23 +56,10 @@ class GithubConnector: if downloaded_response.ok: return downloaded_response.content - logger.error( - "Failed to download asset from Github repo %s of owner %s. Response code was: %s", - repo, - owner, - downloaded_response.status_code, - ) raise DownloadFailure( f"The asset {asset_id} was not found on Github for the repo {repo} from owner {owner}" ) - logger.error( - "Failed to find asset with id %s from Github repo %s of owner %s. Response code was: %s", - asset_id, - repo, - owner, - asset_response.status_code, - ) raise AssetNotFound( f"The asset {asset_id} was not found on Github for the repo {repo} from owner {owner}" ) diff --git a/majordome/local_files.py b/majordome/local_files.py new file mode 100644 index 0000000..d9304ce --- /dev/null +++ b/majordome/local_files.py @@ -0,0 +1,17 @@ +from pathlib import Path + + +def save(destination: Path, file_content: bytes): + destination.parent.mkdir(parents=True, exist_ok=True) + destination.write_bytes(file_content) + + +def set_execution_rights(file: Path): + file_rights = file.stat().st_mode + rights_to_set = file_rights | 0o111 + file.chmod(rights_to_set) + + +def save_and_make_executable(destination: Path, content: bytes): + save(destination, content) + set_execution_rights(destination) diff --git a/logging.conf b/majordome/logging.conf similarity index 100% rename from logging.conf rename to majordome/logging.conf diff --git a/majordome/main.py b/majordome/main.py new file mode 100644 index 0000000..e94362a --- /dev/null +++ b/majordome/main.py @@ -0,0 +1,16 @@ +from pathlib import Path + +from majordome.github_service import GithubConnector +from majordome.settings import GithubSettings +from majordome.software_repo import SoftwareRepo + +settings = GithubSettings() +github_service = GithubConnector(settings.token) + + +def download_latest( + url: str, asset_mnemonic: str, tag_mnemonic: str, destination: Path +): + software_repo = SoftwareRepo(url, github_service, tag_mnemonic, asset_mnemonic) + asset = software_repo.download_latest_asset() + destination.write_bytes(asset) diff --git a/tests/conftest.py b/tests/conftest.py index 2b47f96..9755dbb 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,9 +1,15 @@ +import shutil +from pathlib import Path + import pytest from majordome.github_service import GithubConnector from majordome.settings import GithubSettings from majordome.software_repo import SoftwareRepo + +current_dir = Path(__file__).parent + github_settings = GithubSettings() @@ -13,7 +19,7 @@ def github_token(): @pytest.fixture -def project_url(): +def freetube_url(): return "https://github.com/FreeTubeApp/FreeTube" @@ -34,14 +40,28 @@ def freetube_amd64_deb_mnemonic(): @pytest.fixture def freetube_repo( - project_url, + freetube_url, github_connector, freetube_tag_name_mnemonic, freetube_amd64_deb_mnemonic, ): return SoftwareRepo( - project_url, + freetube_url, github_connector, freetube_tag_name_mnemonic, freetube_amd64_deb_mnemonic, ) + + +@pytest.fixture +def clean_tmpdir(): + rm_tmpdir() + yield + rm_tmpdir() + + +def rm_tmpdir(): + print("teardown") + tmp_dir = current_dir / "tmp" + if tmp_dir.exists(): + shutil.rmtree(tmp_dir) diff --git a/tests/local_files_test.py b/tests/local_files_test.py new file mode 100644 index 0000000..da54214 --- /dev/null +++ b/tests/local_files_test.py @@ -0,0 +1,51 @@ +from pathlib import Path + +from majordome import local_files + +current_dir = Path(__file__).parent +tmp_dir = current_dir / "tmp" + + +def test_save_local_file(clean_tmpdir): + file_content = b"some bytes" + filename = "toto_titi.tutu" + file_to_save = tmp_dir / filename + tmp_files = list(tmp_dir.glob("*")) + assert len(tmp_files) == 0 + + local_files.save(file_to_save, file_content) + + tmp_files = list(tmp_dir.glob("*")) + assert len(tmp_files) == 1 + tmp_file = tmp_files[0] + assert tmp_file.name == filename + assert tmp_file.read_bytes() == file_content + + +def test_make_file_executable(clean_tmpdir): + file = tmp_dir / "toto_titi.tutu" + file.parent.mkdir(parents=True, exist_ok=True) + file.touch() + assert file.stat().st_mode == 0o100664 + + local_files.set_execution_rights(file) + + assert file.stat().st_mode == 0o100775 + + +def test_download_and_make_executable(clean_tmpdir): + file_content = b"some bytes" + filename = "toto_titi.tutu" + file_to_save = tmp_dir / filename + tmp_files = list(tmp_dir.glob("*")) + assert len(tmp_files) == 0 + + local_files.save_and_make_executable(file_to_save, file_content) + + tmp_files = list(tmp_dir.glob("*")) + assert len(tmp_files) == 1 + tmp_file = tmp_files[0] + assert tmp_file.name == filename + assert tmp_file.read_bytes() == file_content + + assert tmp_file.stat().st_mode == 0o100775 diff --git a/tests/main_test.py b/tests/main_test.py new file mode 100644 index 0000000..8ad8da8 --- /dev/null +++ b/tests/main_test.py @@ -0,0 +1,13 @@ +from pathlib import Path + +from majordome import main + + +def test_download_and_save_latest_asset(freetube_url, freetube_amd64_deb_mnemonic): + destination = Path(__file__).parent / "tmp" + + main.download_latest(freetube_url, freetube_amd64_deb_mnemonic, destination) + + files = list(destination.glob("*")) + assert len(files) == 1 + assert files[0].filename == "freetube_0.23.2_amd64.deb"