feat: initial recipe-importer application
Python/Flask web app that scrapes Hungarian recipe sites (mindmegette.hu) and imports them into Mealie via its REST API. Includes dark-themed web UI with editable preview, Dockerfile, build script, and docker-compose. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# recipe-importer — Docker image build script
|
||||
# =============================================================================
|
||||
# Location: /home/kisfenyo/build/recipe-importer/build.sh
|
||||
#
|
||||
# Copies source from the git repo and builds the Docker image.
|
||||
# Build artifacts stay here — the git repo stays clean.
|
||||
#
|
||||
# Usage:
|
||||
# ./build.sh # Build for current platform, tag as :dev
|
||||
# ./build.sh 0.1.0 # Build with version tag
|
||||
# ./build.sh 0.1.0 --push # Build + push to Gitea registry
|
||||
# ./build.sh 0.1.0 --multiarch # Build amd64+arm64 + push
|
||||
# =============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
# --- Configuration ---
|
||||
REPO_DIR="/home/kisfenyo/git/recipe-importer"
|
||||
REGISTRY="gitea.dooplex.hu/admin"
|
||||
IMAGE="${REGISTRY}/recipe-importer"
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
BUILD_DIR="${SCRIPT_DIR}/workspace"
|
||||
|
||||
# --- Parse arguments ---
|
||||
VERSION="${1:-dev}"
|
||||
ACTION="${2:-}"
|
||||
|
||||
# --- Colors ---
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
|
||||
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||
error() { echo -e "${RED}[ERROR]${NC} $*"; }
|
||||
step() { echo -e "${CYAN}[STEP]${NC} $*"; }
|
||||
|
||||
# --- Pre-flight checks ---
|
||||
if [[ ! -d "${REPO_DIR}" ]]; then
|
||||
error "Source not found: ${REPO_DIR}"
|
||||
error "Clone the repo first: git clone https://gitea.dooplex.hu/admin/recipe-importer.git ${REPO_DIR}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v docker &>/dev/null; then
|
||||
error "Docker not found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
GIT_COMMIT="unknown"
|
||||
if [[ -d "${REPO_DIR}/.git" ]]; then
|
||||
GIT_COMMIT=$(cd "${REPO_DIR}" && git rev-parse --short HEAD 2>/dev/null || echo "unknown")
|
||||
fi
|
||||
|
||||
echo ""
|
||||
info "╔══════════════════════════════════════╗"
|
||||
info "║ recipe-importer image builder ║"
|
||||
info "╚══════════════════════════════════════╝"
|
||||
info "Version: ${VERSION}"
|
||||
info "Commit: ${GIT_COMMIT}"
|
||||
info "Source: ${REPO_DIR}"
|
||||
info "Build dir: ${BUILD_DIR}"
|
||||
info "Image: ${IMAGE}:${VERSION}"
|
||||
echo ""
|
||||
|
||||
# =========================================================================
|
||||
# Step 1: Pull latest & sync source
|
||||
# =========================================================================
|
||||
step "1/2 — Syncing source to workspace..."
|
||||
|
||||
cd "${REPO_DIR}"
|
||||
git pull --ff-only 2>/dev/null || warn "git pull failed (offline or dirty tree?)"
|
||||
|
||||
rm -rf "${BUILD_DIR}"
|
||||
mkdir -p "${BUILD_DIR}"
|
||||
|
||||
rsync -a --delete \
|
||||
--exclude '.git' \
|
||||
--exclude 'mindmegette-examples' \
|
||||
--exclude '__pycache__' \
|
||||
--exclude '*.pyc' \
|
||||
"${REPO_DIR}/" "${BUILD_DIR}/"
|
||||
|
||||
# Verify structure
|
||||
for required in Dockerfile requirements.txt app/main.py app/scraper.py app/mealie.py; do
|
||||
if [[ ! -f "${BUILD_DIR}/${required}" ]]; then
|
||||
error "Missing: ${required}"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
info "Source synced ✓"
|
||||
|
||||
# =========================================================================
|
||||
# Step 2: Docker build
|
||||
# =========================================================================
|
||||
step "2/2 — Building Docker image..."
|
||||
|
||||
cd "${BUILD_DIR}"
|
||||
|
||||
BUILD_ARGS=(
|
||||
--build-arg "VERSION=${VERSION}"
|
||||
)
|
||||
|
||||
case "${ACTION}" in
|
||||
--push)
|
||||
info "Building for current platform + pushing..."
|
||||
docker build "${BUILD_ARGS[@]}" \
|
||||
-t "${IMAGE}:${VERSION}" \
|
||||
-t "${IMAGE}:latest" \
|
||||
.
|
||||
|
||||
info "Pushing..."
|
||||
docker push "${IMAGE}:${VERSION}"
|
||||
docker push "${IMAGE}:latest"
|
||||
;;
|
||||
|
||||
--multiarch)
|
||||
info "Building multi-arch (amd64 + arm64) + pushing..."
|
||||
|
||||
if ! docker buildx inspect felhom-builder &>/dev/null; then
|
||||
info "Creating buildx builder (one-time setup)..."
|
||||
docker buildx create --name felhom-builder --use --bootstrap
|
||||
else
|
||||
docker buildx use felhom-builder
|
||||
fi
|
||||
|
||||
docker buildx build "${BUILD_ARGS[@]}" \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
-t "${IMAGE}:${VERSION}" \
|
||||
-t "${IMAGE}:latest" \
|
||||
--push \
|
||||
.
|
||||
;;
|
||||
|
||||
*)
|
||||
info "Building for current platform (local only)..."
|
||||
docker build "${BUILD_ARGS[@]}" \
|
||||
-t "${IMAGE}:${VERSION}" \
|
||||
-t "${IMAGE}:latest" \
|
||||
.
|
||||
;;
|
||||
esac
|
||||
|
||||
# =========================================================================
|
||||
# Summary
|
||||
# =========================================================================
|
||||
echo ""
|
||||
info "╔══════════════════════════════════════╗"
|
||||
info "║ Build complete ✓ ║"
|
||||
info "╚══════════════════════════════════════╝"
|
||||
info "Image: ${IMAGE}:${VERSION}"
|
||||
|
||||
SIZE=$(docker image inspect "${IMAGE}:${VERSION}" --format='{{.Size}}' 2>/dev/null || echo "")
|
||||
if [[ -n "${SIZE}" ]]; then
|
||||
SIZE_HUMAN=$(numfmt --to=iec "${SIZE}" 2>/dev/null || echo "${SIZE} bytes")
|
||||
info "Size: ${SIZE_HUMAN}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
if [[ "${ACTION}" == "" ]]; then
|
||||
info "Image is local only. To push:"
|
||||
info " ./build.sh ${VERSION} --push # current arch"
|
||||
info " ./build.sh ${VERSION} --multiarch # amd64 + arm64"
|
||||
fi
|
||||
Reference in New Issue
Block a user