Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ repos:
- id: check-docstring-first
- id: check-symlinks
- id: check-added-large-files
exclude: ^(videoanalytics/videoanalytics/modules/yolov8n.pt|videoanalytics/videoanalytics/test.mp4)$
- id: check-merge-conflict
- id: check-executables-have-shebangs
- id: check-shebang-scripts-are-executable
Expand Down
15 changes: 12 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ all: check silent-stop run-app # Launch videoanalytics (EXAMPLE USAGE>> make )

launch: silent-stop run-app # Launch videoanalytics without user choice to stop containers (EXAMPLE USAGE>> make launch)

frebuild: fclean load-app run-app # BECARE: Completly delete images and load them after, then launch videoanalytics (EXAMPLE USAGE>> make frebuild)
frebuild: run-build # BECARE: Completly delete images and load them after, then launch videoanalytics (EXAMPLE USAGE>> make frebuild)

# Stop:
stop: stop-containers # Stop videoanalytics (EXAMPLE USAGE>> make stop )
Expand All @@ -89,9 +89,11 @@ back-sh: get-inside-backend # To get into backend (EXAMPLE USAGE>> make back-sh)

# Run App:
# ------------------------------
.PHONY: run-app
.PHONY: run-app run-build

run-app: figlet-launch compose-up-script
run-build: compose-script-build



# Sub commands:
Expand All @@ -114,6 +116,13 @@ compose-up-script:
@sudo docker compose -f $(DOCKER_COMPOSE_BACKEND) up -d
@echo "$(COLOR_GREEN)$(TAB)Docker Compose up finished successfully!$(COLOR_CLEAR)"

compose-script-build:
@echo "$(COLOR_YELLOW)$(TAB)Configuring Docker Compose...$(COLOR_CLEAR)"
@bash $(SCRIPTS_DIR)/docker-compose-setup.sh
@echo "$(COLOR_YELLOW)$(TAB)Building Docker Compose...$(COLOR_CLEAR)"
@sudo docker compose -f $(DOCKER_COMPOSE_BACKEND) build
@echo "$(COLOR_GREEN)$(TAB)Building Docker Compose is finished successfully!$(COLOR_CLEAR)"

see-backend-logs:
@echo "$(COLOR_YELLOW)$(TAB)Backend logs...$(COLOR_CLEAR)"
@export CONTAINER_ID=$$(sudo docker ps -q --filter "name=django_videoanalytics"); \
Expand Down Expand Up @@ -155,7 +164,7 @@ fclean: stop
figlet -c -t -f "ANSI Shadow" Deleting...; \
echo "\n\n\n"; \
echo "$(COLOR_YELLOW)$(TAB)$(TAB)$(TAB)Deleting...$(COLOR_CLEAR)"; \
sudo docker rmi -f $$(sudo docker images -a --quiet); \
sudo docker rmi -f $$(sudo docker images -a --quiet); h\
else \
echo "$(COLOR_GREEN)$(TAB)$(TAB)$(TAB)Cleaning canceled!$(COLOR_CLEAR)"; \
fi
Expand Down
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# Checkpoint_4 | Человеческий комментарий для проверки

Пункты 1 и 2 чекпоинта выполнены в полном объёме (статика, proxy). Для проверки отдачи статики открыается *url* админки. Всё умещено в 1 образе nginx.
Команды для запуска актуальны, всё накатиться и запустится автоматически. Желательно до git pull сделать docker compose down на предыдущем коммите.

ВНИМАНИЕ: при отсутствии вебкамеры подготовленное видео не отображается в фронте, но отображается в очереди и приходят уведомления в телеграмм (нужно допиливать кодовую базу, чтобы работал StreamingHttpResponse с mp4, отложили на попозже). Для тестирования с своей вэбкой уведомлений и очередей необходимо оказаться человеку/части тела человека в объективе
ВНИМАНИЕ: для запуска также необходимо поместить файл .env в папку с проектом. При желании можно подписаться на бота. Для этого необходимо написать боту https://t.me/JsonDumpBot , узнать свой "chat": { "**id**":** **123456789** и поместить его в файл .env через запятую. Важно, чтобы в конце OVCTECH_TG_CHAT_IDS была цифра, а не запятая. Токен трогать не нужно. В личку направили Павлу файлик.

По всем возникшим вопросам можно писать в любое время в тг: @ovctech @Alex_alex_68

# Предварительные требования:

**Выполнить следующую команду:**
Expand Down Expand Up @@ -51,7 +61,7 @@ Commands:

Скачайте репозиторий и перейдите в корень проекта:
```bash
git clone git@github.com:ovctech/videoanalytics.git -b checkpoint_1 && cd videoanalytics
git clone git@github.com:ovctech/videoanalytics.git -b checkpoint_3 && cd videoanalytics
```

