-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Vincent Berenz
committed
Oct 10, 2024
0 parents
commit b8077ce
Showing
23 changed files
with
4,258 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
name: unit tests | ||
|
||
on: | ||
push: | ||
branches: | ||
- master | ||
pull_request: | ||
branches: | ||
- master | ||
workflow_dispatch: | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-20.04 | ||
|
||
strategy: | ||
matrix: | ||
python-version: [3.9.2] | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v2 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
pip install poetry | ||
poetry install --with test | ||
- name: Run tests | ||
run: | | ||
poetry run pytest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Python bytecode | ||
__pycache__/ | ||
.py[cod] | ||
|
||
# Environments | ||
venv | ||
|
||
# Coverage reports | ||
.coverage | ||
*.xml | ||
|
||
# mypy | ||
.mypy_cache/ | ||
|
||
# Editors. | ||
*~ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
[![Python package](https://github.com/MPI-IS/nightskycam-images/actions/workflows/tests.yml/badge.svg)](https://github.com/MPI-IS/nightskycam-images/actions/workflows/tests.yml) | ||
[![PyPI version](https://img.shields.io/pypi/v/nightskycam-images.svg)](https://pypi.org/project/nightskycam-images/) | ||
|
||
> 🚧 **Under Construction** | ||
> This project is currently under development. Please check back later for updates. | ||
|
||
# Nightskycam Images | ||
|
||
This is the repository for `nightskycam_images`, | ||
a python package for managing images captured by the camera-RaspberryPi systems of the nightskycam project. | ||
These images are managed in a filesystem. | ||
|
||
Its functions include: | ||
* managing images (and related data) in a filesystem | ||
* generating thumbnail images | ||
* generating summary videos. | ||
|
||
## Requirements | ||
|
||
* Operating system: Linux or macOS | ||
* Python 3.9+ | ||
|
||
## Getting Started as a User (using `pip`) | ||
|
||
Dependency management with `pip` is easier to set up than with `poetry`, but the optional dependency-groups are not installable with `pip`. | ||
|
||
* Create and activate a new Python virtual environment: | ||
```bash | ||
python3 -m venv --copies venv | ||
source venv/bin/activate | ||
``` | ||
* Update `pip` and build package: | ||
```bash | ||
pip install -U pip # optional but always advised | ||
pip install . # -e option for editable mode | ||
``` | ||
|
||
## Getting Started as a Developer (using `poetry`) | ||
|
||
Dependency management with `poetry` is required for the installation of the optional dependency-groups. | ||
|
||
* Install [poetry](https://python-poetry.org/docs/). | ||
* Install dependencies for package | ||
(also automatically creates project's virtual environment): | ||
```bash | ||
poetry install | ||
``` | ||
* Install `dev` dependency group: | ||
```bash | ||
poetry install --with dev | ||
``` | ||
* Activate project's virtual environment: | ||
```bash | ||
poetry shell | ||
``` | ||
* Optional: Set up pre-commit git hook (automatic `isort` and `black` formatting): | ||
```bash | ||
pre-commit install | ||
``` | ||
The hook will now run automatically on `git commit`. It is not recommended, but the hook can be bypassed with the option `--no-verify`. | ||
|
||
The hook can also be manually run with: | ||
```bash | ||
# Force checking all files (instead of only changed files). | ||
pre-commit run --all-files | ||
``` | ||
|
||
## Tests (only possible for setup with `poetry`, not with `pip`) | ||
|
||
To install `test` dependency group: | ||
```bash | ||
poetry install --with test | ||
``` | ||
|
||
To run the tests: | ||
```bash | ||
python -m pytest | ||
``` | ||
|
||
To extract coverage data: | ||
* Get code coverage by measuring how much of the code is executed when running the tests: | ||
```bash | ||
coverage run -m pytest | ||
``` | ||
* View coverage results: | ||
```bash | ||
# Option 1: simple report in terminal. | ||
coverage report | ||
# Option 2: nicer HTML report. | ||
coverage html # Open resulting 'htmlcov/index.html' in browser. | ||
``` |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
""" | ||
Definition of project-level constants. | ||
""" | ||
|
||
from typing import Tuple | ||
|
||
# Files in general. | ||
FILE_PERMISSIONS: int = 0o755 # Octal integer. | ||
|
||
# HD image. | ||
IMAGE_FILE_FORMATS: Tuple[str, ...] = ("npy", "tiff", "jpg", "jpeg") | ||
|
||
# Thumbnail image. | ||
THUMBNAIL_DIR_NAME: str = "thumbnails" | ||
THUMBNAIL_FILE_FORMAT: str = "jpeg" | ||
THUMBNAIL_WIDTH: int = 200 # In pixels. | ||
|
||
# Zip. | ||
ZIP_DIR_NAME: str = "zip" | ||
|
||
# Video. | ||
VIDEO_FILE_NAME: str = "day_summary.webm" | ||
|
||
# Weather summary. | ||
WEATHER_SUMMARY_FILE_NAME: str = "weathers.toml" | ||
|
||
# Format patterns. | ||
|
||
# formats for filename, e.g. nightskycamX_2024_09_26_13_57_50.jpeg | ||
DATE_FORMAT_FILE: str = "%Y_%m_%d" | ||
TIME_FORMAT_FILE: str = "%H_%M_%S" | ||
DATETIME_FORMATS: Tuple[str, ...] = ("%d_%m_%Y_%H_%M_%S", "%Y_%m_%d_%H_%M_%S") | ||
|
||
# formats for displaying on the website | ||
DATE_FORMAT: str = "%Y-%m-%d" | ||
TIME_FORMAT: str = "%H:%M:%S" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
from pathlib import Path | ||
import tempfile | ||
|
||
import PIL.Image as PILImage | ||
import cv2 | ||
import numpy as np | ||
import numpy.typing as npt | ||
|
||
|
||
def _bits_reduction(data: npt.NDArray, target: type) -> npt.NDArray: | ||
original_max = np.iinfo(data.dtype).max | ||
target_max = np.iinfo(target).max | ||
ratio = target_max / original_max | ||
return (data * ratio).astype(target) | ||
|
||
|
||
def _to_8bits(image: npt.NDArray) -> npt.NDArray: | ||
return _bits_reduction(image, np.uint8) | ||
|
||
|
||
def npy_file_to_pil(image_path: Path) -> PILImage.Image: | ||
""" | ||
Read the file (expected to be an .npy file) and | ||
return a corresponding instance of PIL Image. | ||
It first converts the image to 8 bits. | ||
""" | ||
img_array = np.load(image_path) | ||
img_array = _to_8bits(img_array) | ||
|
||
# Create a temporary directory for intermediary tiff file. | ||
with tempfile.TemporaryDirectory() as tmp_dir: | ||
tiff_file_path = Path(tmp_dir) / f"{image_path.stem}.tiff" | ||
cv2.imwrite(str(tiff_file_path), img_array, [cv2.IMWRITE_TIFF_COMPRESSION, 1]) | ||
return PILImage.open(str(tiff_file_path)) | ||
|
||
|
||
def npy_file_to_numpy(image_path: Path) -> np.ndarray: | ||
""" | ||
Read the file (expected to be an .npy file) and | ||
return a corresponding numpy array, converted to 8 bits. | ||
""" | ||
img_array = np.load(image_path) | ||
img_array = _to_8bits(img_array) | ||
return img_array |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import os | ||
from pathlib import Path | ||
from typing import Optional | ||
|
||
|
||
def folder_has_changed( | ||
folder: Path, history: Optional[dict[Path, Optional[float]]] | ||
) -> bool: | ||
""" | ||
Check whether the last-modified-time of the directory changed | ||
since the previous check. | ||
If there is no history of a previous check: | ||
return True and initialise history. | ||
Parameters | ||
---------- | ||
folder | ||
Path to directory. | ||
history | ||
Last modification times found in previous check: | ||
- key: | ||
Path to directory. | ||
- value: | ||
Time of last modification of directory. | ||
""" | ||
history = history if history else {} | ||
|
||
# Float: number of seconds since epoch. | ||
last_modified_time = os.path.getmtime(folder) | ||
|
||
# Set to dummy value when key does NOT exist. | ||
previous_modified_time = history.get(folder, None) | ||
|
||
# If the folder has NO previous history | ||
# OR was modified since previous history, | ||
# update the history. | ||
if not previous_modified_time or previous_modified_time < last_modified_time: | ||
history[folder] = last_modified_time | ||
return True | ||
|
||
return False |
Oops, something went wrong.