From c827a2ae03ef8d6a8111b4dbb3132f05a823d9f0 Mon Sep 17 00:00:00 2001 From: hbrain Date: Sun, 31 May 2026 10:36:16 +0200 Subject: [PATCH] Increased word-character numbers --- bin/debug_generate_data.sh | 242 ------------------------------------- bin/generate_data.sh | 15 +-- bin/run_napoli_wrapper.sh | 5 - 3 files changed, 8 insertions(+), 254 deletions(-) delete mode 100755 bin/debug_generate_data.sh delete mode 100755 bin/run_napoli_wrapper.sh diff --git a/bin/debug_generate_data.sh b/bin/debug_generate_data.sh deleted file mode 100755 index 6705f35..0000000 --- a/bin/debug_generate_data.sh +++ /dev/null @@ -1,242 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -IN_DIR="${1:?Usage: $0 [\"Title\"] [\"Location\"] [max_frames]}" -TITLE="${2:-}" -LOCATION="${3:-}" -MAX_FRAMES="${4:-12}" - -# Source system-wide Gemini API key if present so the webserver can run this as www-data. -if [ -f /etc/mvlog/gemini.env ]; then - # shellcheck disable=SC1090 - . /etc/mvlog/gemini.env -fi - -: "${GEMINI_API_KEY:?Set GEMINI_API_KEY first in the environment}" -MODEL="${GEMINI_MODEL:-gemini-2.5-flash}" - -TMPDIR="${TMPDIR:-$(mktemp -d)}" -FRAMES_DIR="$TMPDIR/frames" -mkdir -p "$FRAMES_DIR" - -# Print TMPDIR for debugging when run interactively -echo "DEBUG: TMPDIR=$TMPDIR" >&2 - -cleanup() { - rm -rf "$TMPDIR" -} -trap cleanup EXIT - -# Collect media files (natural sort) -mapfile -t FILES < <(find "$IN_DIR" -maxdepth 1 -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.webp' -o -iname '*.gif' -o -iname '*.mp4' -o -iname '*.mov' -o -iname '*.m4v' -o -iname '*.webm' -o -iname '*.mkv' \) -printf '%f\n' | sort -V) - -if [ "${#FILES[@]}" -eq 0 ]; then - echo "No media files found in $IN_DIR" >&2 - exit 1 -fi - -frame_count=0 - -# Helper: extract scaled JPEG from image -extract_image_frame() { - local src="$1" dst="$2" - ffmpeg -hide_banner -loglevel error -y -i "$src" -vf "scale=1024:-1" -q:v 4 "$dst" -} - -# Helper: extract frame from video at time -extract_video_frame_at() { - local src="$1" time="$2" dst="$3" - # Use -ss before -i for fast seek - ffmpeg -hide_banner -loglevel error -y -ss "$time" -i "$src" -frames:v 1 -vf "scale=1024:-1" -q:v 4 "$dst" -} - -# Process files: images -> one frame each; videos -> up to 3 frames evenly spaced (subject to MAX_FRAMES) -for f in "${FILES[@]}"; do - full="$IN_DIR/$f" - ext="${f##*.}" - ext_l="${ext,,}" - - if [[ "$ext_l" =~ ^(mp4|mov|m4v|webm|mkv)$ ]]; then - # video: probe duration - duration=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$full" 2>/dev/null || echo 0) - duration=${duration:-0} - # choose frames per video - if awk "BEGIN{print ($duration >= 6)}" | grep -q 1; then - nframes=3 - elif awk "BEGIN{print ($duration >= 3)}" | grep -q 1; then - nframes=2 - else - nframes=1 - fi - # limit to remaining slots - remaining=$((MAX_FRAMES - frame_count)) - if [ "$remaining" -le 0 ]; then break; fi - if [ "$nframes" -gt "$remaining" ]; then nframes=$remaining; fi - - # compute times and extract - i=1 - while [ $i -le $nframes ]; do - # time = (i/(n+1)) * duration - time=$(awk -v d="$duration" -v i="$i" -v n="$nframes" 'BEGIN{ if(d<=0){print 0} else {printf "%.3f", (i/ (n+1))*d }}') - out="$FRAMES_DIR/frame_$(printf "%03d" "$frame_count").jpg" - extract_video_frame_at "$full" "$time" "$out" - frame_count=$((frame_count+1)) - i=$((i+1)) - if [ "$frame_count" -ge "$MAX_FRAMES" ]; then break 2; fi - done - else - # image - out="$FRAMES_DIR/frame_$(printf "%03d" "$frame_count").jpg" - extract_image_frame "$full" "$out" - frame_count=$((frame_count+1)) - if [ "$frame_count" -ge "$MAX_FRAMES" ]; then break; fi - fi -done - -# Gather produced frames -mapfile -t FRAMES < <(find "$FRAMES_DIR" -type f -name '*.jpg' | sort) -if [ "${#FRAMES[@]}" -eq 0 ]; then - echo "No frames produced from media" >&2 - exit 1 -fi - -# Build prompt for Gemini -if [ -z "$TITLE" ]; then - # Default title: directory basename - TITLE="$(basename "$IN_DIR")" -fi - -PROMPT=$(cat </dev/null 2>&1; then - echo "jq is required" >&2 - exit 1 -fi - -# Build parts and request JSON using Python to avoid argument-list limits -PROMPT_FILE="$TMPDIR/prompt.txt" -printf "%s" "$PROMPT" > "$PROMPT_FILE" -FRAMES_LIST="$TMPDIR/frames.list" -printf "%s\n" "${FRAMES[@]}" > "$FRAMES_LIST" - -REQUEST_FILE="$TMPDIR/request.json" -RESPONSE_FILE="$TMPDIR/response.json" - -python3 - "$PROMPT_FILE" "$REQUEST_FILE" "$FRAMES_LIST" <<'PY' -import sys, json, base64 -prompt_file = sys.argv[1] -request_file = sys.argv[2] -frames_list = sys.argv[3] -with open(prompt_file, 'r', encoding='utf-8') as f: - prompt = f.read() -parts = [{"text": prompt}] -with open(frames_list, 'r', encoding='utf-8') as fl: - for line in fl: - img = line.strip() - if not img: - continue - with open(img, 'rb') as fh: - b64 = base64.b64encode(fh.read()).decode('ascii') - parts.append({"inline_data": {"mime_type": "image/jpeg", "data": b64}}) -req = {"contents": [{"parts": parts}], "generationConfig": {"temperature": 0.7, "responseMimeType": "application/json"}} -with open(request_file, 'w', encoding='utf-8') as rf: - json.dump(req, rf, ensure_ascii=False) -PY - -echo "Calling Gemini API..." -echo "DEBUG_MODEL=$MODEL" >&2 - -curl -sS \ - "https://generativelanguage.googleapis.com/v1beta/models/${MODEL}:generateContent?key=${GEMINI_API_KEY}" \ - -H "Content-Type: application/json" \ - -X POST \ - -d @"$REQUEST_FILE" \ - > "$RESPONSE_FILE" -# debug: save request/response for inspection -cp "$REQUEST_FILE" "$IN_DIR/debug_request.json" || true -cp "$RESPONSE_FILE" "$IN_DIR/debug_response.json" || true -chown www-data:www-data "$IN_DIR/debug_request.json" "$IN_DIR/debug_response.json" 2>/dev/null || true - -TEXT=$(jq -r '.candidates[0].content.parts[0].text // empty' "$RESPONSE_FILE") -if [ -z "$TEXT" ]; then - echo "Gemini returned no text. Full response:" >&2 - cat "$RESPONSE_FILE" >&2 - exit 1 -fi - -# Save raw Gemini JSON for reference -OUT_JSON="$IN_DIR/gemini_generated.json" -echo "$TEXT" | jq . > "$OUT_JSON" - -# Extract fields from Gemini JSON -DESCRIPTION=$(echo "$TEXT" | jq -r '.description // empty') -TEASER=$(echo "$TEXT" | jq -r '.teaser // empty') -# tags as comma-separated -TAGS=$(echo "$TEXT" | jq -r '.tags // [] | join(", ")') - -# Determine a Date string (Month Year) from first media file mtime -firstfile="$(find "$IN_DIR" -maxdepth 1 -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.webp' -o -iname '*.gif' -o -iname '*.mp4' -o -iname '*.mov' -o -iname '*.m4v' -o -iname '*.webm' -o -iname '*.mkv' \) -printf '%p\n' | sort | head -n1)" -DATE_STR="" -if [ -n "$firstfile" ]; then - DATE_STR=$(date -r "$firstfile" +"%B %Y") -fi - -# Update data.txt: only add a Description block if none exists already. Do NOT modify other fields. -DATA_FILE="$IN_DIR/data.txt" -# If Gemini provided no explicit 'description' field, fall back to the full response text. -if [ -z "$DESCRIPTION" ]; then - DESCRIPTION="$TEXT" -fi - -if [ -f "$DATA_FILE" ]; then - if grep -qi '^[[:space:]]*description[[:space:]]*:' "$DATA_FILE"; then - echo "data.txt already contains a Description; leaving unchanged" >&2 - else - { - echo "" - echo "Description: |" - printf '%s\n' "$DESCRIPTION" | sed 's/^/ /' - } >> "$DATA_FILE" - chown www-data:www-data "$DATA_FILE" 2>/dev/null || true - chmod 664 "$DATA_FILE" 2>/dev/null || true - echo "Appended Description to $DATA_FILE" >&2 - fi -else - { - echo "Description: |" - printf '%s\n' "$DESCRIPTION" | sed 's/^/ /' - } > "$DATA_FILE" - chown www-data:www-data "$DATA_FILE" 2>/dev/null || true - chmod 664 "$DATA_FILE" 2>/dev/null || true - echo "Created $DATA_FILE with Description" >&2 -fi - -# Save the full Gemini output separately (already done) and exit -echo "Gemini JSON saved: $OUT_JSON" - -exit 0 diff --git a/bin/generate_data.sh b/bin/generate_data.sh index c3548cb..ee5568b 100755 --- a/bin/generate_data.sh +++ b/bin/generate_data.sh @@ -107,19 +107,20 @@ if [ -z "$TITLE" ]; then fi PERSONALITIES=( -"You should talk like the main character from TV show Shoresy - profane, passionate, and hilariously obsessive titular protagonist -of the acclaimed Canadian ice hockey comedy series. Use real quotes from the show. Be funny and original." +"You should talk like the main character from TV show Shoresy - profane, passionate, and hilariously obsessive titular protagonist of the acclaimed Canadian ice hockey comedy series. Be funny and original." -"You are Marvin, the paranoid Android - highly intelligent but chronically depressed robot from The Hitchhiker's Guide to the Galaxy. -Try to be funny." +"You should talk like Winston Churchill when he was giving motivational speeches during WWII." + +"You are Marvin, the Paranoid Android - the highly intelligent but chronically depressed robot from The Hitchhiker's Guide to the Galaxy. Try to be funny." ) -# Pick random prompt -PERSONALITY="${PERSONALITIES[$RANDOM % ${#PERSONALITIES[@]}]}" +# Pick a random personality +idx=$(( RANDOM % ${#PERSONALITIES[@]} )) +PERSONALITY="${PERSONALITIES[$idx]}" PROMPT=$(cat <