## Автоматизированный метод
Expand All @@ -78,11 +88,12 @@ bash scripts/run.sh
```bash
sudo apt install -y make figlet
bash scripts/docker-compose-setup.sh
sudo make frebuild
sudo make
open http://127.0.1.1:8000/video_feed/?camera_url=do_not_have_webcam__if_have_dont_parametize__just_video_feed_slash
open http://127.0.1.1:8100/video_feed/?camera_url=do_not_have_webcam__if_have_dont_parametize__just_video_feed_slash
## ИЛИ при наличии вебкамеры
open http://127.0.1.1:8000/video_feed/
open http://127.0.1.1:8100/video_feed/
```
# Ожидаемый результат

У вас открывается браузер по умолчанию и отображается видео с закатом или видеопоток с вашей вебкамеры в зависимости от открытой *url* ссылки. В автоматизированном способе скрипт смотрит наличие вебкамеры в системы и при её отсутствии запускает подготовленное видео с закатом.
У вас открывается браузер по умолчанию и отображается видео с закатом или видеопоток с вашей вебкамеры в зависимости от открытой *url* ссылки (в случае отсутствия вебкамеры будет отображаться пустая страница, но весь функционал будет работать в нормальном режиме). Также открывается *flower* в браузере за отслеживанием очереди. Также открывается админка *django* с демонстрацией отгрузки статики.
76 changes: 73 additions & 3 deletions docker-compose-template.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
version: "3.9"

services:
redis:
container_name: redis_videoanalytics
image: redis:alpine
ports:
- 6379:6379
networks:
- django_network

postgres:
container_name: postgres_videoanalytics
image: postgres:latest
Expand All @@ -18,8 +25,9 @@ services:
build:
context: ./videoanalytics/
dockerfile: Dockerfile
ports:
- 8000:8000
entrypoint: /app/entrypoint.sh
expose:
- 8000
depends_on:
- postgres
environment:
Expand All @@ -28,12 +36,74 @@ services:
- POSTGRES_DB=my_database
- POSTGRES_USER=my_username
- POSTGRES_PASSWORD=my_password
env_file:
- .env
networks:
- django_network
# ${DEVICES}:
# ${DEVICES_DASH} /dev/video0:/dev/video0
volumes:
- ./data:/var/lib/postgresql/data
- ./videoanalytics/data:/data
- static_volume:/var/www/static

nginx:
container_name: nginx_videoanalytics
image: nginx:latest
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- static_volume:/var/www/static
ports:
- 8100:8100
depends_on:
- django
networks:
- django_network

celery_worker:
container_name: celery_worker_videoanalytics
restart: always
hostname: celery_worker
build:
context: ./videoanalytics
dockerfile: Dockerfile
command: ['celery', '-A', 'backend.celery_app', 'worker' ]
volumes:
- ./data:/var/lib/postgresql/data
- ./videoanalytics/data:/data
env_file:
- .env
depends_on:
- redis
links:
- redis
networks:
- django_network

flower_worker:
container_name: flower_worker_videoanalytics
restart: always
hostname: flower_worker
build:
context: ./videoanalytics
dockerfile: Dockerfile
ports:
- 5555:5555
command: ['celery', '-A', 'backend.celery_app', 'flower' ]
volumes:
- ./data:/var/lib/postgresql/data
- ./videoanalytics/data:/data
env_file:
- .env
depends_on:
- redis
links:
- redis
networks:
- django_network

volumes:
static_volume:

networks:
django_network:
Expand Down
26 changes: 26 additions & 0 deletions nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
events {}

