Files
infoscreen/Makefile
olaf fcc0dfbb0f feat(conversions): end-to-end PPT/PPTX/ODP -> PDF pipeline with RQ worker + Gotenberg
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
2025-10-07 19:06:09 +00:00

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"