DB/model Add Conversion model + ConversionStatus enum (pending, processing, ready, failed) Alembic migrations: create conversions table, indexes, unique (source_event_media_id, target_format, file_hash), and NOT NULL on file_hash API Enqueue on upload (ppt|pptx|odp) in routes/eventmedia.py: compute sha256, upsert Conversion, enqueue job New routes: POST /api/conversions/<media_id>/pdf — ensure/enqueue conversion GET /api/conversions/<media_id>/status — latest status/details GET /api/files/converted/<path> — serve converted PDFs Register conversions blueprint in wsgi Worker server/worker.py: convert_event_media_to_pdf Calls Gotenberg /forms/libreoffice/convert, writes to server/media/converted/ Updates Conversion status, timestamps, error messages Fix media root resolution to /server/media Prefer function enqueue over string path; expose server.worker in package init for RQ string compatibility Queue/infra server/task_queue.py: RQ queue helper (REDIS_URL, default redis://redis:6379/0) docker-compose: Add redis and gotenberg services Add worker service (rq worker conversions) Pass REDIS_URL and GOTENBERG_URL to server/worker Mount shared media volume in prod for API/worker parity docker-compose.override: Add dev redis/gotenberg/worker services Ensure PYTHONPATH + working_dir allow importing server.worker Use rq CLI instead of python -m rq for worker Dashboard dev: run as appropriate user/root and pre-create/chown caches to avoid EACCES Dashboard dev UX Vite: set cacheDir .vite to avoid EACCES in node_modules Disable Node inspector by default to avoid port conflicts Docs Update copilot-instructions.md with conversion system: flow, services, env vars, endpoints, storage paths, and data model
93 lines
2.9 KiB
Makefile
93 lines
2.9 KiB
Makefile
# Makefile for infoscreen_2025
|
|
# Usage: run `make help` to see available targets.
|
|
|
|
# Default compose files
|
|
COMPOSE_FILES=-f docker-compose.yml -f docker-compose.override.yml
|
|
COMPOSE=docker compose $(COMPOSE_FILES)
|
|
|
|
# Registry and image names (adjust if needed)
|
|
REGISTRY=ghcr.io/robbstarkaustria
|
|
API_IMAGE=$(REGISTRY)/infoscreen-api:latest
|
|
DASH_IMAGE=$(REGISTRY)/infoscreen-dashboard:latest
|
|
LISTENER_IMAGE=$(REGISTRY)/infoscreen-listener:latest
|
|
SCHED_IMAGE=$(REGISTRY)/infoscreen-scheduler:latest
|
|
|
|
.PHONY: help
|
|
help:
|
|
@echo "Available targets:"
|
|
@echo " up - Start dev stack (compose + override)"
|
|
@echo " down - Stop dev stack"
|
|
@echo " logs - Tail logs for all services"
|
|
@echo " logs-% - Tail logs for a specific service (e.g., make logs-server)"
|
|
@echo " build - Build all images locally"
|
|
@echo " push - Push built images to GHCR"
|
|
@echo " pull-prod - Pull prod images from GHCR"
|
|
@echo " up-prod - Start prod stack (docker-compose.prod.yml)"
|
|
@echo " down-prod - Stop prod stack"
|
|
@echo " health - Quick health checks"
|
|
@echo " fix-perms - Recursively chown workspace to current user"
|
|
|
|
|
|
# ---------- Development stack ----------
|
|
.PHONY: up
|
|
up: ## Start dev stack
|
|
$(COMPOSE) up -d --build
|
|
|
|
.PHONY: down
|
|
down: ## Stop dev stack
|
|
$(COMPOSE) down
|
|
|
|
.PHONY: logs
|
|
logs: ## Tail logs for all services
|
|
$(COMPOSE) logs -f
|
|
|
|
.PHONY: logs-%
|
|
logs-%: ## Tail logs for a specific service, e.g. `make logs-server`
|
|
$(COMPOSE) logs -f $*
|
|
|
|
# ---------- Images: build/push ----------
|
|
.PHONY: build
|
|
build: ## Build all images locally
|
|
docker build -f server/Dockerfile -t $(API_IMAGE) .
|
|
docker build -f dashboard/Dockerfile -t $(DASH_IMAGE) .
|
|
docker build -f listener/Dockerfile -t $(LISTENER_IMAGE) .
|
|
docker build -f scheduler/Dockerfile -t $(SCHED_IMAGE) .
|
|
|
|
.PHONY: push
|
|
push: ## Push all images to GHCR
|
|
docker push $(API_IMAGE)
|
|
docker push $(DASH_IMAGE)
|
|
docker push $(LISTENER_IMAGE)
|
|
docker push $(SCHED_IMAGE)
|
|
|
|
# ---------- Production stack ----------
|
|
PROD_COMPOSE=docker compose -f docker-compose.prod.yml
|
|
|
|
.PHONY: pull-prod
|
|
pull-prod: ## Pull prod images
|
|
$(PROD_COMPOSE) pull
|
|
|
|
.PHONY: up-prod
|
|
up-prod: ## Start prod stack
|
|
$(PROD_COMPOSE) up -d
|
|
|
|
.PHONY: down-prod
|
|
down-prod: ## Stop prod stack
|
|
$(PROD_COMPOSE) down
|
|
|
|
# ---------- Health ----------
|
|
.PHONY: health
|
|
health: ## Quick health checks
|
|
@echo "API health:" && curl -fsS http://localhost:8000/health || true
|
|
@echo "Dashboard (dev):" && curl -fsS http://localhost:5173/ || true
|
|
@echo "MQTT TCP 1883:" && nc -z localhost 1883 && echo OK || echo FAIL
|
|
@echo "MQTT WS 9001:" && nc -z localhost 9001 && echo OK || echo FAIL
|
|
|
|
# ---------- Permissions ----------
|
|
.PHONY: fix-perms
|
|
fix-perms:
|
|
@echo "Fixing ownership to current user recursively (may prompt for sudo password)..."
|
|
sudo chown -R $$(id -u):$$(id -g) .
|
|
@echo "Done. Consider adding UID and GID to your .env to prevent future root-owned files:"
|
|
@echo " echo UID=$$(id -u) >> .env && echo GID=$$(id -g) >> .env"
|