http {
include /etc/nginx/mime.types;

upstream django {
server django_videoanalytics:8000;
}

server {
listen 8100;
server_name localhost;

location /static/ {
autoindex on;
alias /var/www/static/;
}

location / {
proxy_pass http://django;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
}
}
2 changes: 1 addition & 1 deletion scripts/configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ if [ -n "$ENV_SETUP" ]; then
# Append the environment variable setup to the detected shell's configuration file
echo 'export OVCTECH_VIDEOANALYTICS_SOFTWARE_INSTALLED=true' >> "$ENV_SETUP"
echo "${COLOR_GREEN}${TAB}${TAB}Installation flag set in $ENV_SETUP.${COLOR_CLEAR}"
echo "${COLOR_YELLOW}${TAB}${TAB}Please restart your terminal or source the config file to apply changes.${COLOR_CLEAR}"
echo "${COLOR_YELLOW}${TAB}${TAB}Please restart your terminal or source the config file to apply changes. Accept next offer for auto.${COLOR_CLEAR}"
else
echo "${COLOR_RED}${TAB}${TAB}${TAB}Could not determine shell configuration file to update.${COLOR_CLEAR}"
fi
Expand Down
11 changes: 8 additions & 3 deletions scripts/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ fi
# Check if the OVCTECH_VIDEOANALYTICS_SOFTWARE_INSTALLED environment variable is set to true
if [ "$OVCTECH_VIDEOANALYTICS_SOFTWARE_INSTALLED" = "true" ]; then
echo "${COLOR_GREEN}${TAB}Installation state verified. Proceeding to run the application.${COLOR_CLEAR}"
echo "${COLOR_GREEN}${TAB}Rebuilding if necessary.${COLOR_CLEAR}"
sudo make frebuild
else
echo "${COLOR_RED}${TAB}The software does not appear to be installed.${COLOR_CLEAR}"
read -p "${COLOR_YELLOW}${TAB}Would you like to install the software dependicies now? If yes - type yes${ENTER}${TAB}${TAB}Type choices: [Any button/yes] ${COLOR_CLEAR}" answer
Expand All @@ -57,18 +59,21 @@ else
fi
fi


###############################################################################

# Prepate docker compose file depending on system webcam
bash $RELATIVE_PATH/scripts/docker-compose-setup.sh

# Run application if dependicies are already installed
sudo make
sleep 3
sleep 15
open http://127.0.1.1:5555/
open http://127.0.1.1:8100/admin/
if test -n "$(find /dev -name 'video*' -print -quit)"; then
echo "Webcam found!"
open http://127.0.1.1:8000/video_feed/
open http://127.0.1.1:8100/video_feed/
else
echo "No webcam found."
open http://127.0.1.1:8000/video_feed/?camera_url=do_not_have_webcam__if_have_dont_parametize__just_video_feed_slash
open http://127.0.1.1:8100/video_feed/?camera_url=do_not_have_webcam__if_have_dont_parametize__just_video_feed_slash
fi
16 changes: 11 additions & 5 deletions videoanalytics/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,30 @@ FROM python:3.11.0-slim-bullseye AS builder

WORKDIR /app

COPY poetry.lock pyproject.toml ./

RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
libffi-dev \
libssl-dev \
libpq-dev \
curl \
redis-server \
&& rm -rf /var/lib/apt/lists/*

COPY pyproject.toml poetry.lock ./
RUN python -m pip install --no-cache-dir poetry==1.7.1 \
&& poetry config virtualenvs.in-project true \
&& poetry config installer.max-workers 10 \
&& poetry install --no-interaction --no-ansi --without dev,test

FROM python:3.11.0-slim-bullseye

WORKDIR /app

RUN mkdir -p /data

RUN mkdir -p /var/www/static
COPY --from=builder /app /app
COPY . /app/
COPY entrypoint.sh /app/

WORKDIR /app

CMD ["/app/.venv/bin/python", "manage.py", "runserver", "0.0.0.0:8000"]
ENV PATH="/app/.venv/bin:$PATH"
Empty file added videoanalytics/__init__.py
Empty file.
5 changes: 5 additions & 0 deletions videoanalytics/backend/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from .celery import app as celery_app

__all__ = ("celery_app",)
22 changes: 22 additions & 0 deletions videoanalytics/backend/celery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import os

from celery import Celery

# Set the default Django settings module for the 'celery' program.
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "backend.settings")

app = Celery("backend", broker="redis://redis:6379/0")

# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
# should have a `CELERY_` prefix.
app.config_from_object("django.conf:settings", namespace="CELERY")

# Load task modules from all registered Django apps.
app.autodiscover_tasks()


@app.task(bind=True)
def debug_task(self):
print(f"Request: {self.request!r}")
24 changes: 20 additions & 4 deletions videoanalytics/backend/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
https://docs.djangoproject.com/en/4.2/ref/settings/
"""

from pathlib import Path
import os
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
Expand All @@ -23,7 +23,7 @@
SECRET_KEY = "django-insecure-r)28+*-%uagi$_uvpdzs4lgstea85u7nikb7jc8-5uw803&&(o"

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
DEBUG = False

ALLOWED_HOSTS = [".localhost", "127.0.0.1", "[::1]", "127.0.1.1"]

Expand All @@ -39,6 +39,7 @@
"django.contrib.staticfiles",
"rest_framework",
"videoanalytics",
"celery",
]

MIDDLEWARE = [
Expand Down Expand Up @@ -118,13 +119,28 @@

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/

STATIC_URL = "static/"
STATIC_URL = "/static/"
MEDIA_URL = "/media/"
STATICFILES_DIRS = [
BASE_DIR / "static",
]
STATIC_ROOT = "/var/www/static/"


MEDIA_ROOT = os.path.join(BASE_DIR, "media")
# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

# set the celery broker url
CELERY_BROKER_URL = "redis://redis:6379/0"

# set the celery result backend
CELERY_RESULT_BACKEND = "redis://redis:6379/0"

# set the celery timezone
CELERY_TIMEZONE = "UTC"
Loading