diff --git a/.idea/misc.xml b/.idea/misc.xml index 3ce3588..c9a492c 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,4 +3,5 @@ + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..0f20fd2 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +Cat detection \ No newline at end of file diff --git a/docker/.dockerignore b/docker/.dockerignore new file mode 100644 index 0000000..22c4864 --- /dev/null +++ b/docker/.dockerignore @@ -0,0 +1,6 @@ +*.md +/venv +.git +__pycache__ +.pytest_cache +/tests \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..f2361f2 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,17 @@ +# Użyj obrazu bazowego Python 3.8 +FROM python:3.11 + +# Ustaw katalog roboczy na /app +WORKDIR /app + +# Skopiuj zawartość bieżącego katalogu do /app w kontenerze +COPY . /app + +# Zainstaluj zależności +RUN pip install --no-cache-dir -r requirements.txt + +# Wyeksponuj port 5000 +EXPOSE 5000 + +# Uruchom aplikację po uruchomieniu kontenera +CMD ["python", "main.py"] diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..48cf64e --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,10 @@ +version: '3.3' + +services: + cat-detection: + image: cat-detection + build: + context: ../ + dockerfile: ./docker/Dockerfile + ports: + - "5000:5000" \ No newline at end of file diff --git a/img/cat.png b/img/cat.png deleted file mode 100644 index 9abe07a..0000000 Binary files a/img/cat.png and /dev/null differ diff --git a/language_label_mapper.py b/language_label_mapper.py index aeaf1a0..95de877 100644 --- a/language_label_mapper.py +++ b/language_label_mapper.py @@ -1,3 +1,5 @@ +import os + from jproperties import Properties """ @@ -10,9 +12,11 @@ from jproperties import Properties def translate(to_translate, lang): try: config = Properties() + script_directory = os.path.dirname(os.path.abspath(__file__)) + resources_path = os.path.join(script_directory, "./resources") # Load properties file for given lang - with open(f"resources/{lang}.properties", 'rb') as config_file: + with open(os.path.join(resources_path, f"./{lang}.properties"), 'rb') as config_file: config.load(config_file, encoding='UTF-8') # Translate labels for given to_translate dictionary diff --git a/main.py b/main.py index b0be64d..58a866f 100644 --- a/main.py +++ b/main.py @@ -103,4 +103,4 @@ def upload_file(): if __name__ == '__main__': - app.run(debug=True) + app.run(host='0.0.0.0') diff --git a/requirements.txt b/requirements.txt index daeb034..a5e6c15 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,7 @@ flask==3.0.0 numpy==1.26.3 pillow==10.2.0 keras==2.15.0 -jproperties==2.1.1 \ No newline at end of file +jproperties==2.1.1 +tensorflow==2.15.0 +werkzeug==3.0.1 +pytest==7.4.4 \ No newline at end of file diff --git a/scripts/build_image.bat b/scripts/build_image.bat new file mode 100644 index 0000000..a48057f --- /dev/null +++ b/scripts/build_image.bat @@ -0,0 +1,24 @@ +@echo off +chcp 65001 >nul + +docker -v >nul 2>&1 +if %errorlevel% neq 0 ( + echo Docker is not installed. + exit /b 1 +) + +docker info >nul 2>&1 +if %errorlevel% neq 0 ( + echo Docker engine is not running. + exit /b 1 +) + +cd ../docker +echo Building docker image... +docker compose build cat-detection +if %errorlevel% neq 0 ( + echo Building cdocker imagew failed. + exit /b 1 +) + +echo The image was built successfully. diff --git a/scripts/build_image.sh b/scripts/build_image.sh new file mode 100644 index 0000000..45c2ed2 --- /dev/null +++ b/scripts/build_image.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +export LC_ALL=C.UTF-8 +export LANG=C.UTF-8 + +docker -v > /dev/null 2>&1 +if [ $? -ne 0 ]; then + echo -e "\033[31mDocker is not installed.\033[0m" + exit 1 +fi + +docker info > /dev/null 2>&1 +if [ $? -ne 0 ]; then + echo -e "\033[31mDocker engine is not running.\033[0m" + exit 1 +fi + +cd ../docker +echo -e "\033[32mBuilding docker image...\033[0m" +docker-compose build cat-detection + +if [ $? -ne 0 ]; then + echo -e "\033[31mBuilding docker image failed.\033[0m" + exit 1 +fi + +echo -e "\033[32mThe image was built successfully.\033[0m" diff --git a/scripts/run_tests.bat b/scripts/run_tests.bat new file mode 100644 index 0000000..b2f2fd7 --- /dev/null +++ b/scripts/run_tests.bat @@ -0,0 +1,14 @@ +@echo off +echo Running unit tests. + +set PYTHONPATH=%CD%;%PYTHONPATH% + +cd %~dp0 +pytest ../tests + +if %ERRORLEVEL% equ 0 ( + echo Tests passed successfully. +) else ( +Tests failed. + echo Tests failed. +) \ No newline at end of file diff --git a/scripts/start.bat b/scripts/start.bat new file mode 100644 index 0000000..9712cd6 --- /dev/null +++ b/scripts/start.bat @@ -0,0 +1,8 @@ +@echo off +chcp 65001 >nul + +docker compose -f ../docker/docker-compose.yml up cat-detection -d +if %errorlevel% neq 0 ( + echo Starting docker container failed. + exit /b 1 +) \ No newline at end of file diff --git a/scripts/start.sh b/scripts/start.sh new file mode 100644 index 0000000..eb7d9a7 --- /dev/null +++ b/scripts/start.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +export LC_ALL=C.UTF-8 +export LANG=C.UTF-8 + +docker-compose -f ../docker/docker-compose.yml up cat-detection -d + +if [ $? -ne 0 ]; then + echo -e "\033[31mStarting docker container failed.\033[0m" + exit 1 +fi diff --git a/tests/img/Egyptian_cat/Egyptian-Mau-Bronze-750.jpg b/tests/img/Egyptian_cat/Egyptian-Mau-Bronze-750.jpg new file mode 100644 index 0000000..2414cfa Binary files /dev/null and b/tests/img/Egyptian_cat/Egyptian-Mau-Bronze-750.jpg differ diff --git a/tests/img/Persian_cat/PER_Fluffy_Fancy_Antony_(5468896948).jpg b/tests/img/Persian_cat/PER_Fluffy_Fancy_Antony_(5468896948).jpg new file mode 100644 index 0000000..387bbc8 Binary files /dev/null and b/tests/img/Persian_cat/PER_Fluffy_Fancy_Antony_(5468896948).jpg differ diff --git a/tests/img/Siamese_cat/siamese-cat-cover.jpg b/tests/img/Siamese_cat/siamese-cat-cover.jpg new file mode 100644 index 0000000..6ae3269 Binary files /dev/null and b/tests/img/Siamese_cat/siamese-cat-cover.jpg differ diff --git a/tests/img/cheetah/TheCheethcat.jpg b/tests/img/cheetah/TheCheethcat.jpg new file mode 100644 index 0000000..625155b Binary files /dev/null and b/tests/img/cheetah/TheCheethcat.jpg differ diff --git a/tests/img/cougar/Cougar_at_Cougar_Mountain_Zoological_Park_2.jpg b/tests/img/cougar/Cougar_at_Cougar_Mountain_Zoological_Park_2.jpg new file mode 100644 index 0000000..e2b3f25 Binary files /dev/null and b/tests/img/cougar/Cougar_at_Cougar_Mountain_Zoological_Park_2.jpg differ diff --git a/tests/img/jaguar/Junior-Jaguar-Belize-Zoo.jpg b/tests/img/jaguar/Junior-Jaguar-Belize-Zoo.jpg new file mode 100644 index 0000000..450a858 Binary files /dev/null and b/tests/img/jaguar/Junior-Jaguar-Belize-Zoo.jpg differ diff --git a/tests/img/leopard/African_leopard_male_(cropped).jpg b/tests/img/leopard/African_leopard_male_(cropped).jpg new file mode 100644 index 0000000..8a7a3be Binary files /dev/null and b/tests/img/leopard/African_leopard_male_(cropped).jpg differ diff --git a/tests/img/lion/Lion_waiting_in_Namibia.jpg b/tests/img/lion/Lion_waiting_in_Namibia.jpg new file mode 100644 index 0000000..b98984a Binary files /dev/null and b/tests/img/lion/Lion_waiting_in_Namibia.jpg differ diff --git a/tests/img/lynx/552661_poster.jpg b/tests/img/lynx/552661_poster.jpg new file mode 100644 index 0000000..678a60b Binary files /dev/null and b/tests/img/lynx/552661_poster.jpg differ diff --git a/img/wolf.jpg b/tests/img/not a cat/wolf.jpg similarity index 100% rename from img/wolf.jpg rename to tests/img/not a cat/wolf.jpg diff --git a/tests/img/snow_lopard/Snow-Leopard.jpg b/tests/img/snow_lopard/Snow-Leopard.jpg new file mode 100644 index 0000000..f6d9846 Binary files /dev/null and b/tests/img/snow_lopard/Snow-Leopard.jpg differ diff --git a/tests/img/tabby/Cat_November_2010-1a.jpg b/tests/img/tabby/Cat_November_2010-1a.jpg new file mode 100644 index 0000000..0e729b7 Binary files /dev/null and b/tests/img/tabby/Cat_November_2010-1a.jpg differ diff --git a/tests/img/tiger/1000_F_88747131_OIL6X2l7Nur139dUHTdaRK51NwqW02DE.jpg b/tests/img/tiger/1000_F_88747131_OIL6X2l7Nur139dUHTdaRK51NwqW02DE.jpg new file mode 100644 index 0000000..97d9442 Binary files /dev/null and b/tests/img/tiger/1000_F_88747131_OIL6X2l7Nur139dUHTdaRK51NwqW02DE.jpg differ diff --git a/img/cat1.jpg b/tests/img/tiger_cat/cat1.jpg similarity index 100% rename from img/cat1.jpg rename to tests/img/tiger_cat/cat1.jpg diff --git a/tests/test_1.py b/tests/test_1.py new file mode 100644 index 0000000..8604b18 --- /dev/null +++ b/tests/test_1.py @@ -0,0 +1,19 @@ +import os + +from werkzeug.datastructures import FileStorage + +from main import app + + +def test_upload_file(): + with app.test_client() as test_client: + script_directory = os.path.dirname(os.path.abspath(__file__)) + image_path = os.path.join(script_directory, "./img/tiger_cat/cat1.jpg") + image = FileStorage( + stream=open(image_path, "rb"), + filename="cat1.jpg", + content_type="image/jpeg", + ) + + response = test_client.post('/api/v1/detect-cat', data={'image': image}, content_type='multipart/form-data') + assert response.status_code == 200 diff --git a/validator.py b/validator.py index 8aa7ec5..d661a6f 100644 --- a/validator.py +++ b/validator.py @@ -1,5 +1,3 @@ -import imghdr - """ Validation method. If everything fine then returns empty list.