From d0669e4dd0bf9491f8b7a221607652e26d3507c2 Mon Sep 17 00:00:00 2001 From: Ismo Vuorinen Date: Wed, 30 Apr 2025 17:22:21 +0300 Subject: [PATCH] chore(lint): more linting fixes --- .editorconfig | 5 +-- .github/CONTRIBUTING.md | 44 ++++++++++---------- README.md | 8 ++-- aeonview.py | 8 ++-- aeonview_test.py | 92 +++++++++++++++++++++++++++++------------ pyproject.toml | 2 +- 6 files changed, 98 insertions(+), 61 deletions(-) diff --git a/.editorconfig b/.editorconfig index 65bc698..cf1202f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -20,7 +20,6 @@ indent_style = tab [*.md] trim_trailing_whitespace = false -max_line_length = 100 -[*.yml] -max_line_length = 100 +[*.{yml,toml,md}] +max_line_length = 200 diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 98ae206..fd3dcc8 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -6,22 +6,22 @@ This guide will help you get started. ## 🛠 Project Setup 1. Clone the repository: - ```bash - git clone https://github.com/your-username/aeonview.git - cd aeonview - ``` + ```bash + git clone https://github.com/your-username/aeonview.git + cd aeonview + ``` 2. Set up your environment: - ```bash - python3 -m venv venv - source venv/bin/activate - pip install -r dev-requirements.txt - ``` + ```bash + python3 -m venv venv + source venv/bin/activate + pip install -r dev-requirements.txt + ``` 3. Install pre-commit hooks: - ```bash - pre-commit install - ``` + ```bash + pre-commit install + ``` ## ✅ Development Workflow @@ -46,20 +46,20 @@ make lint # check for lint errors ## ✅ Submitting a Pull Request 1. Create a feature branch: - ```bash - git checkout -b feature/my-new-feature - ``` + ```bash + git checkout -b feature/my-new-feature + ``` 2. Commit your changes: - ```bash - git add . - git commit -m "feat: add support for X" - ``` + ```bash + git add . + git commit -m "feat: add support for X" + ``` 3. Push and open a pull request: - ```bash - git push origin feature/my-new-feature - ``` + ```bash + git push origin feature/my-new-feature + ``` 4. Follow the PR template and link any relevant issues. diff --git a/README.md b/README.md index 8f06723..900f9e8 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ ```markdown - _) - _` | -_) _ \ \ \ \ / | -_) \ \ \ / - \__,_| \___| \___/ _| _| \_/ _| \___| \_/\_/ - aeonview - a simple timelapse tool +# _) +# _` | -_) _ \ \ \ \ / | -_) \ \ \ / +# \__,_| \___| \___/ _| _| \_/ _| \___| \_/\_/ +# aeonview - a simple timelapse tool ``` **aeonview** is a Python-based tool for generating timelapse videos diff --git a/aeonview.py b/aeonview.py index a6e87ed..6ac2d5f 100644 --- a/aeonview.py +++ b/aeonview.py @@ -365,12 +365,12 @@ class AeonViewHelpers: if url.endswith(".png"): return ".png" - elif url.endswith(".gif"): + if url.endswith(".gif"): return ".gif" - elif url.endswith(".webp"): + if url.endswith(".webp"): return ".webp" - else: - return ".jpg" + + return ".jpg" @staticmethod def setup_logger(verbose: bool): diff --git a/aeonview_test.py b/aeonview_test.py index 2bc79ce..06be73e 100644 --- a/aeonview_test.py +++ b/aeonview_test.py @@ -92,27 +92,35 @@ def test_get_image_paths_valid(): date = datetime(2025, 4, 10, 12, 30, 45) aeon_view_images = AeonViewImages(destination_base, url) paths = aeon_view_images.get_image_paths(url, destination_base, date) + + a_p = destination_base / "2025-04" / "10" / "12-30-45.jpg" + assert paths["url"] == url assert paths["file"] == "12-30-45.jpg" - assert paths["destinations"][ - "file"] == destination_base / "2025-04" / "10" / "12-30-45.jpg" - + assert paths["destinations"]["file"] == a_p def test_get_image_paths_invalid_url(): with pytest.raises(SystemExit), mock.patch("aeonview.logging.error") as log: aeon_view_images = AeonViewImages(default_test_path, "invalid-url") - aeon_view_images.get_image_paths("invalid-url", default_test_path, - datetime(2025, 4, 10)) + aeon_view_images.get_image_paths( + "invalid-url", + default_test_path, + datetime(2025, 4, 10) + ) assert AeonViewMessages.INVALID_URL in log.call_args[0][0] def test_get_image_paths_invalid_date(): with pytest.raises(SystemExit), mock.patch("aeonview.logging.error") as log: - aeon_view_images = AeonViewImages(default_test_path, - f"{default_image_domain}.jpg") - aeon_view_images.get_image_paths(f"{default_image_domain}.jpg", - default_test_path, - "invalid-date") # pyright: ignore [reportArgumentType] + aeon_view_images = AeonViewImages( + default_test_path, + f"{default_image_domain}.jpg" + ) + aeon_view_images.get_image_paths( + f"{default_image_domain}.jpg", + default_test_path, + "invalid-date" # pyright: ignore [reportArgumentType] + ) assert AeonViewMessages.INVALID_DATE in log.call_args[0][0] @@ -138,8 +146,11 @@ def test_download_image_success(mock_get): with tempfile.NamedTemporaryFile(delete=True) as temp_file: destination = Path(temp_file.name) avi.download_image(destination) - mock_get.assert_called_once_with(f"{default_image_domain}.jpg", - stream=True, timeout=10) + mock_get.assert_called_once_with( + f"{default_image_domain}.jpg", + stream=True, + timeout=10 + ) assert destination.exists() @@ -161,8 +172,13 @@ def test_download_image_failure(mock_get): @mock.patch("aeonview.AeonViewHelpers.mkdir_p") @mock.patch("subprocess.run") def test_generate_daily_video(mock_subprocess_run, mock_mkdir_p): - args = argparse.Namespace(simulate=False, fps=10, day="01", month="04", - year="2025") + args = argparse.Namespace( + simulate=False, + fps=10, + day="01", + month="04", + year="2025" + ) avv = AeonViewVideos(default_test_path, args) with mock.patch("aeonview.logging.info") as log: avv.generate_daily_video() @@ -177,31 +193,46 @@ def test_generate_daily_video(mock_subprocess_run, mock_mkdir_p): @mock.patch("aeonview.AeonViewHelpers.mkdir_p") def test_generate_daily_video_simulate(mock_mkdir_p): - args = argparse.Namespace(simulate=True, fps=10, day="01", month="04", - year="2025") + args = argparse.Namespace( + simulate=True, + fps=10, + day="01", + month="04", + year="2025" + ) avv = AeonViewVideos(default_test_path, args) avv.generate_daily_video() mock_mkdir_p.assert_not_called() def test_generate_monthly_video_not_implemented(): - args = argparse.Namespace(simulate=False, fps=10, day="01", month="04", - year="2025") + args = argparse.Namespace( + simulate=False, + fps=10, + day="01", + month="04", + year="2025" + ) avv = AeonViewVideos(default_test_path, args) with pytest.raises(NotImplementedError): avv.generate_monthly_video(Path("/tmp")) def test_generate_yearly_video_not_implemented(): - args = argparse.Namespace(simulate=False, fps=10, day="01", month="04", - year="2025") + args = argparse.Namespace( + simulate=False, + fps=10, + day="01", + month="04", + year="2025" + ) avv = AeonViewVideos(default_test_path, args) with pytest.raises(NotImplementedError): avv.generate_yearly_video(Path("/tmp")) @mock.patch("sys.argv", ["aeonview.py", "--mode", "image", "--url", - f"{default_image_domain}.jpg"]) + f"{default_image_domain}.jpg"]) def test_parse_arguments_image_mode(): args, _ = AeonViewHelpers.parse_arguments() assert args.mode == "image" @@ -210,7 +241,7 @@ def test_parse_arguments_image_mode(): @mock.patch("sys.argv", ["aeonview.py", "--mode", "video", "--project", - f"{default_project}"]) + f"{default_project}"]) def test_parse_arguments_video_mode(): args, _ = AeonViewHelpers.parse_arguments() assert args.mode == "video" @@ -234,8 +265,10 @@ def test_parse_arguments_fps(): assert args.fps == 30 -@mock.patch("sys.argv", - ["aeonview.py", "--mode", "video", "--generate", "2023-10-01"]) +@mock.patch( + "sys.argv", + ["aeonview.py", "--mode", "video", "--generate", "2023-10-01"] +) def test_parse_arguments_generate_date(): args, _ = AeonViewHelpers.parse_arguments() assert args.mode == "video" @@ -268,7 +301,10 @@ def test_image_simulation(mock_download_image, mock_mkdir_p): args.simulate = True args.date = "2025-04-10 12:30:45" avi = AeonViewImages( - default_test_path, f"{default_image_domain}.jpg", args) + default_test_path, + f"{default_image_domain}.jpg", + args + ) with mock.patch("aeonview.logging.info") as log: avi.get_current_image() mock_mkdir_p.assert_not_called() @@ -302,7 +338,8 @@ def test_setup_logger_verbose(mock_basic_config): AeonViewHelpers.setup_logger(verbose=True) mock_basic_config.assert_called_once_with( level=logging.DEBUG, - format="[%(levelname)s] %(message)s") + format="[%(levelname)s] %(message)s" + ) @mock.patch("logging.basicConfig") @@ -310,4 +347,5 @@ def test_setup_logger_non_verbose(mock_basic_config): AeonViewHelpers.setup_logger(verbose=False) mock_basic_config.assert_called_once_with( level=logging.INFO, - format="[%(levelname)s] %(message)s") + format="[%(levelname)s] %(message)s" + ) diff --git a/pyproject.toml b/pyproject.toml index 8c66d37..f39fdd5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,4 +21,4 @@ python_files = ["*_test.py"] ignore-patterns='^\.#' ignore-paths='^\.#' ignore='CVS,.venv' -disable='attribute-defined-outside-init,invalid-name,missing-docstring,protected-access,too-few-public-methods,format' +disable='attribute-defined-outside-init,invalid-name,missing-docstring,protected-access,too-many-instance-attributes,too-few-public-methods,format'