# core/views_tts.py from django.contrib.auth.decorators import login_required, user_passes_test from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden from django.shortcuts import get_object_or_404 from django.views.decorators.http import require_GET from .models import Entry # If you use the OpenAI SDK: from openai import OpenAI import os client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY", "")) def _is_staff(user): return user.is_authenticated and (user.is_staff or user.is_superuser) @login_required @user_passes_test(_is_staff) @require_GET def api_tts_for_entry(request, entry_id): """ Generate MP3 speech for an entry (staff‑only). """ entry = get_object_or_404(Entry, pk=entry_id) # ---- Build safe combined text (avoid TypeError) ---- ill = (entry.illustration or "").strip() app = (entry.application or "").strip() if ill and not any(ill.endswith(p) for p in ".!?…"): ill = ill + "." combined = " ".join([t for t in (ill, app) if t]).strip() if not combined: return HttpResponseBadRequest("No text available for this entry.") # ---- Call OpenAI TTS (MP3) ---- try: # Use the streaming helper for broad SDK compatibility. # It yields MP3 audio bytes by default. with client.audio.speech.with_streaming_response.create( model="gpt-4o-mini-tts", voice="alloy", # or another supported voice input=combined, ) as resp: audio_bytes = resp.read() # raw MP3 bytes except Exception as e: return HttpResponse(f"OpenAI TTS failed: {e}", status=500, content_type="text/plain") # ---- Serve as audio/mpeg ---- resp = HttpResponse(audio_bytes, content_type="audio/mpeg") resp["Content-Disposition"] = 'inline; filename="entry-tts.mp3"' resp["Cache-Control"] = "no-store" return resp