Download button now redirects to backend endpoint that generates
GCS signed URLs with Content-Disposition: attachment header,
forcing browser download instead of opening in new tab.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Handle both old (audio_path) and new (audio_blob_path) keys in create_video
task to support tasks that were queued before the GCS migration deployed.
Also properly detect local vs GCS paths for photo_path.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add google-cloud-storage dependency to requirements.txt
- Add GCS configuration settings to config.py
- Create storage.py utility module with upload/download/delete operations
and temp file context managers for video generation
- Update submissions.py to upload photos to GCS and return full GCS URLs
- Update results.py to return full GCS URLs for video and record image
- Update workers.py to use GCS for audio download, video creation, and cleanup
- Update result.js to use audio_url directly from API response
- Update docker-compose.yml with GCS credentials mount
Storage now uses GCS bucket vday2026 in project holiday-project-india.
Database stores blob paths; URLs constructed at API response time.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds server-side image safety check to ensure users upload pet photos instead
of human images. Uses NudeNet with 0.5 confidence threshold and fail-open
behavior. Frontend shows loading state during analysis and error UI when
humans are detected.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add profanity detection using better-profanity library with:
- Real-time API validation during typing (500ms debounce)
- Defense-in-depth server-side validation on form submission
- Visual feedback with red borders and warning message
- Submit button disabled when profanity detected
- Fail-open behavior on API errors to not block users
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Allows frontend to access the MP3 audio URL as soon as download
completes, even while video generation is still in progress.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove process_pending_queue and check_credits scheduled tasks
- Add check_submission_timeout task for per-submission timeout handling
- Modify send_to_sonauto to schedule timeout check after successful API call
- Reduce check_timeouts frequency to 30min (safety net only)
- Update submissions endpoint to use apply_async with better error logging
- Remove unused config settings (QUEUE_PROCESSOR_INTERVAL, CREDITS_CHECK_INTERVAL)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Route create_video task to dedicated 'video' queue with concurrency=2.
Default worker now has concurrency=10 for all other tasks.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change frame format from PNG to JPEG (quality 85) for faster encoding
- Use mjpeg input codec instead of png for FFmpeg
- Change preset from 'faster' to 'superfast' for quicker encoding
Trade-off: ~20-30% larger file size for significantly faster generation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add composite PNG generation (vinyl record + pet photo with transparent
background, no needle) saved to storage/images/. The results API now
returns record_image_url pointing to the composite or default-record.png
for submissions without a user photo.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Users can now submit the form without uploading a photo. When no photo is
provided, the video will display the default "Pet Love Songs" record instead
of a pet image in the vinyl center.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Triggers send_to_sonauto.delay() right after creating a submission,
eliminating up to 60 seconds of wait time. The periodic task remains
as a fallback for edge cases (Celery unavailable, immediate dispatch fails).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace communicate() with stderr.read() + wait() after manually
closing stdin. communicate() tries to flush stdin internally which
fails when stdin is already closed.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace backend proxy streaming endpoint with direct access to
Sonauto's public streaming URL (api-stream.sonauto.ai). This
simplifies the architecture and reduces latency.
- Update waiting.php to use task_id from status API response
- Add autoplay attribute to audio element per Sonauto docs
- Remove stream.py proxy router (no longer needed)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add restriction to prevent potentially inappropriate double-meaning
words from appearing in generated song lyrics: pussy, cock, beaver,
bitch, ass, tit, tits, puppies, trouser snake.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace the generic song generation prompt with pet-specific prompt
templates. Each pet type (Dog, Cat, Fish, Bird, Hamster, Gerbil,
Guinea Pig, Rabbit, Bearded Dragon, Leopard Gecko, Corn Snake) now
has its own tailored prompt with pet-specific behaviors and content
restrictions.
Also fix typo: "Beared Dragon" → "Bearded Dragon" in schemas.py and
home.js. The prompts.py file includes backwards compatibility for the
old spelling to handle any pending database records.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The queue-status endpoint now fetches credits from the Sonauto API
when the Redis cache is empty/zero, making the admin dashboard
more reliable.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sonauto rejects custom tag values. The prompt already contains all
necessary style and content guidance, so tags are not needed.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sonauto only accepts specific predefined tags. The custom frontend
music vibes (Hip-Hop, Boy Band, etc.) were being rejected with 422.
Now using fixed tags ["love song", "valentine"] and including the
music vibe in the prompt text instead.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Stream endpoint:
- Increase read timeout to 600s for progressive audio generation
- Use larger 16KB chunks for smoother playback
- Remove misleading Accept-Ranges header (we don't support range requests)
- Add logging for stream start/completion
- Properly close httpx client after streaming
Frontend:
- Wait for 'canplay' event before attempting autoplay
- Add event listeners for play, error, stalled, waiting
- Native audio controls' play button now properly hides tap message
- Add 5s fallback timeout if canplay doesn't fire
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Frontend was updated in 1b26b7a but backend validation wasn't updated,
causing 422 errors on form submission.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Enable users to listen to their song while video generation continues
in the background. Backend proxies authenticated Sonauto stream API
since HTML audio elements cannot send auth headers.
- Add streaming_ready_at column to track when stream becomes available
- Enable streaming in Sonauto API request payload
- Handle GENERATING_STREAMING_READY webhook status
- Add /api/stream/{session_id} proxy endpoint using httpx
- Update StatusResponse with streaming_ready and task_id fields
- Add audio player UI with autoplay fallback for mobile
- Fade out audio gracefully before redirect to result page
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use wait() instead of communicate() after manually closing stdin.
communicate() tries to flush stdin which fails if already closed.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Only use the music_vibe as the tag - "love song" and "valentine"
are not valid Sonauto API tags.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Python/FastAPI backend with Celery workers
- Add video generation with FFmpeg (spinning record animation)
- Add API endpoints: submissions, status polling, webhook, results
- Add database schema and Alembic migrations
- Update frontend pages with API integration
- Add project documentation and spec
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>