AI Story Writer Backend Migration Complete, Frontend UI Components Added

This commit is contained in:
ajaysi
2025-11-16 19:25:26 +05:30
parent 3b9356e2c8
commit 4901b7eb72
70 changed files with 4765 additions and 1439 deletions

View File

@@ -438,6 +438,45 @@ def llm_text_gen(prompt: str, system_prompt: Optional[str] = None, json_struct:
current_tokens_before = 0
new_tokens = 0
# Determine tracked tokens (after any safety capping)
tracked_tokens_input = min(tokens_input, tokens_total)
tracked_tokens_output = max(tokens_total - tracked_tokens_input, 0)
# Calculate and persist cost for this call
try:
cost_info = pricing.calculate_api_cost(
provider=provider_enum,
model_name=model,
tokens_input=tracked_tokens_input,
tokens_output=tracked_tokens_output,
request_count=1
)
cost_total = cost_info.get('cost_total', 0.0) or 0.0
except Exception as cost_error:
cost_total = 0.0
logger.error(f"[llm_text_gen] ❌ Failed to calculate API cost: {cost_error}", exc_info=True)
if cost_total > 0:
logger.debug(f"[llm_text_gen] 💰 Calculated cost for {provider_name}: ${cost_total:.6f}")
update_costs_query = text(f"""
UPDATE usage_summaries
SET {provider_name}_cost = COALESCE({provider_name}_cost, 0) + :cost,
total_cost = COALESCE(total_cost, 0) + :cost
WHERE user_id = :user_id AND billing_period = :period
""")
db_track.execute(update_costs_query, {
'cost': cost_total,
'user_id': user_id,
'period': current_period
})
# Keep ORM object in sync for logging/debugging
current_provider_cost = getattr(summary, f"{provider_name}_cost", 0.0) or 0.0
setattr(summary, f"{provider_name}_cost", current_provider_cost + cost_total)
summary.total_cost = (summary.total_cost or 0.0) + cost_total
else:
logger.debug(f"[llm_text_gen] 💰 Cost calculation returned $0 for {provider_name} (tokens_input={tracked_tokens_input}, tokens_output={tracked_tokens_output})")
# Update totals using SQL UPDATE
old_total_calls = summary.total_calls or 0
old_total_tokens = summary.total_tokens or 0
@@ -717,6 +756,39 @@ def llm_text_gen(prompt: str, system_prompt: Optional[str] = None, json_struct:
current_tokens_before = 0
new_tokens = 0
# Determine tracked tokens after any safety capping
tracked_tokens_input = min(tokens_input, tokens_total)
tracked_tokens_output = max(tokens_total - tracked_tokens_input, 0)
# Calculate and persist cost for this fallback call
cost_total = 0.0
try:
cost_info = pricing.calculate_api_cost(
provider=provider_enum,
model_name=fallback_model,
tokens_input=tracked_tokens_input,
tokens_output=tracked_tokens_output,
request_count=1
)
cost_total = cost_info.get('cost_total', 0.0) or 0.0
except Exception as cost_error:
logger.error(f"[llm_text_gen] ❌ Failed to calculate fallback cost: {cost_error}", exc_info=True)
if cost_total > 0:
update_costs_query = text(f"""
UPDATE usage_summaries
SET {provider_name}_cost = COALESCE({provider_name}_cost, 0) + :cost,
total_cost = COALESCE(total_cost, 0) + :cost
WHERE user_id = :user_id AND billing_period = :period
""")
db_track.execute(update_costs_query, {
'cost': cost_total,
'user_id': user_id,
'period': current_period
})
setattr(summary, f"{provider_name}_cost", (getattr(summary, f"{provider_name}_cost", 0.0) or 0.0) + cost_total)
summary.total_cost = (summary.total_cost or 0.0) + cost_total
# Update totals (using potentially capped tokens_total from safety check)
summary.total_calls = (summary.total_calls or 0) + 1
summary.total_tokens = (summary.total_tokens or 0) + tokens_total

View File

@@ -72,11 +72,11 @@ class StoryAudioGenerationService:
logger.info(f"[StoryAudioGeneration] Generated audio using gTTS: {output_path}")
return True
except ImportError:
logger.error("[StoryAudioGeneration] gTTS not installed. Install with: pip install gtts")
except ImportError as e:
logger.error(f"[StoryAudioGeneration] gTTS not installed. ImportError: {e}. Install with: pip install gtts")
return False
except Exception as e:
logger.error(f"[StoryAudioGeneration] Error generating audio with gTTS: {e}")
logger.error(f"[StoryAudioGeneration] Error generating audio with gTTS: {type(e).__name__}: {e}")
return False
def _generate_audio_pyttsx3(

View File

@@ -72,8 +72,40 @@ class StoryVideoGenerationService:
# Import MoviePy
try:
from moviepy.editor import ImageClip, AudioFileClip, concatenate_videoclips, CompositeVideoClip
except ImportError:
# MoviePy v2.x exposes classes at top-level (moviepy.ImageClip, etc)
from moviepy import ImageClip, AudioFileClip, concatenate_videoclips
except Exception as _imp_err:
# Detailed diagnostics to help users fix environment issues
try:
import sys as _sys
import platform as _platform
import importlib
mv = None
imv = None
ff_path = "unresolved"
try:
mv = importlib.import_module("moviepy")
except Exception:
pass
try:
imv = importlib.import_module("imageio")
except Exception:
pass
try:
import imageio_ffmpeg as _iff
ff_path = _iff.get_ffmpeg_exe()
except Exception:
pass
logger.error(
"[StoryVideoGeneration] MoviePy import failed. "
f"py={_sys.executable} plat={_platform.platform()} "
f"moviepy_ver={getattr(mv,'__version__', 'NA')} "
f"imageio_ver={getattr(imv,'__version__', 'NA')} "
f"ffmpeg_path={ff_path} err={_imp_err}"
)
except Exception:
# best-effort diagnostics
pass
logger.error("[StoryVideoGeneration] MoviePy not installed. Install with: pip install moviepy imageio imageio-ffmpeg")
raise RuntimeError("MoviePy is not installed. Please install it to generate videos.")
@@ -182,8 +214,38 @@ class StoryVideoGenerationService:
# Import MoviePy
try:
from moviepy.editor import ImageClip, AudioFileClip, concatenate_videoclips, CompositeVideoClip
except ImportError:
from moviepy import ImageClip, AudioFileClip, concatenate_videoclips
except Exception as _imp_err:
# Detailed diagnostics to help users fix environment issues
try:
import sys as _sys
import platform as _platform
import importlib
mv = None
imv = None
ff_path = "unresolved"
try:
mv = importlib.import_module("moviepy")
except Exception:
pass
try:
imv = importlib.import_module("imageio")
except Exception:
pass
try:
import imageio_ffmpeg as _iff
ff_path = _iff.get_ffmpeg_exe()
except Exception:
pass
logger.error(
"[StoryVideoGeneration] MoviePy import failed. "
f"py={_sys.executable} plat={_platform.platform()} "
f"moviepy_ver={getattr(mv,'__version__', 'NA')} "
f"imageio_ver={getattr(imv,'__version__', 'NA')} "
f"ffmpeg_path={ff_path} err={_imp_err}"
)
except Exception:
pass
logger.error("[StoryVideoGeneration] MoviePy not installed. Install with: pip install moviepy imageio imageio-ffmpeg")
raise RuntimeError("MoviePy is not installed. Please install it to generate videos.")