+
    oi                      R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIH	t	 ^ RI
Ht ^ RIHtHtHtHt ^ RIHt ^ RIHtHtHtHt ^ RIHt ]! ]4      P7                  4       P8                  P8                  t]! ]4      ]P>                  9  d#   ]P>                  PA                  ^ ]! ]4      4       ^ R	I!H"t"H#t# ^ R
I$H%t%H&t& ^ RI'H(t(H)t) ^ RI*H+t+ ^ RI,H-t-H.t.H/t/H0t0H1t1H2t2H3t3H4t4H5t5H6t6H7t7H8t8H9t9H:t:H;t;H<t=H>t>H?t?H@t@HAtAHBtBHCtCHDtDHEtEHFtFHGtGHHtHHItIHJtJHKtKHLtL ]P                  ! ]N4      tO]! ]4      P7                  4       P8                  tP]PR,          tQR R ltR]	R R l4       tS]! RR]SR7      tT]TP                  ]R.RR.R.R7       ]TP                  R]! ]! ]Q4      R7      RR7       ]R,          tW]WP                  RRR7       ]TP                  R]! ]! ]W4      R7      RR7       ]TP                  R4      R  4       tZ]TP                  R!4      R" 4       t[]TP                  R#4      R$ 4       t\]TP                  R%4      R& 4       t]]TP                  R'4      R( R) l4       t^]TP                  R%4      R* R+ l4       t`]TP                  R'4      R, R- l4       tb]TP                  R'4      R. R/ l4       td]TP                  R04      R1 R2 l4       te]TP                  R34      R4 R5 l4       tfR6 R7 ltg]TP                  R84      R9 4       th]TP                  R84      R: R; l4       ti]TP                  R<4      RR= R> ll4       tj]TP                  R?4      R@ 4       tk]TP                  R?4      RA RB l4       tl]TP                  RC4      RD 4       tm]TP                  RE4      RF 4       tn]TP                  RE4      RG RH l4       to]TP                  RI4      RJ RK l4       tp]TP                  RL4      RM RN l4       tq]TP                  RO4      RP 4       tr]TP                  RQ4      RR RS l4       ts]TP                  RT4      RU 4       tt]TP                  RV4      RW RX l4       tu]TP                  RY4      RZ R[ l4       tv]TP                  R\4      R] R^ l4       tw]TP                  R_4      R` Ra l4       tx]TP                  Rb4      Rc 4       ty]TP                  Rd4      Re 4       tz]TP                  Rd4      Rf Rg l4       t{]TP                  Rh4      Ri Rj l4       t}]TP                  Rk4      Rl 4       t~]TP                  Rm4      Rn 4       t]TP                  Ro4      Rp Rq l4       t]TP                  Ro4      Rr Rs l4       t]TP                  Rt4      Ru Rv l4       t]TP                  Rw4      Rx Ry l4       t]TP                  Rz4      R{ R| l4       t]TP                  R}4      R~ R l4       t]TP                  R4      R R l4       t]TP                  R4      R R l4       t]TP                  R4      R R l4       t]TP                  R4      R R l4       t]TP                  R4      R R l4       t]TP                  R4      R R l4       t]TP                  R4      R R l4       t]TP                  R4      R R l4       t]TP                  R4      R R l4       t]TP                  R4      R R l4       t]TP                  R4      R R l4       t]TEP#                  R4      R R l4       tR# )z
FastAPI application for the Video Production Pipeline web interface.

Provides REST endpoints for configuration and a WebSocket endpoint
for real-time pipeline execution with event streaming.
Persistent SQLite storage via web/database.py.
)annotationsN)asynccontextmanagerPath)FastAPIRequest	WebSocketWebSocketDisconnect)CORSMiddleware)FileResponseJSONResponseResponseStreamingResponse)StaticFiles)build_configlist_available_templates)PipelineEventPipelineMode)	save_jsonsave_markdown)Pipeline)character_countclose_dbdelete_characterdelete_grok_accountdelete_imagedelete_projectget_characterget_character_by_nameget_next_grok_accountget_projectget_project_imagesget_project_videosget_project_audiosget_settingset_settingget_all_settingsinit_dbinsert_characterinsert_grok_accountinsert_projectlist_characterslist_grok_accountslist_projectsupdate_characterupdate_image_pathupdate_image_statusupdate_project_resultupdate_project_statusupsert_imageupsert_videoupsert_audiostaticc                   V ^8  d   QhRR/#    returnNone )formats   "
web/app.py__annotate__r?   R   s      N  N$  N    c                   "   ^ RI p \        4       G Rj  xL
 pV^ 8  d   R# \        R,          pVP                  4       '       g   R# \	        VP                  R4      4       EFK  p ^ RIpVP                  VP                  RR7      4      p\        \        V P                  4       4      VP                  RVP                  4      VP                  RR4      VP                  R	. 4      VP                  R
. 4      VP                  R. 4      VP                  RR4      VP                  RR4      VP                  RR4      VP                  RR4      VP                  RR4      VP                  RR4      RR7      G Rj  xL
  \        P                  RVP                  RVP                  4      4       EKN  	  R#  EL L>  \          d#   p\        P#                  RY64        Rp?EK  Rp?ii ; i5i)z8Seed character DB from JSON templates if table is empty.Ncharacter_templatesz*.jsonutf-8)encodingnamephysical_description style_keywordsnegative_keywordshard_prohibitionscamera_settingslighting_settings	pose_ruleenvironment_ruleclothing_ruleanatomical_highlight_rulesT)idrE   rF   rH   rI   rJ   rK   rL   rM   rN   rO   rP   
is_defaultzSeeded character: %sz$Failed to seed character from %s: %s)uuidr   _PROJECT_ROOTexistssortedglobjsonloads	read_textr(   struuid4getstemloggerinfo	Exceptionwarning)rS   counttemplates_dirpath_jsondataexcs          r>   _seed_characters_from_jsonri   R   s    !##Eqy!$99M!!}))(34	N ;;t~~w~?@D"tzz|$XXfdii0%)XX.Db%I#xx(8"="&((+>"C"&((+>"C $):B ?"&((+>"C((;3!%*<b!A"hh;+/884PRT+U   KK.0KL) 5 $   	NNNA4MM	NsR   G(F3/G( G(&DF87F684F8,G(6F88G%G G( G%%G(c                   V ^8  d   QhRR/# )r9   appr   r<   )r=   s   "r>   r?   r?   v   s       r@   c                  "   \        4       G Rj  xL
  \        4       G Rj  xL
  R5x  \        4       G Rj  xL
  R#  L/ L L
5i)zDModern lifespan context manager replacing on_event startup/shutdown.N)r'   ri   r   )rk   s   &r>   lifespanrm   u   s7      )OO
$
&&&	
*	 & s/   AA AAAAAAAzVideo Production Pipelinez2.0.0)titleversionrm   *T)allow_originsallow_credentialsallow_methodsallow_headersz/static)	directory)rE   outputparentsexist_okz/output/c                 H   "   \        \        \        R ,          4      4      # 5i)z
index.html)r   r[   _STATIC_DIRr<   r@   r>   indexr}      s     K,6788s    "z/healthc                    "   RRRR/# 5i)z!Health check endpoint for Docker.statushealthydatabase
postgresqlr<   r<   r@   r>   health_checkr      s      i\::s   	z/api/templatesc                 p   "   \        4       G Rj  xL
 p RV  Uu. uF  qR,          NK  	  up/#  Lu upi 5i)zEList available character templates (legacy, redirects to characters).N	templatesrE   r+   )charscs     r>   get_templatesr      s8      "##EU3UF))U344 $3s   6/	6166z/api/charactersc                 :   "   \        4       G Rj  xL
 p RV /#  L5i)z"List all characters with metadata.N
charactersr   )r   s    r>   api_list_charactersr      s"      "##E%   $   	z/api/characters/{char_id}c                   V ^8  d   QhRR/# r9   char_idr[   r<   )r=   s   "r>   r?   r?      s      S r@   c                ^   "   \        V 4      G Rj  xL
 pVf   \        RR/RR7      # V#  L5i)zGet a single character by ID.NerrorCharacter not found  status_code)r   r   )r   chars   & r>   api_get_characterr      s6      w''D|W&;<#NNK (s   -+-c                   V ^8  d   QhRR/# r9   requestr   r<   )r=   s   "r>   r?   r?      s     $/ $/ $/r@   c                R  "   ^ RI p V P                  4       G Rj  xL
 pTP	                  RR4      P                  4       pT'       g   \        RR/RR7      # \        T4      G Rj  xL
 pT'       d   \        RR	T R
2/RR7      # \        TP                  4       4      p\        TTTP	                  RR4      TP	                  R. 4      TP	                  R. 4      TP	                  R. 4      TP	                  RR4      TP	                  RR4      TP	                  RR4      TP	                  RR4      TP	                  RR4      TP	                  RR4      R7      G Rj  xL
  \        T4      G Rj  xL
 p\        T^R7      #  ELb  \         d    \        RR/RR7      u # i ; i EL; LJ L95i)zCreate a new character.Nr   Invalid JSON  r   rE   rG   zName is requiredzCharacter 'z' already exists  rF   rH   rI   rJ   rK   rL   rM   rN   rO   rP   )rQ   rE   rF   rH   rI   rJ   rK   rL   rM   rN   rO   rP   )rS   rX   ra   r   r]   stripr   r[   r\   r(   r   )r   rS   bodyrE   existingr   r   s   &      r>   api_create_characterr      s     H\\^# 88FB%%'DW&89sKK*400HD6)9:;
 	
 $**,G
!XX&<bAxx 0"5((#6;((#6;!2B7((#6;((;+"4b9hh3#'88,H"#M   w''D#..? $ HWn53GGH 1 (st   F'F  E=F  'F'F'%F &F'2C&F'F#F'+F%,F'=F   FF'FF'#F'%F'c                    V ^8  d   QhRRRR/# )r9   r   r[   r   r   r<   )r=   s   "r>   r?   r?      s     #( #( #(g #(r@   c                L  "   \        V 4      G Rj  xL
 pVf   \        RR/RR7      #  VP                  4       G Rj  xL
 p0 RmpTP	                  4        UUu/ uF  w  rVYT9   g   K  YVbK  	  pppT'       g   \        RR	/RR7      # RT9   d@   \        TR,          4      G Rj  xL
 pT'       d   TR
,          T 8w  d   \        RR/RR7      # \        Y4      G Rj  xL
  \        T 4      G Rj  xL
 #  L L  \         d    \        RR/RR7      u # i ; iu uppi  Ly LC L25i)z(Update individual fields of a character.Nr   r   r   r   r   r   rE   zNo valid fields to updaterQ   zName already takenr   >   rE   rM   rO   rH   rK   rN   rJ   rL   rI   rF   rP   )r   r   rX   ra   itemsr   r.   )	r   r   r   r   allowedkvupdatesr   s	   &&       r>   api_update_characterr      s     w''D|W&;<#NNH\\^#G !%

=tqtG=W&ABPSTT .wv??'1*> ?SQQ
7
,,,w'''C (
 $ HWn53GGH  > @ -'s   D$C4D$C8 C6C8 D$
D(D.6D$$D%D$1+D$D D$/D"0D$6C8 8DD$D
D$ D$"D$c                   V ^8  d   QhRR/# r   r<   )r=   s   "r>   r?   r?     s     0 0 0r@   c                2  "   \        V 4      G Rj  xL
 pVf   \        RR/RR7      # VP                  R4      '       d;   \        VR,          4      pVP	                  4       '       d   VP                  RR7       \        V 4      G Rj  xL
  R	R
RV /#  L L5i)zDelete a character.Nr   r   r   r   thumbnail_pathT)
missing_okr   deletedrQ   )r   r   r]   r   rU   unlinkr   )r   r   thumbs   &  r>   api_delete_characterr     s      w''D|W&;<#NNxx !!T*+,<<>>LLDL)
7
###iw// ( $s(   BB-B ABB	BBz,/api/characters/{char_id}/generate-thumbnailc                   V ^8  d   QhRR/# r   r<   )r=   s   "r>   r?   r?   #  s     +U +U# +Ur@   c                  aa"   \        V 4      G Rj  xL
 pVf   \        RR/RR7      # VP                  RR4      pV'       g   \        RR/R	R7      # R
P                  VP                  R. 4      4      pRV RV R2o\        R,          R,          pVP                  RRR7       W@ R2,          o VV3R lp\        P                  ! V4      G Rj  xL
  \        V R\        S4      /4      G Rj  xL
  RRRRV  R2RV /#  L L1 L  \         d3   p\        P                  RT 4       \        RRT 2/RR7      u Rp?# Rp?ii ; i5i)z3Generate a thumbnail preview image for a character.Nr   r   r   r   rF   rG   z(No physical description to generate fromr   z, rH   zgPortrait shot, neutral standing pose, studio lighting, dark gradient background, centered composition,  z9. Photorealistic, 8K, sharp focus, no text, no watermark.rg   
thumbnailsTrw   .pngc                    < ^ RI Hp  V ! 4       ;_uu_ 4       pVP                  SS4       RRR4       R#   + '       g   i     R# ; i)    )GoogleFlowImageProviderN)providers.google_flow_providerr   generate)r   provprompt
thumb_paths     r>   _gen$api_generate_thumbnail.<locals>._gen=  s.    N(**dfj1 +***s	   4A	r   r   	generatedthumbnail_urlz/api/characters/z
/thumbnailr   z,Thumbnail generation failed for character %szGeneration failed:   )r   r   r]   joinrT   mkdirasyncio	to_threadr.   r[   ra   r_   	exception)	r   r   physstyle_kw	thumb_dirr   rh   r   r   s	   &      @@r>   api_generate_thumbnailr   "  st     w''D|W&;<#NN88*B/D@As
 	
 yy"2B78H!!%a* B	C  &5IOOD4O0y--JU	2 %%%w)93z?(KLLL k/y
Cw
 	
E (< 	&L  UGQW(;C5&ABPSTTUsj   ED0EA+E1 D DD 0D1D  ED D E'D?9E:E?EEz#/api/characters/{char_id}/thumbnailc                   V ^8  d   QhRR/# r   r<   )r=   s   "r>   r?   r?   R  s     ) )s )r@   c                  "   \        V 4      G Rj  xL
 pVf   \        RR/RR7      # VP                  RR4      pV'       d    \        V4      P	                  4       '       g   \        RR/RR7      # \        \        V4      4      #  Ls5i)	z$Serve a character's thumbnail image.Nr   r   r   r   r   rG   zNo thumbnail available)r   r   r]   r   rU   r   r[   )r   r   r   s   &  r>   api_serve_thumbnailr   Q  sz      w''D|W&;<#NN*B/JT*-4466W&>?SQQJ(( (s   BB0BABc                    V ^8  d   QhRRRR/# )r9   r   zdict[str, str]r:   r;   r<   )r=   s   "r>   r?   r?   b  s      n  r@   c                   \         R,          pVP                  4       '       d   VP                  4       MRp\        4       p. pVP	                  4        Fk  pRV9   d   VP                  R^4      ^ ,          MRpW`9   d0   VP                  V RW,           24       VP                  V4       KZ  VP                  V4       Km  	  V P                  4        F#  w  rxWs9  g   K  VP                  V RV 24       K%  	  VP                  RP                  V4      R,           4       V P                  4        F  w  rxV\        P                  V&   K  	  R# )z8Update keys in the .env file and in the running process..envrG   =
N)rT   rU   rZ   set
splitlinessplitappendaddr   
write_textr   osenviron)	r   env_pathcontentfound	new_lineslinekeyr   r   s	   &        r>   _update_env_keysr   b  s   v%H&.oo&7&7h  "RGEEI""$'*d{djja #>uAgl^45IIcNT" % >s!A3Z(   		),t34

1  r@   z/api/settings/llmc                 d  "   \        4       G Rj  xL
 p V P                  R4      ;'       g!    \        P                  P                  RR4      pVP	                  R^4      p\        V4      ^8X  d
   V^ ,          MRp\        V4      ^8X  d
   V^,          MV^ ,          pV P                  R4      ;'       g!    \        P                  P                  RR	4      pV P                  R
4      ;'       g!    \        P                  P                  RR	4      pRVRVRVR\        V4      R\        V4      /#  EL5i)z3Return current LLM provider, model, and key status.N	llm_model	LLM_MODELopenai/gpt-4orz   openaiopenai_api_keyOPENAI_API_KEYrG   anthropic_api_keyANTHROPIC_API_KEYprovidermodelhas_openai_keyhas_anthropic_key)db_get_all_settingsr]   r   r   r   lenbool)db_settingsr   partsr   r   
openai_keyanthropic_keys          r>   get_llm_settingsr   |  s      ,--K,\\

{O0\IOOC#Eu:?uQxHE
aE!HU1XE!12ZZbjjnnEUWY6ZJOO$78ccBJJNNK^`b<cM 	HY$z*T-0  .s"   D0D-D0BD058D0.A D0c                   V ^8  d   QhRR/# r   r<   )r=   s   "r>   r?   r?     s     '; ';w ';r@   c                f  "    V P                  4       G Rj  xL
 pTP                  RR4      P	                  4       pTP                  RR4      P	                  4       pTP                  R	R4      P	                  4       pTR9  d   \        RR/RR7      # T'       dY   TR
8X  d*   \        RTR4      G Rj  xL
  T\        P                  R&   M(\        RTR4      G Rj  xL
  T\        P                  R&   T'       d	   T RT 2pMvT'       dm   \        4       G Rj  xL
 pTP                  R4      ;'       g!    \        P                  P                  RR4      pTP                  R^4      R,          pT RT 2pMRpT'       d)   \        RTR4      G Rj  xL
  T\        P                  R&   T;'       gJ    \        4       G Rj  xL
 P                  R4      ;'       g!    \        P                  P                  RR4      p	RRRT	/#  EL  \         d    \        RR/RR7      u # i ; i ELs ELM EL L Lo5i)z(Update LLM provider, API key, and model.Nr   r   r   r   r   rG   api_keyr   r   z(Provider must be 'openai' or 'anthropic'r   OpenAI API keyr   r   Anthropic API keyr   rz   r   r   r   LLM model identifierr   updated)r   	anthropic)
rX   ra   r   r]   r   r%   r   r   r   r   )
r   r   r   r   r   r   r   currentcurrent_modelfinal_models
   &         r>   update_llm_settingsr    s    H\\^# xx
B'--/Hhhy"%++-GHHWb!'')E..@As
 	
 x.9IJJJ+2BJJ'(17<OPPP.5BJJ*+j%)		/11//+.^^"**..o2^c1-b1j-1		+y2HIII"+

;pp&9&; ;@@MppQSQ[Q[Q_Q_`kmoQpKik::I $ HWn53GGH K Q 2 	J !<s   H1H HH A=H1H11H$2(H1H'H1:H1
H1H*H14AH1 H1H-H11H1?H/ H1'H1H H!H1 H!!H1'H1*H1-H1/H1z/api/settings/llm/modelsc                   V ^8  d   QhRR/# )r9   r   r[   r<   )r=   s   "r>   r?   r?     s     BH BHC BHr@   c                X  aa"   V R8X  Ed   \        4       G Rj  xL
 pVP                  R4      ;'       g!    \        P                  P                  RR4      oS'       g   \	        RR/RR	7      #  ^ RIo\        P                  ! VV3R
 l4      G Rj  xL
 pVP                  ^8w  d   \	        RRVP                   2/RR	7      # VP                  4       p\        VP                  R. 4       Uu. uF  pRVR,          9   g   K  VR,          NK  	  upRR7      pRRRV/# V R8X  Ed   \        4       G Rj  xL
 pVP                  R4      ;'       g!    \        P                  P                  RR4      oS'       g   \	        RR/RR	7      #  ^ RIo\        P                  ! VV3R l4      G Rj  xL
 pVP                  ^8w  d   \	        RRVP                   2/RR	7      # VP                  4       p\        VP                  R. 4       Uu. uF  qDR,          NK  	  upRR7      pRRRV/# \	        RR/RR	7      #  EL ELu upi   \         d#   p\	        R\        T4      /RR	7      u Rp?# Rp?ii ; i EL= Lu upi   \         d#   p\	        R\        T4      /RR	7      u Rp?# Rp?ii ; i5i)z2Fetch available models from the selected provider.r   Nr   r   rG   r   zOPENAI_API_KEY not configuredr   r   c                 6   < SP                  R RRS  2/^R7      # )z https://api.openai.com/v1/modelsAuthorizationBearer headerstimeoutr]   r   httpxs   r>   <lambda>!list_llm_models.<locals>.<lambda>  s(    		6,y.AB " r@   zOpenAI API error: i  rg   gptrQ   T)reverser   modelsr   r  r   r   z ANTHROPIC_API_KEY not configuredc                 4   < SP                  R RS RR/^R7      # )z#https://api.anthropic.com/v1/modelsz	x-api-keyzanthropic-versionz
2023-06-01r  r  r  s   r>   r  r    s*    		9#W+\  " r@   zAnthropic API error: zUnknown provider)r   r]   r   r   r   r  r   r   r   rX   rV   ra   r[   )	r   r   resrg   mr  rh   r   r  s	   &      @@r>   list_llm_modelsr    s     8/11//"23[[rzz~~FVXZ7[9: 	F)) C #%# 23??2CDESV  88:D"&((62"6K"6Q%1T7:J4"6KF (F;; 
[	 /11//"56aa"**..I\^`:a<=3 	F))	 	C #%# 5coo5FGH #  88:D"&((62"67"6Q4"67F Xv>> "453GG 2 L  	F#c( 3EE	F 2	" 8  	F#c( 3EE	Fs   J*H5J*(J* J*0"I  H80I  J*)I  -H;H;I  J*3I04J*(J*9J*	"I: +I3,0I: J*)I: I5I: %J*8I  ;I   I-I("I-#J*(I--J*3I: 5I: :J'J"J'J*"J''J*z/api/settings/cookiesc            
     ^  "   \         R,          p \        P                  P                  RR4      p\        P                  P                  RR4      pR\	        V4      R\	        V4      R\        V4      ^8  d   VR,          R	,           MTR
\        V4      ^8  d   VR,          R	,           /# T/# 5i)z,Check if Google Flow cookies are configured.r   GOOGLE_FLOW_SESSION_TOKENrG   GOOGLE_FLOW_CSRF_TOKENhas_session_tokenhas_csrf_tokensession_token_previewN   N...csrf_token_preview)rT   r   r   r]   r   r   )r   sessioncsrfs      r>   get_cookies_statusr(    s      v%Hjjnn8"=G::>>2B7DT']$t*W9J!5PW3t9r>d3i%/	  HL	 s   B+B-c                   V ^8  d   QhRR/# r   r<   )r=   s   "r>   r?   r?     s     1 1' 1r@   c                T  "    V P                  4       G Rj  xL
 p\        T\        4      '       g   \        RR/RR7      # RpRpT F=  pTP                  RR4      pTP                  R	R4      pTR
8X  d   TpK2  TR8X  g   K;  TpK?  	  T'       g   \        RR/RR7      # T'       g   \        RR/RR7      #  \        RTR4      G Rj  xL
  \        RTR4      G Rj  xL
  \        RRR4      G Rj  xL
  T\        P                  R&   T\        P                  R&   RRRTR,          R,           RTR,          R,           /#  EL)  \         d    \        RR/RR7      u # i ; i L L Lu  \         d2   p\        P                  R4       \        RRT 2/RR7      u Rp?# Rp?ii ; i5i) z<Update Google Flow cookies from browser-exported JSON array.Nr   r   r   r    Expected a JSON array of cookiesrG   rE   valuez __Secure-next-auth.session-tokenz__Host-next-auth.csrf-tokenz;Cookie '__Secure-next-auth.session-token' not found in JSONz6Cookie '__Host-next-auth.csrf-token' not found in JSONgoogle_flow_session_tokenzGoogle Flow session cookiegoogle_flow_csrf_tokenzGoogle Flow CSRF cookieimage_providergoogle_flowActive image providerr  r  z'Failed to save Flow cookies to databaseFailed to save: r   r   r  r!  r"  r$  r%  )rX   ra   r   
isinstancelistr]   r%   r   r   r_   r   )r   r   session_token
csrf_tokencookierE   r,  rh   s   &       r>   update_cookiesr8    s    H\\^# dD!!89s
 	

 MJzz&"%

7B'55!M22J  ST
 	
 NO
 	

	R5}Fbccc2J@YZZZ*M;RSSS2?

.//9

+, 	)s!3e!;jo5 U $ HWn53GGH> 	dZS  RBCW(8&>?SQQRs   F(E E E A!F(F(F('F(7E) E#E) E%E) 1E'2*E) $F( E E F(E  F(#E) %E) 'E) )F%4&F F%F( F%%F(z/api/settings/flow-auto-setupc            
     f  "   \         P                  P                  RR4      p \         P                  P                  RR4      pV '       d	   V'       g   \        RR/RR7      #  ^ RIHp V! W4      G R	j  xL
 pVP                  R4      '       d   \        RR
VR,           2/RR7      # / pVP                  R4      '       d   VR,          VR&   VP                  R4      '       d   VR,          VR&   V'       d   \        V4       RRRVP                  R4      R\        VP                  R4      4      RVP                  R4      '       d   R/# R/#  L  \         d    \        RR/RR7      u # \         d8   p\        P                  R4       \        R\        T4      /RR7      u R	p?# R	p?ii ; i5i)zGUse headless Playwright to auto-extract project_id and reCAPTCHA token.r  rG   r  r   z9Cookies must be configured first (session + CSRF tokens).r   r   )auto_setup_flow_credentialsNzAuto-setup failed: r   
project_idGOOGLE_FLOW_PROJECT_IDrecaptcha_tokenGOOGLE_FLOW_RECAPTCHA_TOKENr   okhas_recaptchamessagez,Flow API credentials extracted successfully!zcCould not extract project_id. Try generating an image manually on labs.google/fx first, then retry.zWPlaywright is not installed. Run: pip install playwright && playwright install chromiumzFlow auto-setup error)r   r   r]   r   providers.flow_token_servicer:  r   r   ImportErrorra   r_   r   r[   )r5  r6  r:  resultr   rh   s         r>   flow_auto_setuprE  J  s     JJNN#>CM 8"=J
QR
 	

(BL2=MM::g/w/@AB 
 ::l##06|0DG,-::'((5;<M5NG12W% d&**\2T&**->"?@::l++ ?	
 		
 {	
 		
# N8  
r 	
 	
  B01Wc#h/SAABs   AF1F1#E 4E5E E (F1)E "E %E 9AE F1E F1E F.+F1-F.6F.7,F)#F.$F1)F..F1z/api/settings/grok-cookiesc                   "   \        4       G Rj  xL
 p RV  Uu. uF  pRVR,          RVR,          RVR,          RVR,          RVR,          RVR,          R	VR	,          '       d   VR	,          P                  4       MRR
VR
,          '       d   VR
,          P                  4       MR/NK  	  upR\        V 4      R\        R V  4       4      /#  Lu upi 5i)z%Check if Grok cookies are configured.NaccountsrQ   labeluser_id	is_activeusage_countdaily_usage_countlast_used_at
created_attotalactivec              3  F   "   T F  qR ,          '       g   K  ^x  K  	  R# 5irJ  Nr<   .0as   & r>   	<genexpr>*get_grok_cookies_status.<locals>.<genexpr>  s     <A{^^aas   !
!)r,   	isoformatr   sum)rG  rU  s     r>   get_grok_cookies_statusrZ    s      ())H 
  ag71Y<Q{^q/#Q':%;>ARAR. 1 ; ; =X\Q|__ao779RV	 
 	X#<<<  *
s-   CC	CA
C%'CC+"CCc                   V ^8  d   QhRR/# r   r<   )r=   s   "r>   r?   r?     s     C Cw Cr@   c                  "    V P                  4       G Rj  xL
 p\        T\        4      '       g   \        RR/RR7      # RpRpRpT FH  pTP                  RR4      pTP                  R	R4      pTR
8X  d   TpK2  TR8X  d   TpK=  TR8X  g   KF  TpKJ  	  T'       g   \        RR/RR7      # T'       g   \        RR/RR7      # T'       g   \        RR/RR7      # RpT F5  pTP                  RR4      R8X  g   K  TP                  R	R4      R,          pK7  	   \        TTTTR7      G Rj  xL
 p	\        RRR4      G Rj  xL
  RRRT	R,          RT	R,          RT/#  ELE  \         d    \        RR/RR7      u # i ; i LT LA  \         d2   p
\        P                  R4       \        RRT
 2/RR7      u Rp
?
# Rp
?
ii ; i5i)z5Update Grok cookies from browser-exported JSON array.Nr   r   r   r   r+  rG   rE   r,  ssosso-rwx-useridzCookie 'sso' not found in JSONz!Cookie 'sso-rw' not found in JSONz#Cookie 'x-userid' not found in JSONr"  )rH  	sso_tokensso_rw_tokenrI  video_providergrokActive video providerz'Failed to save Grok account to databaser2  r   r   added
account_idrQ   rH  rI  )
rX   ra   r   r3  r4  r]   r)   r%   r_   r   )r   r   r`  ra  rI  r7  rE   r,  rH  accountrh   s   &          r>   update_grok_cookiesrh    s    H\\^# dD!!89s
 	

 ILGzz&"%

7B'5=IX LZG  67
 	
 9:
 	
 ;<
 	
 E::fb!Z/JJw+C0E R+%	
 
 *F4KLLL 	'gdm!7	 w $ HWn53GGH\
 	M RBCW(8&>?SQQRs   GE EE A.GGG4G*G:GF *E?+F ?F F GE E<9G;E<<G?F F F?&F:4F?5G:F??Gz'/api/settings/grok-cookies/{account_id}c                   V ^8  d   QhRR/# )r9   rf  intr<   )r=   s   "r>   r?   r?     s     ; ;# ;r@   c                n   "   \        V 4      G Rj  xL
 pV'       g   \        RR/RR7      # RRRV /#  L!5i)	zRemove a Grok account.Nr   zAccount not foundr   r   r   r   rf  )r   r   )rf  r   s   & r>   remove_grok_accountrl    s>      (
33GW&9:LLiz:: 4s   5355z#/api/settings/grok-cookies/validatec                   V ^8  d   QhRR/# r   r<   )r=   s   "r>   r?   r?     s     2B 2B 2Br@   c                  "    V P                  4       G Rj  xL
 pTP                  RR4      P	                  4       pTP                  RR4      P	                  4       pTP                  R	R4      P	                  4       pT'       d	   T'       g   \        RR
/RR7      #  ^ RIpRTRTRT/pTP                  ^
R7      ;_uu_4       GRj  xL
 pTP                  RTR7      G Rj  xL
 pRRR4      GRj  xL
  XP                  ^8X  d	   RRRTRR/# TP                  R9   d   RRRRTP                   R2/# RRRRTP                   R2/#  EL1  \         d    \        RR/RR7      u # i ; i L L L}  + GRj  xL 
 '       g   i     L; i  \         d8   p	\        P                  R4       \        R\        T	4      /RR7      u Rp	?	# Rp	?	ii ; i5i)z7Validate Grok cookies by making a lightweight API call.Nr   r   r   r   r`  rG   ra  rI  z'sso_token and sso_rw_token are requiredr]  r^  r_  r  z,https://grok.com/rest/app-chat/conversations)cookiesvalidTusernamerA  zCookies are validFzAuthentication failed (HTTP )zUnexpected response (HTTP zGrok cookie validation errorr   )  i  )rX   ra   r   r]   r   r  AsyncClientr   r_   r   r[   )
r   r   r`  ra  rI  r  rp  clientresprh   s
   &         r>   validate_grok_cookiesrx    s    H\\^# b)//1I88NB/557Lhhy"%++-GL?@
 	

!B 9l

 $$R$000F> $  D 10 s"G. 
 +9$:J:J9K1M  78H8H7IK Q $ HWn53GGH* 1 1000.  B78Wc#h/SAABs   GE EE A'GGG*F E+F 
E1!E-"E1&F 1E/2F G$F 3G4F GE E(%G'E((G+F -E1/F 1F
	7E:8
F
	F
	F G,G
GG
GGz/api/settings/grok-sessionc                   "   \         P                  P                  RR4      p \         P                  P                  RR4      p\         P                  P                  RR4      p\        WV.4      '       g   \	        RR/RR7      #  ^ R	IHp V! 4       ;_uu_4       GR
j  xL
 pVP                  P                  RR7      G R
j  xL
 pVP                  4       G R
j  xL
 pVP                  RRRV RRRR/RRRVRRRR/RRRVRRRR/.4      G R
j  xL
  VP                  4       G R
j  xL
 pVP                  RRR7      G R
j  xL
  VP                  R4      G R
j  xL
  VP                  R4      G R
j  xL
 pVP                  4       G R
j  xL
  RTRV'       d   RMR/uuR
R
R
4      GR
j  xL
  #  EL L L L L L{ Ld LM L7 L  + GR
j  xL 
 '       g   i     R
# ; i  \          d    \	        RR/R R7      u # \"         d8   p	\$        P'                  R!4       \	        R\)        T	4      /R R7      u R
p	?	# R
p	?	ii ; i5i)"z4Validate if Grok session is active using Playwright.GROK_SSO_TOKENrG   GROK_SSO_RW_TOKENGROK_USER_IDr   z7Grok cookies not configured. Please save cookies first.r   r   )async_playwrightNT)headlessrE   r]  r,  domainz	.grok.comre   rz   r^  r_  zhttps://grok.com/i0u  ro  domcontentloadedaA  
                () => {
                    // Check for profile button or user menu
                    const pfp = document.querySelector('img[alt="pfp"]');
                    const userMenu = document.querySelector('[aria-label="pfp"]');
                    return !!(pfp || userMenu);
                }
            rq  rA  zSession is activez'Session expired - please update cookieszTPlaywright not installed. Run: pip install playwright && playwright install chromiumr   zGrok session validation error)r   r   r]   allr   playwright.async_apir}  chromiumlaunchnew_contextadd_cookiesnew_pagegotowait_for_load_stateevaluatecloserC  ra   r_   r   r[   )
r]  sso_rwrI  r}  pbrowsercontextpageis_logged_inrh   s
             r>   validate_grok_sessionr  #  s7     **..)2
.CZZ^^/4Fjjnn^R0GW%&&OP
 	

:B9#%%%JJ--t-<<G#//11G %%UGS(KQTU +	 
 +	  $ !))++D))/)???**+=>>> "& 0 " L --/!!  />	O &%%<1$ ,?> "K &%%%\  
o 	
 	
  B89Wc#h/SAABs8  BIG% F3 G% # GF6GF83GF:G'F<(GF>GG G4G5GGGG G% -G.G% 2I3G% 6G8G:G<G>G GGGG% G"	G
G"	G"	G%  I"G% %I?II
I,H=7I8I=IIz/api/settings/leonardoc                   V ^8  d   QhRR/# r   r<   )r=   s   "r>   r?   r?   q  s        G  r@   c                  "    V P                  4       G Rj  xL
 pTP                  RR4      P	                  4       pTP                  RR	4      P	                  4       pT'       g   \        RR
/RR7      # TR9  d   R	pT\
        P                  R&   T\
        P                  R&    \        RTR4      G Rj  xL
  \        RTR4      G Rj  xL
  \        RRR4      G Rj  xL
  RRRT/#  L  \         d    \        RR/RR7      u # i ; i LV LC L0  \         d2   p\        P                  R4       \        RRT 2/RR7      u Rp?# Rp?ii ; i5i)z(Update Leonardo AI API key and settings.Nr   r   r   r   r   rG   
resolution720zAPI key is requiredLEONARDO_API_KEYLEONARDO_RESOLUTIONleonardo_api_keyzLeonardo AI API keyleonardo_resolutionzLeonardo video resolutionrb  leonardord  z,Failed to save Leonardo settings to databaseFailed to save settings: r   r   r  )480r  
rX   ra   r   r]   r   r   r   r%   r_   r   )r   r   r   r  rh   s   &    r>   update_leonardo_settingsr  p  sW    H\\^# hhy"%++-G,.446JW&;<#NN'
 &-BJJ!"(2BJJ$%[,g7LMMM/=XYYY*J8OPPP 	)j 5 $ HWn53GGH$ 	NYP [GHW(A#&GHVYZZ[s   EC* C(C* AE$>E#D 3D
4D D	D DD "E(C* *DEDE
D D D E&EEEEEz/api/settings/leonardo/testc                   "   \        R4      G Rj  xL
 ;'       g!    \        P                  P                  RR4      p V '       g   \	        RR/RR7      #  ^ RIpVP                  ^R	7      ;_uu_4       GRj  xL
 pVP                  R
RRRRV  2/R7      G Rj  xL
 pVP                  ^8X  de   VP                  4       pVP                  R/ .4      ^ ,          pRRRVP                  RR4      RVP                  RR4      /uuRRR4      GRj  xL
  # VP                  R8X  d   RRRR/uuRRR4      GRj  xL
  # \	        RRVP                   2/VP                  R7      uuRRR4      GRj  xL
  #  ELd L L Lm LF L  + GRj  xL 
 '       g   i     R# ; i  \         d8   p\        P                  R4       \	        R\        T4      /RR7      u Rp?# Rp?ii ; i5i)z/Test Leonardo AI API key by fetching user info.r  Nr  rG   r   zLeonardo API key not configuredr   r   ro  z(https://cloud.leonardo.ai/api/rest/v1/meacceptzapplication/jsonauthorizationr  r  user_detailsrq  TcreditsapiConcurrencySlotsunknownrr  rt  FInvalid API keyAPI error: zLeonardo API test errorr   )r$   r   r   r]   r   r  ru  r   rX   ra   r_   r   r[   )r   r  rv  rw  rg   r  rh   s          r>   test_leonardo_apir    s       233]]rzz~~FXZ\7]G78
 	

B$$R$000F:0#wwi%8 $  D 3&yy{#xx=a@T|//0EyQ 0 0R @ 100" !!S(1BC% 100( $D,<,<+=>? $ 0 0) 100 4 1 10002  B23Wc#h/SAABs   G$E5
G$(G$G$"F 8E89F <FE:A&FF E<F G$F*F 7E>8F <G$=%F"F /F 0F 4G$8F :F<F >F  F F	F	
F	F	F G$F G!*,GG!G$G!!G$z/api/settings/pollinationsc                   V ^8  d   QhRR/# r   r<   )r=   s   "r>   r?   r?     s     $ $ $r@   c                  "    V P                  4       G Rj  xL
 pTP                  RR4      P	                  4       pTP                  RR	4      P	                  4       pTP                  R
R4      P	                  4       pTP                  RR4      P	                  4       pT'       d   T\
        P                  R&   T\
        P                  R&   T\
        P                  R&   T\
        P                  R&    T'       d   \        RTR4      G Rj  xL
  \        RTR4      G Rj  xL
  \        RTR4      G Rj  xL
  \        RTR4      G Rj  xL
  RRRTR
TRT/#  EL@  \         d    \        RR/RR7      u # i ; i Lp L] LJ L7  \         d2   p\        P                  R4       \        RRT 2/RR7      u Rp?# Rp?ii ; i5i)z)Update Pollinations API key and settings.Nr   r   r   r   r   rG   image_modelfluxvideo_modelseedance	tts_voicenovaPOLLINATIONS_API_KEYPOLLINATIONS_IMAGE_MODELPOLLINATIONS_VIDEO_MODELPOLLINATIONS_TTS_VOICEpollinations_api_keyPollinations API keypollinations_image_modelPollinations image modelpollinations_video_modelPollinations video modelpollinations_tts_voicePollinations TTS voicez0Failed to save Pollinations settings to databaser  r   r   r  r  )r   r   r   r  r  r  rh   s   &      r>   update_pollinations_settingsr    s    H\\^# hhy"%++-G((=&1779K((=*5;;=Kf-335I -4

)*-8BJJ)*-8BJJ)*+4BJJ'([4g?UVVV4kC]^^^4kC]^^^2I?WXXX 	){{Y	 9 $ HWn53GGH& W^^X [KLW(A#&GHVYZZ[s   GE EE BG$AG1F 9F 	E:
F E<F 3E>4F F 	F 
GE E74G6E77G:F <F >F  F F>&F93F>4G9F>>Gz /api/settings/pollinations/imagec                   V ^8  d   QhRR/# r   r<   )r=   s   "r>   r?   r?     s     S Sg Sr@   c                  "    V P                  4       G Rj  xL
 pTP                  RR4      P	                  4       pTP                  RR	4      P	                  4       pTP                  R
R	4      P	                  4       pTP                  RR4      P	                  4       pT\
        P                  R&   T\
        P                  R&   T\
        P                  R&   T'       d   T\
        P                  R&    \        RTR4      G Rj  xL
  \        RTR4      G Rj  xL
  \        RTR4      G Rj  xL
  T'       d   \        RTR4      G Rj  xL
  \        RRR4      G Rj  xL
  RR RTRTR
T/#  ELU  \         d    \        RR/RR7      u # i ; i L Lz Lg LL L9  \         d2   p\        P                  R4       \        RRT 2/RR7      u Rp?# Rp?ii ; i5i)!z#Update Pollinations Image settings.Nr   r   r   r   r   r  width1024heightr   rG   r  POLLINATIONS_IMAGE_WIDTHPOLLINATIONS_IMAGE_HEIGHTr  r  r  pollinations_image_widthzPollinations image widthpollinations_image_heightzPollinations image heightr  r  r/  pollinationsr1  z*Failed to save Pollinations Image settingsr2  r   r   r  r  )r   r   r   r  r  r   rh   s   &      r>   "update_pollinations_image_settingsr    s    H\\^# HHWf%++-EHHWf%++-EXXh'--/Fhhy"%++-G-2BJJ)*-2BJJ)*.4BJJ*+-4

)*	R4e=WXXX4e=WXXX5v?Z[[[4g?UVVV*N<STTT
 i%%6RR5 $ HWn53GGH 	YX[VT REFW(8&>?SQQR   GE/ E,E/ C GG1F FF FF +F,F 8F F	F FF "
G,E/ /F	GFGF F F F F G$&G
GGGGz/api/settings/pollinations/ttsc                   V ^8  d   QhRR/# r   r<   )r=   s   "r>   r?   r?     s      c  cG  cr@   c           
     L  "    V P                  4       G Rj  xL
 pTP                  RR4      P	                  4       pTP                  RR	4      P	                  4       pTP                  R
R4      P	                  4       pTP                  RR4      P	                  4       pTP                  RR4      P	                  4       pT\
        P                  R&   T\
        P                  R&   T\
        P                  R&   T\
        P                  R&   T'       d   T\
        P                  R&    \        RTR4      G Rj  xL
  \        RTR4      G Rj  xL
  \        RTR4      G Rj  xL
  \        RTR4      G Rj  xL
  T'       d   \        RTR4      G Rj  xL
  \        RR R!4      G Rj  xL
  R%R&RTRTR
TRT/#  EL  \         d    \        RR/RR7      u # i ; i L L L~ Lk LP L=  \         d2   p\        P                  R"4       \        RR#T 2/R$R7      u Rp?# Rp?ii ; i5i)'z!Update Pollinations TTS settings.Nr   r   r   r   r   r   voicer  speed1.0r=   mp3r   rG   POLLINATIONS_TTS_MODELr  POLLINATIONS_TTS_SPEEDPOLLINATIONS_TTS_FORMATr  pollinations_tts_modelzPollinations TTS modelr  r  pollinations_tts_speedzPollinations TTS speedpollinations_tts_formatzPollinations TTS formatr  r  tts_providerr  zActive TTS providerz(Failed to save Pollinations TTS settingsr2  r   r   r  r  )r   r   r   r  r  r=   r   rh   s   &       r>    update_pollinations_tts_settingsr  
  s    H\\^# HHWh'--/EHHWf%++-EHHWe$**,EXXh&,,.Fhhy"%++-G+0BJJ'(+0BJJ'(+0BJJ'(,2BJJ()-4

)*
R2E;STTT2E;STTT2E;STTT3V=VWWW4g?UVVV..:OPPP
 i%%%QY[abb; $ HWn53GGH" 	UTTWVP RCDW(8&>?SQQRs   H$F9 F6F9 C3H$H$$G% 4G5G% 	G
G% GG% 3G4G%  G% G!G% %G#&G% *H$6F9 9GH$GH$G% G% G% G% !G% #G% %H!0&HH!H$H!!H$z /api/settings/pollinations/videoc                   V ^8  d   QhRR/# r   r<   )r=   s   "r>   r?   r?   /  s     e eg er@   c                  "    V P                  4       G Rj  xL
 pTP                  RR4      P	                  4       pTP                  RR	4      P	                  4       pTP                  R
R4      P	                  4       pTP                  RR4      P	                  4       pT\
        P                  R&   T\
        P                  R&   T\
        P                  R&   T'       d   T\
        P                  R&    \        RTR4      G Rj  xL
  \        RTR4      G Rj  xL
  \        RTR4      G Rj  xL
  T'       d   \        RTR4      G Rj  xL
  \        RRR4      G Rj  xL
  R R!RTRTR
T/#  ELU  \         d    \        RR/RR7      u # i ; i L Lz Lg LL L9  \         d2   p\        P                  R4       \        RRT 2/RR7      u Rp?# Rp?ii ; i5i)"z#Update Pollinations Video settings.Nr   r   r   r   r   r  duration5aspect_ratio16:9r   rG   r  POLLINATIONS_VIDEO_DURATIONPOLLINATIONS_VIDEO_ASPECTr  r  r  pollinations_video_durationzPollinations video durationpollinations_video_aspectzPollinations video aspect ratior  r  rb  r  rd  z*Failed to save Pollinations Video settingsr2  r   r   r  r  )r   r   r   r  r  r   rh   s   &      r>   "update_pollinations_video_settingsr  .  s    H\\^# HHWj)//1Exx
C(..0H88NF399;Lhhy"%++-G-2BJJ)*08BJJ,-.:BJJ*+-4

)*	R4e=WXXX7C`aaa5|Efggg4g?UVVV*N<STTT
 i%X~Wcdd5 $ HWn53GGH 	YagVT REFW(8&>?SQQRr  z/api/settings/pollinations/testc                 f  "   \        R4      G Rj  xL
 ;'       g!    \        P                  P                  RR4      p V '       g	   RRRRRR	/#  ^ RIpVP                  ^R
7      ;_uu_4       GRj  xL
 pVP                  RRRV  2/R7      G Rj  xL
 pVP                  ^8X  d;   VP                  4       pRRRRRVP                  RR4      /uuRRR4      GRj  xL
  # VP                  R8X  d   RRRR/uuRRR4      GRj  xL
  # \        RRVP                   2/VP                  R7      uuRRR4      GRj  xL
  #  EL1 L L Lm LF L  + GRj  xL 
 '       g   i     R# ; i  \         d8   p\        P                  R4       \        R\        T4      /RR7      u Rp?# Rp?ii ; i5i)z6Test Pollinations API key by checking account balance.r  Nr  rG   rq  TlimitedrA  z/No API key configured - using limited free tierro  z+https://gen.pollinations.ai/account/balancer  r  r  Fbalancer  rt  r   r  r  r   zPollinations API test errorr   )r$   r   r   r]   r  ru  r   rX   r   ra   r_   r   r[   )r   r  rv  rw  rg   rh   s         r>   test_pollinations_apir  O  s       677ee2::>>J`bd;eG TtH
 	
B$$R$000F=#wwi%8 $  D 3&yy{Tutxx	9= 100 !!S(1BC! 100$ $D,<,<+=>? $ 0 0% 100 8 1 1000.  B67Wc#h/SAABs   F1E
F1(F1F1"E, 1E2E, 5EE<EE, E	E,  F1!E7E, EE, 	F1
%E/E, <E=E, F1E, E	E, E, E, E)	E
E)	!E)	#E, 'F1)E, ,F.7,F)#F.$F1)F..F1z/api/settingsc                 	  "   R R lp  \        4       G Rj  xL
 pVP                  R4      ;'       g!    \        P                  P                  RR4      pVP                  R4      ;'       g!    \        P                  P                  RR	4      pVP                  R
R4      pVP                  RR4      pVP                  RR4      pVP                  R4      ;'       g!    \        P                  P                  RR4      pVP                  R4      ;'       g!    \        P                  P                  RR4      pVP                  R4      ;'       g!    \        P                  P                  RR4      p	VP                  R4      ;'       g!    \        P                  P                  RR4      p
VP                  R4      ;'       g!    \        P                  P                  RR4      pVP                  R^4      p\        V4      ^8X  d
   V^ ,          MRp\        V4      ^8X  d
   V^,          MV^ ,          pVP                  R 4      ;'       g!    \        P                  P                  R!R4      pVP                  R"4      ;'       g!    \        P                  P                  R#R4      pR$R%VR&VR'V ! V4      R(V ! V4      /R)R&\        P                  P                  R*R+4      R,\        P                  P                  R-R.4      R/\        P                  P                  R0R14      R2\        P                  P                  R3R44      /RR5\        VP                  R6R4      4      R7\        VP                  R8R4      4      R9VP                  R:R;4      R&R</RR=R>/R?R@V ! V4      RAVRB\        V4      /RCR@V ! V4      RDVREV	RFV
RBR>RG\        V4      /R
VRVRVRHRIV ! \        P                  P                  RJR4      4      RK\        P                  P                  RLR4      RM\        P                  P                  RNRO4      /RPRQV ! \        P                  P                  RRR4      4      RS\        P                  P                  RTRU4      /RVRW\        P                  P                  RXRV4      RY\        P                  P                  RZR[4      //#  EL  \         d    / p ELi ; i5i)\z/Return all configurable settings (keys masked).c                    V ^8  d   QhRRRR/# )r9   valr[   r:   r<   )r=   s   "r>   r?   /get_all_settings_endpoint.<locals>.__annotate__  s      3 3 r@   c                    V '       d   V P                  R 4      '       d   R# \        V 4      ^8  d   V R,          R,           V RR ,           # R# )zyour-rG   :N   Nr$  Nz***)
startswithr   )r  s   &r>   _mask(get_all_settings_endpoint.<locals>._mask  s=    cnnW--s8b=r7U?SX--r@   Nr  r  rG   r  r  r  rb  rc  r/  r0  r  
chatterboxr  r  r  r  r  r  r  r  r  r  r  r   r   r   rz   r   r   r   r   r   llmr   r   r   r   imageIMAGE_MODELzdall-e-3size
IMAGE_SIZE	1792x1024qualityIMAGE_QUALITYhdstyleIMAGE_STYLEnaturalhas_sessionr-  has_csrfr.  r  google_flow_aspect_ratioportraitnano_banana_proaccounts_configuredTr  r   r  
configuredr  r  r  r  has_api_keyttselevenlabs_keyELEVENLABS_API_KEYvoice_idELEVENLABS_VOICE_IDmodel_idELEVENLABS_MODEL_IDeleven_multilingual_v2video
runway_keyRUNWAY_API_KEYrunway_modelRUNWAY_MODELgen3a_turborv   dir
OUTPUT_DIRplatformTARGET_PLATFORMtiktok)r   ra   r]   r   r   r   r   r   )r  r   leonardo_keyr  rb  r/  r  pollinations_keyr  r  r  r   r   r   r   r   r   s                    r>   get_all_settings_endpointr  |  s5    /11
 ??#56``"**..I[]_:`L%//*?@ppBJJNNShjoDp __%5v>N __%5}EN??><@L #'=>ll"**..QgikBl*/IJ   A   Abjjnn]wy  OA*/IJ   E   Ebjjnn]w  zD  OE(__-EFzz"**..YqsyJz,\\

{O0\IOOC#Eu:?uQxHE
aE!HU1XE!12ZZbjjnnEUWY6ZJOO$78ccBJJNNK^`b<cM 	U%
+U=1	
 	RZZ^^M:>BJJNN<=rzz~~ot<RZZ^^M9=	
 	40KR PQ[__-ErJKKOO,F
S&	
 	!4
 	u\*-$|,

 	u-.33/$4 01
 	..eBJJNN3G$LM

'<bA

'<>VW

 	%

/? DEBJJNN>=I
 	2::>>,9

'8(C
_3 33 2 so   SR; R8R; S8S-A.S8S8S8S8S BS8SH7S8R; ;SSSSc                   V ^8  d   QhRR/# r   r<   )r=   s   "r>   r?   r?     s     43 437 43r@   c                  "    V P                  4       G Rj  xL
 pRR%RR&RR'/p. pTP                  4        Fr  w  pw  rVpYA9   g   K  \	        Y,          4      P                  4       pT'       g   K:  \        YXT4      G Rj  xL
  T\        P                  T&   TP                  T4       Kt  	  R	R
RRRRRRRRRRRRRRRRRRRRRR /p	/ p
T	P                  4        F:  w  rFYA9   g   K  \	        Y,          4      P                  4       pT'       g   K6  YT&   K<  	  T
'       d   \        T
4       T\        T
P                  4       4      ,           pT'       g   \        RR!/RR7      # R"R#R$T/#  ELO  \         d    \        RR/RR7      u # i ; i EL
5i)(zGUpdate one or more settings (DB-backed for LLM, env-backed for others).Nr   r   r   r   r   r   r   r  r  
image_sizer  image_qualityr  image_styler  r  GOOGLE_FLOW_ASPECT_RATIOr	  r
  elevenlabs_voice_idr  elevenlabs_model_idr  r  r  r  r  
output_dirr  target_platformr  zNothing to updater   r  keys)r   r   r   )r   r   r   )r   r   r   )rX   ra   r   r   r[   r   r%   r   r   r   r   r4  r(  )r   r   DB_KEYS
db_updatedfrontend_keydb_keyenv_keydescr  ENV_KEY_MAPenv_updatesall_keyss   &           r>   update_settingsr2    s    H\\^# 	LXGG
 J18--vd()//1Cs!&t444&)

7#!!'* 2A 	}l}"$>.44&l,K K!,!2!2!4d()//1Cs'*G$	 "5 %D!1!1!344HW&9:LLi22c $ HWn53GGH 5sc   FE) E&E) &F$F0F?F	 A F%$FFAF&E) )FFFFz/api/settings/providerc                   V ^8  d   QhRR/# r   r<   )r=   s   "r>   r?   r?     s     N NW Nr@   c                  "    V P                  4       G Rj  xL
 pTP                  RR4      pTP                  RR4      pR	R
RRRR/pY$9  d   \        RRT R2/RR7      # T'       g   \        RR/RR7      # \	        YB,          TRT R24      G Rj  xL
  RRRTRT/#  L  \         d    \        RR/RR7      u # i ; i L.5i)z>Update the active provider for a given type (image/video/tts).Nr   r   r   r   typerG   r   r  r/  r  rb  r  r  zInvalid type 'z '. Must be image, video, or tts.zprovider is requiredzActive z	 providerr   r?  )rX   ra   r   r]   r%   )r   r   provider_typeprovider_namekey_maps   &    r>   update_provider_selectionr9    s     H\\^# HHVR(MHHZ,M('3CUN[G#}o5UVW
 	
 W&<=3OO
g,mw}oU^=_
```dFM:}MM# $ HWn53GGH asJ   CB! BB! AC))CCCB! !B>;C=B>>Cz/api/providers/healthc                   "    \        4       G Rj  xL
 p V P                  RR4      pRpRpVR8X  d5   \        V P                  RR4      4      pV'       d   RMRpV'       d   RMR	pMTVR
8X  d   RpRpMHVR8X  dB   \        \        P
                  P                  RR4      4      pV'       d   RMRpV'       d   RMRpV P                  RR4      pRpRpVR8X  dB    \        4       G Rj  xL
 p	\        R V	 4       4      p
V
^ 8  d   RMRpT
 RV
^8w  d   RMR 2pMnVR8X  d]   \        V P                  RR4      ;'       g!    \        P
                  P                  RR4      4      pV'       d   RMRpV'       d   RMRpMVR
8X  d   RpRpV P                  RR4      pRpRpVR8X  d   RpMTVR8X  dC   \        \        P
                  P                  RR4      4      pV'       d   RMRpV'       d   RMRpMVR
8X  d   RpRpRR R!VR"VR#V/R$R!VR"VR#V/R%R!VR"VR#V///#  EL  \         d    / p  ELi ; i ELH  \         d    RpRp Li ; i5i)&z*Health check for all configured providers.Nr/  r0  not_configuredrG   r-  r  zCookies presentzNo session tokenr  zFree cloud providerdalle3r   zAPI key setz
No API keyrb  rc  c              3  V   "   T F  qP                  R 4      '       g   K  ^x  K!  	  R# 5irR  r  rS  s   & r>   rV  )check_providers_health.<locals>.<genexpr>G  s     CHqk0BHs   )
)z active accountsr   zFailed to query accountsr  r  r  r  r  zLocal provider
elevenlabsr
  	providersr  rE   r   detailsr  r  )r   ra   r]   r   r   r   r,   rY  )r   r/  image_statusimage_detailsr   has_keyrb  video_statusvideo_detailsrG  rP  r  
tts_statustts_detailss                 r>   check_providers_healthrJ  (  sk    /11
 !__%5}EN#LM&;??+FKL'2|8H-8)>P	>	)#-	8	#rzz~~&6;<'.|4D)0l !__%5v>N#LM	7/11HCHCCF+1A:<;KL%hoVq[cb5QRM 
:	%{'92>hh"**..QcegBhi'.|4D)0l	>	)#- ??><@LJK|#&		%rzz~~&:B?@%,\2B
'.mL		'!
+ 	fnhiQ^_fnhiQ^_FL(J	;W
 o 2 2 2  	7"L6M	7s   IH HH AI"AI7!IH1 &H.'1H1 %I>,I+I7A3I+,IH H+'I*H++I.H1 1I IIIz/api/projectsc                 :   "   \        4       G Rj  xL
 p RV /#  L5i)zList all projects (summary).Nprojects)r-   )rL  s    r>   api_list_projectsrM  l  s!      #_$H!! %r   z/api/projects/{project_id}c                   V ^8  d   QhRR/# r9   r;  r[   r<   )r=   s   "r>   r?   r?   t  s     3 3 3r@   c                  "   ^ RI p\        V 4      G Rj  xL
 pVf   \        RR/RR7      # \        R,          V ,          pVP	                  4       '       d   VP                  VRR7       \        V 4      G Rj  xL
  R	R
RV /#  Lm L5i)z*Delete a project and its images (cascade).Nr   Project not foundr   r   rv   T)ignore_errorsr   r   rQ   )shutilr    r   rT   rU   rmtreer   )r;  rS  projr&  s   &   r>   api_delete_projectrV  s  s      Z((D|W&9:LL)J6Jj5

$$$iz22 ) %s(   BBA B!B8B9BBc                   V ^8  d   QhRR/# rO  r<   )r=   s   "r>   r?   r?     s      c r@   c                   "   \        V 4      G Rj  xL
 pVf   \        RR/RR7      # \        V 4      G Rj  xL
 pW!R&   \        V 4      G Rj  xL
 pW1R&   \	        V 4      G Rj  xL
 pWAR&   V#  L^ L: L% L5i)	z5Get full project details including result and images.Nr   rQ  r   r   imagesvideosaudios)r    r   r!   r"   r#   )r;  rU  rY  rZ  r[  s   &    r>   api_get_projectr\    s}      Z((D|W&9:LL%j11FN%j11FN%j11FNK ) 211sC   A8A0%A8A2A8A4A8%A6&A82A84A86A8z!/api/projects/{project_id}/assetsc                   V ^8  d   QhRR/# rO  r<   )r=   s   "r>   r?   r?     s     W W Wr@   c                   "   \        V 4      G Rj  xL
 pVf   \        RR/RR7      # VP                  R4      pV'       d   VP                  R. 4      M. p\        V4      p\	        V 4      G Rj  xL
 p\        V 4      G Rj  xL
 p\        V 4      G Rj  xL
 p. pT;'       g    .  F  p	V	P                  RR	4      p
\        P                  P                  V
4      '       d   \        V
4      M\        V
,          pVP                  4       pTP                  R
V	R
,          RT
RTRV'       d   VP                  4       P                  M^ RV	P                  RR4      /4       K  	  . pT;'       g    .  F  pVP                  RR	4      p
\        P                  P                  V
4      '       d   \        V
4      M\        V
,          pVP                  4       pTP                  R
VR
,          RT
RTRV'       d   VP                  4       P                  M^ RVP                  R4      RVP                  RR4      /4       K  	  . pT;'       g    .  F  pVP                  RR	4      p
\        P                  P                  V
4      '       d   \        V
4      M\        V
,          pVP                  4       pTP                  R
VR
,          RT
RTRV'       d   VP                  4       P                  M^ RVP                  R4      RVP                  RR4      /4       K  	  V Uu. uF  pVR,          R'9   g   K  VNK  	  ppV Uu. uF  pVR,          R8X  g   K  VNK  	  ppV Uu. uF  pVR,          R8X  g   K  VNK  	  pp\!        R V 4       4      \!        R V 4       4      ,           \!        R V 4       4      ,           p\!        R V 4       4      pRV RVRRVRVRV/RRVR\        V4      RV\        V4      ,
          RVR \        V4      R!V\        V4      ,
          R"VR#\        V4      R$V\        V4      ,
          R%VR&\#        V^4      //#  EL3 EL EL ELu upi u upi u upi 5i)(z2Return detailed asset metadata for CLI inspection.Nr   rQ  r   r   rD  scenes	file_pathrG   scene_numberrU   file_size_bytesr   pendingduration_secondsr   c              3  2   "   T F  qR ,          x  K  	  R# 5irb  Nr<   )rT  is   & r>   rV  %get_project_assets.<locals>.<genexpr>  s     6+Q  +   c              3  2   "   T F  qR ,          x  K  	  R# 5irf  r<   rT  r   s   & r>   rV  rh         8Kq!""Kri  c              3  2   "   T F  qR ,          x  K  	  R# 5irf  r<   rS  s   & r>   rV  rh    rl  ri  c              3  V   "   T F  qP                  R 4      ;'       g    ^ x  K!  	  R# 5i)rd  Nr  rk  s   & r>   rV  rh    s#     MA1277a7s   ))r;  total_scenesassetsrY  rZ  r[  summarytotal_imagesgenerated_imagesmissing_imagestotal_videosgenerated_videosmissing_videostotal_audiosgenerated_audiosmissing_audiostotal_disk_size_bytestotal_duration_secondsr   approved)r    r   r]   r   r!   r"   r#   r   re   isabsr   rT   rU   r   statst_sizerY  round)r;  rU  rD  r_  ro  	images_db	videos_db	audios_dbimages_listimgfp	full_pathrU   videos_listvidaudios_listaudrg  
gen_imagesr   
gen_videosrU  
gen_audios
total_disktotal_durations   &                        r>   get_project_assetsr    s     Z((D|W&9:LLXXhF)/VZZ"%RFv;L(44I(44I(44I KRWW["% "b 1 1DH}r7I	!!#C/f6y~~/77qcggh	2
 		   KRWW["% "b 1 1DH}r7I	!!#C/f6y~~/77q(: ;cggh	2
 		   KRWW["% "b 1 1DH}r7I	!!#C/f6y~~/77q(: ;cggh	2
 		   )U[AhK;T,T!![JU(G[AhK;,F!![JG(G[AhK;,F!![JG6+66
8K8
8	9
8K8
8	9 
 MMMN 	jkkk

 	LJlS_<LJlS_<LJlS_<#Z$eNA&>
 A ) 544X VGGs   QQ/Q-Q/Q0QQ
QQQ%BQ+AQ-BQ3AQBQAQQ-Q3Q9QQQQ/Q5CQQ
QQQz,/api/projects/{project_id}/generation-statusc                   V ^8  d   QhRR/# rO  r<   )r=   s   "r>   r?   r?     s     > >C >r@   c                  "   \        V 4      G Rj  xL
 pVf   \        RR/RR7      # VP                  R4      pV'       d   VP                  R. 4      M. p\        V 4      G Rj  xL
 p\	        V 4      G Rj  xL
 p\        V 4      G Rj  xL
 pT;'       g    .  Uu/ uF  pVR,          VP                  R	R
4      bK  	  ppT;'       g    .  U	u/ uF  p	V	R,          V	P                  R	R
4      bK  	  p
p	T;'       g    .  Uu/ uF  pVR,          VP                  R	R
4      bK  	  pp. pV F^  pVP                  R^ 4      pVP                  RVRVP                  VR
4      RV
P                  VR
4      RVP                  VR
4      /4       K`  	  \        V4      p\        R V 4       4      p\        R V 4       4      p\        R V 4       4      pRT RVP                  R	R4      RTRRRTRTRV'       d   \        V^d,          V,          4      M^ /RRTRTRV'       d   \        V^d,          V,          4      M^ /RRTRTRV'       d   \        V^d,          V,          4      ///# ^ ///#  ELV EL EL ELu upi u up	i u upi 5i)uI   Non-SSE status polling — return current generation state as plain JSON.Nr   rQ  r   r   rD  r_  ra  r   rc  r  r  audioc              3  D   "   T F  qR ,          R9   g   K  ^x  K  	  R# 5i)r  Nr}  r<   rT  r?  s   & r>   rV  (get_generation_status.<locals>.<genexpr>  s     Xn'
>W0W11n    
 c              3  D   "   T F  qR ,          R8X  g   K  ^x  K  	  R# 5i)r  r   Nr<   r  s   & r>   rV  r         Jn'
k0I11nr  c              3  D   "   T F  qR ,          R8X  g   K  ^x  K  	  R# 5i)r  r   Nr<   r  s   & r>   rV  r    r  r  r;  project_statusr  progressrY  donerO  percentrZ  r[  )
r    r   r]   r!   r"   r#   r   r   rY  r  )r;  rU  rD  r_  r  r  r  r  
img_statusr  
vid_statusr  
aud_statusscene_statusesscenesnrO  img_donevid_doneaud_dones   &                   r>   get_generation_statusr    s     Z((D|W&9:LLXXhF)/VZZ"%RF(44I(44I(44I OOO#C 	NSWWXy99#   OOO#C 	NSWWXy99#   OOO#C 	NSWWXy99#  
 NYY~q)BZ^^B	2Z^^B	2Z^^B	2	
 	  KEXnXXHJnJJHJnJJH 	j$((8Y7.E5C%!78q
 E5C%!78q
 E5C%!78
	 $ HI
	 O ) 544s   JI'/J"J$I*%J7I-8J
I0JJ#I3 
JJ#I83
J>J#I=&C6J(J"J*J-J0J3Jz&/output/{project_id}/assets/{filename}c                    V ^8  d   QhRRRR/# )r9   r;  r[   filenamer<   )r=   s   "r>   r?   r?   1  s     ' '# ' 'r@   c                  "   RV9   g   RV9   g   RV9   d   \        RR/RR7      # \        R,          V ,          R	,          V,          pVP                  4       '       g   \        RR
/RR7      # VP                  4       p\        R,          V ,          R	,          P                  4       p\	        V4      P                  \	        V4      4      '       g   \        RR/RR7      # \        \	        V4      4      # 5i)z:Serve a generated image from per-project output directory.z..rz   \r   zInvalid filenamer   r   rv   rp  zFile not foundr   zInvalid path)r   rT   rU   resolver[   r  r   )r;  r  
asset_pathresolvedexpected_parents   &&   r>   serve_assetr  0  s      x3(?dh.>W&89sKK)J6AHLJW&67SII!!#H$x/*<xGPPROx=##C$899Wn53GGH&&s   AC3BC3z5/api/projects/{project_id}/scenes/{scene_num}/approvec                    V ^8  d   QhRRRR/# r9   r;  r[   	scene_numrj  r<   )r=   s   "r>   r?   r?   B  s     = =C =C =r@   c                   "   \        V 4      G Rj  xL
 pVf   \        RR/RR7      # \        WR4      G Rj  xL
  RRRV/#  L1 L5i)	zMark a scene image as approved.Nr   rQ  r   r   r~  r   ra  )r    r   r0   )r;  r  rU  s   && r>   approve_scener  A  sV      Z((D|W&9:LL
jZ
@@@j.)<<	 ) As   AA&AAAAz3/api/projects/{project_id}/scenes/{scene_num}/imagec                    V ^8  d   QhRRRR/# r  r<   )r=   s   "r>   r?   r?   L  s     < < < <r@   c                .  "   \        V 4      G Rj  xL
 pVf   \        RR/RR7      # \        R,          V ,          R,          pVRVR	 R
2,          pVP                  4       '       d   VP	                  4        \        W4      G Rj  xL
  RRRV/#  L L5i)z2Delete a generated image so it can be regenerated.Nr   rQ  r   r   rv   rp  frame_02dr   r   r   ra  )r    r   rT   rU   r   r   )r;  r  rU  r&  img_paths   &&   r>   delete_scene_imager  K  s      Z((D|W&9:LL )J6AJfYsO488H z
---i;; ) .s(   BBAB(BBBBz8/api/projects/{project_id}/scenes/{scene_num}/regeneratec               $    V ^8  d   QhRRRRRR/# )r9   r;  r[   r  rj  r   r   r<   )r=   s   "r>   r?   r?   _  s+     `W `Ws `Ws `WW `Wr@   c           
     @  a"   \        V 4      G Rj  xL
 pVf   \        RR/RR7      # VP                  R4      pV'       g   \        RR/RR7      # VP                  R	. 4      p\        V3R
 lV 4       R4      pVf   \        RR/RR7      # VP                  RR4      pV'       g   \        RR/RR7      # Rp VP	                  4       G Rj  xL
 p	V	P                  RR4      P                  4       pV'       d   V RV 2p\        R,          V ,          R,          p
V
P                  RRR7       V
RSR R2,          p \        4       G Rj  xL
 pVP                  RR4      p VR8X  d   ^ RI
Hp XP                  RR4      p\        VP                  RR4      4      p\        VP                  R R4      4      pVP                  R!R4      pT! RT;'       g    RR"7      p\        P                  ! VP                  VVVVVR#7      G Rj  xL
  M^ R$IHpHpHp V! XP                  R%R4      VP                  R&R4      R'7      G Rj  xL
  VP                  VP                  R(\(        P*                  P                  R)R*4      4      P-                  4       R+4      pV! W{VR,7      G Rj  xL
  \/        V S\1        V4      4      G Rj  xL
  ^ RIpRpVP5                  4       '       d/   VP7                  VP9                  4       4      P;                  R-4      pR.R/R0SR1R2V  R3SR R2R4VR5V/#  EL EL[  \         d     ELGi ; i EL  \         d    Rp ELi ; i ELM EL L L  \         d4   p\<        P?                  R6T S4       \        RR7T 2/R8R7      u Rp?# Rp?ii ; i5i)9z:Regenerate a single scene image, optionally with feedback.Nr   rQ  r   r   rD  No plan result foundr   r_  c              3  F   <"   T F  qR ,          S8X  g   K  Vx  K  	  R# 5ira  Nr<   rT  r?  r  s   & r>   rV  #regenerate_scene.<locals>.<genexpr>k       FV'8I'E!!V   !
!Scene not foundimage_promptrG   zNo image prompt for scenefeedbackz

Additional direction: rv   rp  Trw   r  r  r   r/  r0  r  )get_image_providerr  r  r  r  r  r  r   )r   output_pathr   r  r  generate_image
get_engineASPECT_RATIOSr-  r.  r5  r6  r  r#  r  IMAGE_ASPECT_RATIO_PORTRAIT)r  rC   r   regeneratedra  	image_url/output//assets/frame_image_base64r   z+Regeneration failed for project %s scene %dzRegeneration failed: r   ) r    r   r]   nextrX   r   ra   rT   r   r   rA  r  rj  r   r   r   providers.flow_browser_enginer  r  r  r   r   lowerr/   r[   base64rU   	b64encode
read_bytesdecoder_   r   )r;  r  r   rU  rD  r_  r  r  r  r   r&  r  r   image_provider_prefr  pollinations_modelpollinations_widthpollinations_heightr  img_provr  r  r  aspectr  r  rh   s   &f&                        r>   regenerate_scener  ^  s     Z((D|W&9:LLXXhFW&<=3OO ZZ"%FFVFME}W&78cJJ99^R0LW&ABPSTT H\\^#88J+113 &'A(L)J6AJTD1fYsO488H,/11)oo.>N6W.04!,1KV!T!$[__5OQW%X!Y"%koo6QSY&Z"[*/ErJ).BRBZBZVZ[H##!!#$((*   `_ )oo.I2N&??+CRH   #&& :JJNN#=zJLLQEG-F
 !fMMM  
Is8}EEE 	??!++H,?,?,ABII'RL mI8J<~i_DQL+
 	
g )* $  2 ,+, N 	F  W9:y	
 W(=cU&CDRUVV	Ws  NL$/NA#N'N9L* L'$L* 1N9AN=L? 
L<L? "A2M 1M M<M MAM #M$M MM "AM #N'L* *L95N8L99N<L? ?MNMNM M M M N((NNNNNz*/api/projects/{project_id}/generate-imagesc                   V ^8  d   QhRR/# rO  r<   )r=   s   "r>   r?   r?     s     J J# Jr@   c                   a a	a
a"   \        S 4      G Rj  xL
 pVf   \        RR/RR7      # VP                  R4      pV'       g   \        RR/RR7      # VP                  R	. 4      pV'       g   \        RR
/RR7      # \        S 4      G Rj  xL
 pT;'       g    .  Uu0 uF$  pVP                  R4      R9   g   K  VR,          kK&  	  ppV Uu. uF7  pVP                  R^ 4      V9  g   K  VP                  R4      '       g   K5  VNK9  	  upo	S	'       g   \        RR/RR7      # \        R,          S ,          R,          o
S
P                  RRR7       \        V4      oV	V
V V3R lp\        V! 4       RRRRR/R7      #  ELj Lu upi u upi 5i)zSGenerate images for missing scenes in a completed plan, streaming progress via SSE.Nr   rQ  r   r   rD  r  r   r_  No scenes in planr   ra  r  zAll scenes already have imagesrv   rp  Trw   c                  <"   \        S4      p / p\        4       G R j  xL
 pVP                  RR4      p\        S^4       EF\  w  rEVP                  RV4      pVP                  RR4      pVP                  R4      pVP                  R^ 4      p	VP                  RR4      p
S R	VR
 R2,          p\        P
                  ! RVRV RS"RVRRRVRV
/4      pRV R25x   VR8X  EdH   ^ RIHpHpH	p VP                  VP                  R\        P                  P                  RR4      4      P                  4       R4      pR pV'       dW   V	^ 8  dP   VP                  V4      pV'       d!   \        P                  RWV
VR,          4       M\        P                  RW4       V! W{VVR7      G R j  xL
  V'       ds   V	^ 8X  dl    V! VP                  RR4      VP                  RR4      R 7      G R j  xL
 pVP                   pV'       d#   VW&   \        P                  R!VVR,          4       EMEMVR#8X  d   ^ R$IHp VP                  R%R4      ;'       g!    \        P                  P                  R&R4      pVP                  R'R(4      p\)        VP                  R)R*4      4      p\)        VP                  R+R*4      4      pT! T;'       g    R R,7      pVP+                  W{VVVR-7      G R j  xL
  MZVR.8X  d(   ^ R/IHp V! 4       pVP+                  W{4      G R j  xL
  M,\        P                  R0V4       ^ R1IHp V! W{4      G R j  xL
  \1        S!VV\3        V4      R2R37      G R j  xL
  \        P
                  ! RVRV RS"RVR4R5S! R6VR
 R2RR7RVRV
/4      pRV R25x  EK_  	  R:5x  R #  EL EL EL  \"         d!   p\        P                  R"T4        R p?LR p?ii ; i L L L L  \"         dX   p\        P5                  R8S!T4       \        P
                  ! RTRT RS"RTR9\3        T4      RT/4      pRT R25x   R p?EK  R p?ii ; i5i);Nr/  r0  ra  r  rG   coverage_group_idcoverage_angle_indexcoverage_angle_typer  r  r   rO  ro  r  r   
generatingcoverage_group
angle_typedata: 

r  r  r#  r  r  u6   Coverage ref: group=%s angle=%d type=%s media_id=%s…:N   NuD   No master reference for %s angle %d — generating without reference)r  reference_media_idr-  r.  r  u1   Coverage master captured: group=%s media_id=%s…z%Could not capture master media_id: %sr  )PollinationsImageProviderr  r  r  r  r  r  r  r  )r   r  r  r<  )DallE3ImageProviderz8Unknown image provider '%s', falling back to google_flow)r  r   r;  ra  r  r`  r   r  r  r  r  z/Image generation failed for project %s scene %dr   event: done
data: {}

)r   r   r]   	enumeraterX   dumpsr  r  r  r  r   r   r  r_   r`   rb   last_media_idra   %providers.pollinations_image_providerr  rj  r   providers.image_providerr  r3   r[   r   )#total_missingcoverage_master_media_idsr   image_provider_nameidxr  r  r  r  angle_indexr  r  start_payloadr  r  r  r  r  engine
master_midmid_excr  r  r   r  r  r  r  payloadrh   err_payloadmissing_scenesr&  r;  ro  s#                                  r>   event_stream)generate_images_sse.<locals>.event_stream  s    N+ 57!/11)oo.>N#NA6JC		.#6I 99^R8L"YY':;N))$:A>K%rJ "fYsO4$@@H !JJ"I]"Lsl$n *
M =/..v1&-7  +..#(BJJNN+EzRTTYTYT[5F 6:&%+/-F-J-J>-Z*-"KK X .Z 23 7 #NN f .
 )$%++=   &+*:]+5.9oo>Y[].^+6??;SUW+X, &F *0)=)=J)LV 9 I &$W$2JsO!" )N:_'27Mr'R  (A  (AVXV`V`VdVde{}  WA$'OO,FOE0JF STE 1Lf!UVF8AQAYAYUYZH"++$#5 ,   
 )H4L24H"++LCCC NN#]_rsL(@@@")!*!-!(m&   **&	&!3#x
|>)TWX\%] &(.$j	 wit,,{ 7b *)i 2v&  ) ]"NN+RT[\\] D A,  1  E
 #jj&	&!3S(.	 {m4000!1s   QN)B<QA)O(O(&AO(*N,+O(7O(?-N2,N/-N2"N2')O(A3O( O(%O &-O(O",O( O$ O(!O&";O(Q,O(/N22O=OO(OO("O($O(&O((Q
3AQ>QQ

Qtext/event-streamCache-Controlno-cacheX-Accel-Bufferingno
media_typer  r}  )r    r   r]   r!   rT   r   r   r   )r;  rU  rD  r_  existing_imagesr  existing_scene_numsr?  r  r
  r&  ro  s   f        @@@r>   generate_images_sser    s     Z((D|W&9:LLXXhFW&<=3OOZZ"%FW&9:LL /z::O $))r))C778 99 	N)   A55#+>> 	
CD55CX 	
N 67S
 	
 )J6AJTD1v;LZ* Z*x &Z
 C ) ;sj   FE?/F(F/FFFFF<F	FF	-F	F	
FA)FF
Fz*/api/projects/{project_id}/generate-videosc                    V ^8  d   QhRRRR/# r9   r;  r[   r   r   r<   )r=   s   "r>   r?   r?     s     d d# d dr@   c           
       a aaaaaaaaa"   \        S 4      G Rj  xL
 pVf   \        RR/RR7      # VP                  R4      pV'       g   \        RR/RR7      # VP                  R	. 4      pV'       g   \        RR
/RR7      # \        S 4      G Rj  xL
 pT;'       g    .  Uu0 uF$  pVP                  R4      R%9   g   K  VR,          kK&  	  pp\	        S 4      G Rj  xL
 pT;'       g    .  U	u0 uF$  p	V	P                  R4      R8X  g   K  V	R,          kK&  	  p
p	V Uu. uF7  pVP                  R^ 4      V9   g   K  VP                  R^ 4      V
9  g   K5  VNK9  	  upoS'       g   \        RR/RR7      # \
        R,          S ,          R,          o \        4       G Rj  xL
 pVP                  RR4      oVP                  RR4      oVP                  RR4      oVP                  RR4      oVP                  RR4      oVP                  RR4      o \        VP                  P                  RR4      4      o\        ^\        S^
4      4      oVVVVVVVVV V3
R lp\        V! 4       RR R!R"R#/R$7      #  ELZ ELu upi  ELu up	i u upi  L  \         d    RoRoRoRoRoRo Li ; i  \        \        3 d    ^o Li ; i5i)&zGenerate videos for scenes that have images but no videos, streaming progress via SSE.

Query params:
    parallel (int): Number of concurrent Grok browser workers (default 1 = sequential).
Nr   rQ  r   r   rD  r  r   r_  r  r   r   ra  z*All scenes with images already have videosrv   rp  rb  rc  r  rG   r  r  r  r  r  r  r  parallel1c                  <
aaa"   \        S4      p R pRpS;'       g!    \        P                  P                  RR4      pS%R8X  d*    ^ RIHp T! S ;'       g    R S#\        S"4      S!R7      pRpM2S%R8X  d,   V'       d$    ^ R	I
Hp V\        P                  R&   V! 4       pRpVR J pV'       dE   \        4       G R j  xL
 pV'       g)   \        P                  ! RR/4      p	RV	 R25x  R5x  R # Rp\        P                  RV4       V'       Ed   S^8  Ed   ^ RIHo \$        P&                  ! 4       oR6R V3R llloR VVVVVVV$3R llp
\$        P(                  ! V
! 4       4      p^ p  SP                  4       G R j  xL
 pVf   EM!VR,          R8X  d:   V^,          p\        P                  ! RVR,          RV RVRR/4      pRV R25x  Kf  VR,          R8X  dJ   V^,          p\        P                  ! RVR,          RV RVRVP                  RR4      /4      pRV R25x  K  VR,          R 8X  d1   \        P                  ! RVR,          RV RVRR /4      pRV R25x  K  VR,          R8X  g   EK  \        P                  ! RVP                  RR!4      /4      pRV R25x  EK@  VG R j  xL
  R\        P                  ! R"RR#S/4       R25x  R5x  R #  R p\+        S^4       EF  w  ppVP                  RV4      pVP                  R$R4      pSR%VR& R'2,          pSR%VR& R(2,          p\        P                  ! RVRV RVRR /4      pRV R25x   V'       d   \        4       G R j  xL
 pV'       g   \-        R)4      hVR*,          V8w  ds   Ve    VP/                  4       G R j  xL
  ^ R+IHp V! VR,,          VR-,          VR.,          R/7      pVR*,          p\        P                  R0VR*,          VR1,          V4       VP5                  VVVR27      G R j  xL
  \7        S$VV\9        V4      R3R47      G R j  xL
  \        P                  ! RVRV RVRR/4      pRV R25x  EK  	  V'       d    VP/                  4       G R j  xL
  M R5x  R #   \         d"   p\        P                  RT4        R p?EL!R p?ii ; i  \         d"   p\        P                  R
T4        R p?ELPR p?ii ; i EL? EL} ELO  TG R j  xL 
  i ; i EL ELg  \         d     ELsi ; i EL L  \         dT   p\        P;                  R5S$T4       \        P                  ! RTRT RTR\9        T4      /4      p	RT	 R25x   R p?EK  R p?ii ; i EL  \         d     ELi ; i  T'       d-    TP/                  4       G R j  xL 
  i   \         d     i i ; ii ; i5i)7Nr  r  rG   r  PollinationsVideoProviderr   r   r  r  3Pollinations video provider failed: %s, trying Grokr  LeonardoVideoProvider)Leonardo provider failed: %s, trying Grokr   6No Grok accounts configured. Add accounts in Settings.r  r  r  rc  zUsing video provider: %s)GrokWorkerPoolc               0    V ^8  d   QhRRRRRRRRRRR	R
/# )r9   r  rj  r   r[   r  rO  r   z
str | Noner:   r;   r<   )r=   s   "r>   r?   ?generate_videos_sse.<locals>.event_stream.<locals>.__annotate__  s<      (+69BENXr@   c                Z   <"   SP                  R V RVRVRVRV/4      G Rj  xL
  R#  L5i)ra  r   r  rO  r   N)put)r  r   r  rO  r   progress_queues   &&&&&r>   _on_pool_progressDgenerate_videos_sse.<locals>.event_stream.<locals>._on_pool_progress  s;      %(("Ixw*   s   +)+c                   V ^8  d   QhRR/# r8   r<   )r=   s   "r>   r?   r'     s     3 3T 3r@   c                 F  <a"    S! SR 7      ;_uu_4       GRj  xL
 p V P                  4       G Rj  xL
  \        S
^4       UUu. uFy  w  rRVP                  RV4      R\        SRVP                  RV4      R R2,          4      RVP                  RR4      R	\        SRVP                  RV4      R R
2,          4      /NK{  	  pppV P	                  VS	R7      G Rj  xL
 pV Fb  oSP
                  '       g   K  \        V3R lS
 4       R4      p\        SSP                  V\        SP                  4      RR7      G Rj  xL
  Kd  	  RRR4      GRj  xL
  SP                  R4      G Rj  xL
  R#  EL\ ELGu uppi  L LA L/  + GRj  xL 
 '       g   i     LF; i  \         dN   p\        P                  RS4       SP                  R^ RRR\        T4      R^ R^ /4      G Rj  xL 
   Rp?LRp?ii ; i L  SP                  R4      G Rj  xL 
  i ; i5i))max_workersNra  
image_pathr  r  r   video_promptrG   r  .mp4)r_  on_progressc              3     <"   T F9  pVP                  R 4      SP                  8X  g   K%  VP                  RR4      x  K;  	  R# 5i)ra  r1  rG   N)r]   ra  )rT  scrs   & r>   rV  Ogenerate_videos_sse.<locals>.event_stream.<locals>._run_pool.<locals>.<genexpr>1  s=      %R.B(*~(>!..(P &@RVVNB%?%?.s
   "AAr   r;  ra  r1  r`  r   z"Parallel pool error for project %sr   r   r  rO  )startr  r]   r[   generate_batchsuccessr  r4   ra  r  ra   r_   r   r)  )poolrg  r?  scenes_dataresults
vid_promptrh   r6  r%  r+  r
  r&  r  r*  r;  s          @r>   	_run_pool<generate_videos_sse.<locals>.event_stream.<locals>._run_pool   s    3-(CCCt"jjl** )2.!(D' )E !/na0H ,c*n^_H`adGeei?j2j.k .nb0I -s:&~_`IabeHffj@k3k/l	 )E $ ' )-(;(;;\m(;(n"n!(A yyy-1%R. %RSU."
 '3/9121;.1!--.@+6'" !" !" ")  DC: ),,T222;  D*' #o!"%  DCCC2 ! B$$%I:V(,,na7T[]`ad]egprsu|~  .A  B  B  BB 3.,,T222s  H!F% E7F% F	E:F	A?E=
F	F F	=AF	F
F	F% FF% H!0H 1H!7F% :F	=F	F	F% 	F"	F
F"	F"	F% !H "F% %G=0=G8-G0.G83H 8G==H  H!HHHH!Tr   	completedra  rO  r  r  failedUnknownr  z
Pool errorparallel_modeworkersr1  r  r  r   r2  z!No active Grok accounts availablerQ   GrokPlaywrightProviderr`  ra  rI  r`  ra  rI  z'Using Grok account %d (%s) for scene %drH  r0  r1  r  r   r8  /Video generation failed for project %s scene %dN)r   r   r   r]   %providers.pollinations_video_providerr  rj  ra   r_   rb   !providers.leonardo_video_providerr"  r   rX   r  r`   providers.grok_worker_poolr%  r   Queuecreate_taskr  RuntimeErrorr  "providers.grok_playwright_providerrH  r   r4   r[   r   )&r  
video_provr7  r  r  rh   r"  use_grok_rotationtest_accountr	  r@  	pool_task
done_counteventr  current_account_idr  r  r  r1  r  vid_pathr  rg  GrokVideoProviderr%  r+  r*  leonardo_key_dbr
  r&  r  pollinations_key_dbr  r  r  r;  video_provider_prefs&                            @@@r>   r  )generate_videos_sse.<locals>.event_stream  sP    N+
! 'PP"**..9KR*P.0
[[6/7742 !<=!:	
 !/ !J.<QS1=

-.24
 *
 '$.!6!88L"jj'3k)lm{m40011"M.> AA9@N 3 3B  ++IK8IJ "0"4"4"66E}X+5"a
"&**neN>SU\^kmv  yC  EM  OU  .V  #W &wit44xH4"a
"&**neN>SU\^kmv  yC  EL  NS  NW  NW  X_  aj  Nk  .l  #m &wit44xL8"&**neN>SU\^kmv  yC  EM  O[  .\  #] &wit44xG3"&**guyy,7W-X"Y &wit444::i&RSTTXYY--X	!%':
U!IInc:	$yy<%&3t(DD%&3t(DD !%

&	!3 ,	! }oT22>5((=(?"?&"./R"SS #4=,>>)5!)*4*:*:*<$<$< w):*1+*>-4^-D(/	(:*J
 29."KK(Q'.t}gg6F	S %--#+%1$, .    '#-%.%1"%h-*   #jj*I#]%s$f	G #7)400A ;d $**,,,  *)  [TVYZZ[  QJCPPQ 9| 7$  i8 #@ %='0 !)$(!)$ ! 5$$I"!
 #'***I#]%s#SX	#K #;-t4445$ -   $**,,,   s  AWR R /W "S "W.W;S:<WAWAW,T  S=C1T 84T ,W1T 2,WA<V& T01T2T0>T0T/T0T4A,T0 T+! T0T.+T0-V& 2W;V VV 	WS'S=WSWS7S2,W2S77W=T  WT	T
TWT0TT($T0'T((T0.T00V;AV	V& 	VV& V V#W"V##W&	W0W
WW
	W
WWWWWr  r  r  r  r  r  r}  )r    r   r]   r!   r"   rT   r   ra   rj  query_params
ValueError	TypeErrormaxminr   )r;  r   rU  rD  r_  r  r  image_scene_numsexisting_videosr  video_scene_numsr?  r   r  r]  r
  r&  r  r^  r  r  r  r_  s   f&            @@@@@@@@@r>   generate_videos_sseri    s     Z((D|W&9:LLXXhFW&<=3OOZZ"%FW&9:LL /z::O $))r))C778 99 	N)   /z::O $))r))C778+ 	N)   A55#'77 	
 EE.!$,<< 	
N BCQT
 	
 )J6AJ+/11)oo.>G%//*<bA)oo.DbI#.??3Mz#Z &1oo6SUX&Y#$/OO4OQW$X!w++//
C@A 1c(B'(HQ* Q*f &Z
 o ) ; ;  2  +$ #- &)#$*!+ 	" s   KI5/K(K5KI8K K%I;I;KJ  K-K2JJK"J JJ
K**KJ "J#A0J %J, 9=K8K;K
KJ J)&K(J))K,K?KKKz*/api/projects/{project_id}/generate-audiosc                   V ^8  d   QhRR/# rO  r<   )r=   s   "r>   r?   r?     s     g g# gr@   c                (  a aa	a
"   \        S 4      G Rj  xL
 pVf   \        RR/RR7      # VP                  R4      o
S
'       g   \        RR/RR7      # S
P                  R	. 4      pV'       g   \        RR
/RR7      # \        S 4      G Rj  xL
 pT;'       g    .  Uu0 uF$  pVP                  R4      R8X  g   K  VR,          kK&  	  ppV Uu. uFF  pVP                  R^ 4      V9  g   K  VP                  RR4      P	                  4       '       g   KD  VNKH  	  upoS'       g   \        RR/^R7      # \
        R,          S ,          R,          o	S	P                  RRR7       VV	V V
3R lp\        V! 4       RRRRR/R7      #  ELn Lu upi u upi 5i)zRGenerate TTS audio for all scenes in a completed plan, streaming progress via SSE.Nr   rQ  r   r   rD  r  r   r_  r  r   r   ra  tts_textrG   rA  zAll scenes already have audiorv   rp  Trw   c                  <"   \        S$4      p R pRp ^ RIHp ^ RIHp  \        4       G R j  xL
 pVP                  RR 4      pVP                  RR4      pVP                  RR4      pVP                  R	R
4      p	VP                  RR4      p
VP                  RR4      pS'P                  R/ 4      pT;'       g    VP                  RR4      pT! TVP                  RR4      VP                  RR4      VP                  RR4      VP                  RR4      TT\        V	4      T
T;'       g    R R7
      pV! V4      p^ R Ip^ RIHp TR8X  d   RpRpM1TR 8X  d'   R!T
 2pRR"R#R$R%R&R'R(R)RR*R+/pTP                  T
R"4      pMR,pR"p. p. pS$ F>  pTP                  R-^ 4      ^ 8X  d   TP                  T4       K-  TP                  T4       K@  	  / p\        T4      \        T4      ,           p^ pT EF!  pT^,          pTP                  R.^ 4      pTP                  R/R4      pS%R0TR1 T 2,          p\        P                  ! R.TR2R3R4TR5TR6T/4      pRT R25x   TP                  TT4      G R j  xL
  TP                  R74      p T '       d   TTT &   R p! TP!                  T4      p!\#        S&TTT\%        T4      TP'                  4       TT!R8R97	      G R j  xL
  \        P                  ! R.TR2R8R4TR5TR:R;S& R<TR1 T 2R=TR>T!R6T/4      p"RT" R25x  EK$  	  T EFn  pT^,          pTP                  R.^ 4      pTP                  R/R4      pS%R0TR1 T 2,          pTP                  R7R4      p \        P                  ! R.TR2R3R4TR5TR6T/4      pRT R25x   TP                  T 4      p#T#'       d*   T#P-                  4       '       d   TP/                  T#T4       M1\(        P1                  R@T T4       TP                  TT4      G R j  xL
  R p! TP!                  T4      p!\#        S&TTT\%        T4      TP'                  4       TT!R8R97	      G R j  xL
  \        P                  ! R.TR2R8R4TR5TR:R;S& R<TR1 T 2R=TR>T!R6T/4      p"RT" R25x  EKq  	  R5x  R #  EL^  \         d    R pRpRpR
p	Rp
Rp EL
i ; i  \         d5   p\        P                  ! RRT 2/4      pRT R25x  R5x   R p?R # R p?ii ; i EL  \         d     EL`i ; i EL6  \         dV   p\(        P+                  R?S&T4       \        P                  ! R.TR2RR\%        T4      R4TR5T/4      pRT R25x   R p?EKx  R p?ii ; i ELn  \         d     ELfi ; i EL<  \         dV   p\(        P+                  R?S&T4       \        P                  ! R.TR2RR\%        T4      R4TR5T/4      pRT R25x   R p?EK  R p?ii ; i5i)ANr  get_tts_providerVoiceSettingsr  r  r   r  r  r  r  r  r  r  rG   voice_settingsr  JBFqnCBsd6RMkjVDRZzbr  r  chatterbox_languageptchatterbox_voice_ref
r  r  r  rt  rv  r  pollinations_voicepollinations_speedpollinations_formatr  r   TTS provider not available: r  r  r  r   .wav	audio/wavr  .
audio/mpegopus
audio/opusaac	audio/aacflac
audio/flacwavpcm	audio/pcm.mp3r  ra  rl  r  r  r   r  r  rO  r   r  r   	r;  ra  rl  r  r`  
audio_data	mime_typerd  r   	audio_urlr  r  r  r  -TTS generation failed for project %s scene %dz@Master audio not found for group %s, generating TTS for scene %d)r   rA  ro  r  rq  r   r]   ra   floatrX   r  rS  pathlibr   r   r   get_audio_durationr5   r[   r  r_   r   rU   copy2rb   )(r  tts_provr7  ro  rq  r   db_tts_providerr  rx  ry  rz  r  rr  settingsrh   r	  rS  _Pathextr  format_mime_mapmasterssecondariesr?  master_audio_pathstotal_to_process	processedr  r  rl  
audio_pathr  	cov_groupr  done_payloadmaster_pathr
  r&  r;  rD  s(                                       r>   r  )generate_audios_sse.<locals>.event_stream  s    N+$,	2,*$7$99"-//.$"G%0__5Mx%X"%0__5Mv%V"%0__5Mu%U"&1oo6OQV&W#'27Mr'R$ $ZZ(8"=N+__~/A/A.R^/_M$*'++J8NO'++J8PQ$2$6$67Ld$S%3%7%78NPR%S#5#5#();#<$7%9%A%ATH (1H 	)L(C#In,)*+C|{{{O (++,?NIC$I Auu+Q/14q!""1%	   02w<#k*::	 ENI		.!4IyyR0H#yocU&CCJ JJ"Il	-M =/..:1''*=== "II&9:	4>&y1  ':::FH
 #)!*%!.!*o)446'%-&
 
 
  $zz&	 +"I!1#x
|>)TWY\X]%^#Y"H"M	  |nD11u \ !ENI		.!4IyyR0H#yocU&CCJ		"5r:I JJ"Il	-M =/..?1044Y?;#5#5#7#7LLj9 NNZ!!
 #++HjAAA  ':::FH
 #)!*%!.!*o)446'%-&
 
 
  $zz&	 +"I!1#x
|>)TWY\X]%^#Y"H"M	  |nD11A !f *)[ :  *"&%-"%+"%*"&+#')$*6  	**g1McU/S%TUK;-t,,--		z > ! 
4  1  C
 #jj&	 'S"I!1 {m40001` B ! 
4  1  C
 #jj&	 'S"I!1 {m40001sW  W%R- R RA0R R- :A/R- *R- :DW%T)S/*TTS2 .TT<TBW%.V=?V<U*=VU-.VU?<V W%R R*&R- )R**R- -S,8)S'!W%'S,,W%/T2T=T TTU'A	U"W%"U''W%*V-U<8V;U<<VW"A	WW%W""W%r  r  r  r  r  r  )r    r   r]   r#   r   rT   r   r   )r;  rU  r_  existing_audiosr  audio_scene_numsr?  r  r
  r&  rD  s   f       @@@r>   generate_audios_sser    s     Z((D|W&9:LLXXhFW&<=3OOZZ"%FW&9:LL /z::O $))r))C778+ 	N)   A55#+;; 	
 EE*b!'') 	
N 78c
 	
 )J6AJTD1x* x*t &Z
 } ) ;sj   FF/F(F/FFFFF<F	FF-#FF
F&AFF
Fz>/api/projects/{project_id}/scenes/{scene_num}/regenerate-audioc                    V ^8  d   QhRRRR/# r  r<   )r=   s   "r>   r?   r?   	  s"     BY BYs BYs BYr@   c                |  a"   \        V 4      G Rj  xL
 pVf   \        RR/RR7      # VP                  R4      pV'       g   \        RR/RR7      # VP                  R	. 4      p\        V3R
 lV 4       R4      pVf   \        RR/RR7      # VP                  RR4      pVP	                  4       '       g   \        RR/RR7      # \
        R,          V ,          R,          pVP                  RRR7        \        4       G Rj  xL
 pVP                  RR4      p	VP                  RR4      p
VP                  RR4      pVP                  RR4      pVP                  RR4      pVP                  RR4      p ^ RI	H
p ^ RIHp VP                  R/ 4      pT	;'       g    VP                  RR 4      pT! TVP                  R!R"4      VP                  R#R$4      VP                  R%R&4      VP                  R'R4      T
T\        V4      TT;'       g    RR(7
      pV! V4      pTR 8X  d   R*pMTR+8X  d   R,T 2pMR-pTR.SR/ T 2,          p TP                  TT4      G Rj  xL
  Rp TP                  T4      pTR 8X  d   R0pM*TR+8X  d"   RR1R2R3R4R5R6R7R8R0R9R:/pTP                  TR14      pMR1p^ RIpTP#                  4       pTP%                  T4      P'                  R;4      p\)        T STT\+        T4      TTTR<R=7	      G Rj  xL
  R>R?R@SRARBT  RCSR/ T 2RDTRETRFTRGT/#  EL EL  \         d    Rp	Rp
RpRpRpRp ELi ; i  \         d   p\        RR)T 2/RR7      u Rp?# Rp?ii ; i EL  \         d     ELi ; i L  \         d4   p\,        P/                  RHT S4       \        RRIT 2/RJR7      u Rp?# Rp?ii ; i5i)Kz4Generate or regenerate TTS audio for a single scene.Nr   rQ  r   r   rD  r  r   r_  c              3  F   <"   T F  qR ,          S8X  g   K  Vx  K  	  R# 5ir  r<   r  s   & r>   rV  #regenerate_audio.<locals>.<genexpr>	  r  r  r  rl  rG   zNo TTS text for this scenerv   rp  Trw   r  r  r   r  r  r  r  r  r  r  rn  rp  rr  r  r  rs  r  r  rt  ru  rv  rw  r{  r|  r  r~  r  r  r  r}  r  r  r  r  r  r  r  r  r  r  rC   r   r  r   r  ra  r  r  r  audio_base64r  r  r   r  zTTS generation failed: r   )r    r   r]   r  r   rT   r   r   ra   rA  ro  r  rq  r  r   r  r  r  r  r  r5   r[   r_   r   )r;  r  rU  rD  r_  r  rl  r&  r   r  r  rx  ry  rz  r  ro  rq  rr  r7  r  r  rh   r  r  r  r  r  r  audio_bytesr  s   &f                            r>   regenerate_audior  	  sM     Z((D|W&9:LLXXhFW&<=3OOZZ"%FFVFME}W&78cJJyyR(H>>W&BCQTUU)J6AJTD1"/11%//.$?(__-ExP(__-EvN(__-EuM)oo.GO*/ErJ
.($4b9'[[>+=+=nl+[ &#''
4JK#''
4LM . 2 23H$ O!/!3!34JB!O11$%78 3!5!=!=
 $H- $	.	(%&'yocU;;J7Y*555	22:>H
 L(#In,|{{{O (++,?NI$I 	 ++-''4;;GD!"&*o"%

 
	
 
	
 mI8J<~i_SERL
 	
g ), 2  "%#"#!"<  
4SE:;
 	

 	6
  		0
	
*  Y;Z	
 W(?u&EFTWXX	Ys   N<L/N<A1N<5=N<3L  LA0L 2&L: A/L: 	L: (N<M; M$M; M' 0BM; 8M99M; N<L L73N<6L77N<:M!MM!N<M!!N<$M; 'M62M; 5M66M; ;N9(N4.N9/N<4N99N<z>/api/projects/{project_id}/scenes/{scene_num}/regenerate-videoc                    V ^8  d   QhRRRR/# r  r<   )r=   s   "r>   r?   r?   y
  s     z zs zs zr@   c                p  a"   \        V 4      G Rj  xL
 pVf   \        RR/RR7      # VP                  R4      pV'       g   \        RR/RR7      # VP                  R	. 4      p\        V3R
 lV 4       R4      pVf   \        RR/RR7      # \        R,          V ,          R,          pVRSR R2,          pVRSR R2,          pVP                  4       '       g   \        RR/RR7      # VP                  RR4      p	 \        4       G Rj  xL
 p
V
P                  RR4      pV
P                  RR4      pV
P                  RR4      pV
P                  RR4      pV
P                  RR4      pV
P                  RR4      pRpRpT;'       g!    \        P                  P                  R R4      pVR!8X  d*    ^ R"I
Hp T! T;'       g    RV\        V4      VR#7      pR!pM2VR%8X  d,   V'       d$    ^ R&IHp V\        P                  R &   V! 4       pR%pVfS    ^ R(IHp \'        4       G Rj  xL
 pV'       g   \        RR)/RR7      # V! VR*,          VR+,          VR,,          R-7      pRp\        P)                  R/VS4        VP+                  VV	VR07      G Rj  xL
  \-        V SV	\/        V4      R1R27      G Rj  xL
  R3R4R5S/ VP1                  4       G Rj  xL
  #  EL EL  \         d    RpRpRpRpRpRp ELzi ; i  \         d"   p\        P                  R$T4        Rp?ELRp?ii ; i  \         d"   p\        P                  R'T4        Rp?ELDRp?ii ; i EL4  \         d   p\        RR.T 2/RR7      u Rp?# Rp?ii ; i L L L  \         d     # i ; i  \         d_   p\        P3                  R6T S4       \        RR7T 2/R8R7      u Rp? TP1                  4       G Rj  xL 
  #   \         d     # i ; iRp?ii ; i   TP1                  4       G Rj  xL 
  i   \         d     i i ; i; i5i)9z2Generate or regenerate a video for a single scene.Nr   rQ  r   r   rD  r  r   r_  c              3  F   <"   T F  qR ,          S8X  g   K  Vx  K  	  R# 5ir  r<   r  s   & r>   rV  #regenerate_video.<locals>.<genexpr>
  r  r  r  rv   rp  r  r  r   r2  zImage not found for this scener1  rG   rb  rc  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r!  r#  rG  r$  r`  ra  rI  rI  zNo video provider configured: z%Using video provider: %s for scene %drJ  r   r8  r   r  ra  rK  zVideo generation failed: r   )r    r   r]   r  rT   rU   r   ra   r   r   rM  r  rj  r_   rb   rN  r"  rS  rH  r   r`   r   r4   r[   r  r   )r;  r  rU  rD  r_  r  r&  r  r[  r1  r   r_  r]  r^  r  r  r  rT  r7  r  r  rh   r"  r\  rg  s   &f                       r>   regenerate_videor  x
  s{     Z((D|W&9:LLXXhFW&<=3OOZZ"%FFVFME}W&78cJJ)J6AJfYsO488HfYsO488H??67S
 	
 99^R0L+/11)oo.>G%//*<bA)oo.DbI#.??3Mz#Z &1oo6SUX&Y#$/OO4OQW$X! JM"LLbjjnn5G&LLn,
	WW2+33t.896	J +M 

	*|	MO-9BJJ)*.0J&M 	f133G#VW #  +!+.$^4	*J
 #M KK7	R!!%  " 
 	
 	
 !"%(m
 	
 	
 mI
	""$$$m )4 2  +$ #- &)#$*!+.  	WNNPRUVV	W  	MNNFLL	M 4  	:3%@A 		
	
* % 		  
=z9	
 1#78c
 	
	""$$$ 		
	""$$$ 		s  P6K/P6BP6!P6<K 	K
A0K :P6(P60K8 K8 P6("L' 
P6M "M#M /M =P6>"M  P68N N N 0N1	N ;N	NN	P6K K51P64K55P68L$LP6L$$P6'M2MP6MP6M N $M;5N 6P6;N  P6N N N		NP6NP6P%(O>PP O-&O)'O-,P6-O;8P6:O;;P6>PP P3P"PP"!P3"P0-P3/P00P33P6z-/api/projects/{project_id}/generate-subtitlesc                   V ^8  d   QhRR/# rO  r<   )r=   s   "r>   r?   r?   
  s     u= u= u=r@   c                  "   \        V 4      G Rj  xL
 pVf   \        RR/RR7      # VP                  R4      pV'       g   \        RR/RR7      # VP                  R	. 4      p\        R
,          V ,          R,          p. pV EF  pVR,          pVP                  RR4      pV'       g   K)  Rp	R" F,  p
VRVR V
 2,          pVP	                  4       '       g   K*  Tp	 M	  V	'       Eg+   VP                  4       pV'       g   K  VP                  R^ 4      p\        V\        4      '       d]   VP                  R4      p\        V4      ^8X  d1   \        V^ ,          4      ^<,          \        V^,          4      ,           M
\        V4      pVP                  RR4      pV\        V4      ,          p\        V4       FV  w  ppVP                  RVRVR\        VVV,          ,           ^4      R\        VV^,           V,          ,           ^4      /4       KX  	  EK   ^ RIpVP                  R4      pVP!                  \        V	4      VRR7      pVP                  R^ 4      p\        V\        4      '       d]   VP                  R4      p\        V4      ^8X  d1   \        V^ ,          4      ^<,          \        V^,          4      ,           M
\        V4      pVP"                   F}  pVP$                   Fj  pVP                  RVRVP&                  P)                  4       R\        VVP*                  ,           ^4      R\        VVP,                  ,           ^4      /4       Kl  	  K  	  EK  	  R VR!\        V4      /#  ELY  \.         Ed    \0        P3                  R4        ^ RIHp TP9                  \        T	4      4      p\        T4      R,          pM#  \:         d    TP                  RR4      p Mi ; iTP                  4       pT'       g    EK  TP                  R^ 4      p\        T\        4      '       d]   TP                  R4      p\        T4      ^8X  d1   \        T^ ,          4      ^<,          \        T^,          4      ,           M
\        T4      pT\        T4      ,          p\        T4       FV  w  ppTP                  RTRTR\        TTT,          ,           ^4      R\        TT^,           T,          ,           ^4      /4       KX  	   EK~  \:         EdP   p\0        P=                  RTT4       TP                  4       pT'       g    Rp?EK  TP                  R^ 4      p\        T\        4      '       d]   TP                  R4      p\        T4      ^8X  d1   \        T^ ,          4      ^<,          \        T^,          4      ,           M
\        T4      pTP                  RR4      pT\        T4      ,          p\        T4       FV  w  ppTP                  RTRTR\        TTT,          ,           ^4      R\        TT^,           T,          ,           ^4      /4       KX  	   Rp?EK  Rp?ii ; i5i)#zGenerate word-level subtitle timestamps from TTS audio files.

Uses stable-ts for forced alignment of known TTS text with audio.
Falls back to simple word-duration estimation if stable-ts unavailable.
Nr   rQ  r   r   rD  r  r   r_  rv   rp  ra  rl  rG   r  r  
time_start:rd        @r  wordr9  endtinyru  )languagez8stable-ts not installed, using duration-based estimation)AudioSegmentg     @@z*Subtitle alignment failed for scene %d: %s	subtitlesrc   )r|  r  z.opusz.aacz.flac)r    r   r]   rT   rU   r   r3  r[   r   rj  r  r  r   r  stable_whisper
load_modelalignsegmentswordsr  r   r9  r  rC  r_   rb   pydubr  	from_filera   r   )r;  rU  rD  r_  r&  r  r  r  rl  r  r  	candidater  r  r   r  word_durrg  wr  r   	result_tssegment	word_datar  r  audio_durationrh   s   &                           r>   generate_subtitlesr  
  sZ     Z((D|W&9:LLXXhFW&<=3OOZZ"%F)J6AJI>"99Z, 
=C"vbXcU%;;I!!&
	 > zNN$E<3J*c**"((-EHZST_Sq]R/%a/AZ_`jZk
yy!3S9H#e*,H!%(1  RAU:H#<a@5q1u.@!@!D	"  ) =	!"--f5EC
OXMI<3J*c**"((-EHZST_Sq]R/%a/AZ_`jZk
$--!(I$$	 4 4 6zIOO'CQ!GuZ)--%?C	&  "/ .[ D GS^<<_ )D  	NNUVD.$..s:?!$Uf!4 D!&+=s!CD NN$E<3J*c**"((-EHZST_Sq]R/%a/AZ_`jZk
%E
2H!%(1  RAU:H#<a@5q1u.@!@!D	"  )  	I2sSNN$E<3J*c**"((-EHZST_Sq]R/%a/AZ_`jZk
yy!3S9H#e*,H!%(1  RAU:H#<a@5q1u.@!@!D	"  )(	s   YM*/YBYY(Y DYEM-Y-!Y2OYO"Y!O""Y=YC;Y<Y 	Y
Y/Y:YDYYYYz(/api/projects/{project_id}/subtitles.srtc                   V ^8  d   QhRR/# rO  r<   )r=   s   "r>   r?   r?   u  s     3 33 3r@   c                  "   \        V 4      G Rj  xL
 pVf   \        RR/RR7      # VP                  R4      pV'       g   \        RR/RR7      # VP                  R	. 4      pV'       g   \        RR
/RR7      # R R lp. p\        V^4       F  w  rgVP                  RR4      P	                  4       pV'       g   K/  VP                  RR4      p	VP                  RR4      p
VP                  \        V4      4       VP                  V! V	4       RV! V
4       24       VP                  V4       VP                  R4       K  	  RP                  V4      p\        VRRR/R7      #  ELS5i)z4Export subtitles in SRT format from production plan.Nr   rQ  r   r   rD  r  r   r_  r  c                    V ^8  d   QhRRRR/# )r9   time_strr[   r:   r<   )r=   s   "r>   r?   *export_subtitles_srt.<locals>.__annotate__  s     " "s "s "r@   c                z    V P                  R4      p\        V4      ^8X  dy   \        V^ ,          4      pV^,          P                  R4      p\        V^ ,          4      p\        V4      ^8  d*   \        V^,          P                  ^R4      R,          4      M^ pMg^ pV^ ,          P                  R4      p\        V^ ,          4      p\        V4      ^8  d*   \        V^,          P                  ^R4      R,          4      M^ pV^<,          pV^<,          pVR RVR RVR RVR 2#   \        \
        3 d     R# i ; i)	z;Convert 'MM:SS.ss' or 'MM:SS' to SRT format 'HH:MM:SS,mmm'.r  r~  0:N   Nr  ,03dz00:00:00,000)r   r   rj  ljustrb  
IndexError)r  r   minutes	sec_partssecondsmillishourss   &      r>   _time_to_srt*export_subtitles_srt.<locals>._time_to_srt  s   	"NN3'E5zQeAh-!!HNN3/	il+@CIQR@RYq\//37;<XY!!HNN3/	il+@CIQR@RYq\//37;<XYrMElGC['#a}AfS\JJJ' 	"!	"s   D"D% %D:9D:rl  rG   r  z00:00time_endz00:03z --> r   z
text/plainzContent-Dispositionz$attachment; filename="subtitles.srt")r   r  r  )	r    r   r]   r  r   r   r[   r   r   )r;  rU  rD  r_  r  	srt_linesr  r  rl  r  r  srt_contents   &           r>   export_subtitles_srtr  t  sY     Z((D|W&9:LLXXhFW&<=3OOZZ"%FW&9:LL"( I*
99Z,224YY|W5
99Z1S"L45U<;Q:RST" + ))I&K&(NO [ )s   E'E$/E'(E'+C:E'z'/api/projects/{project_id}/export-videoc                    V ^8  d   QhRRRR/# r  r<   )r=   s   "r>   r?   r?     s     K
 K
3 K
 K
r@   c                2  "   \        V 4      G Rj  xL
 pVf   \        RR/RR7      #  VP                  4       G Rj  xL
 p\        R,          T ,          pTR	,          pTR
,          pTP                  RRR7       TP                  R. 4      p/ p\        T\        4      '       dJ   T FB  p	T	P                  R4      ;'       g    T	P                  RR4      p
T	P                  R. 4      Y&   KD  	  M\        T\        4      '       d   TpTP                  R. 4      pTP                  R. 4      pTP                  R. 4      pTP                  R^ 4      pTP                  R. 4      pT'       g   \        RR/RR7      #  ^ RI
pRpRR^pppRRRRRRRR R!R"R#R$R%R&R'R(R)R*R+R,R-R.R/R0R1R/pR2R3R4R5R6R7R8R9R:R;R<R=/pR> R? lpTP                  R@/ 4      p. p. p\        TRA RB7      p\        TRC RB7      p^ p. p. p. p T EF  p!T!P                  RD4      ;'       g,    T!P                  RE4      ;'       g    T!P                  RFR4      p"T"'       g   KR  \        T"P                  RG4      ,          p#T#P                  4       '       g   \        P                  RHT#4       K  T!P                  RRI4      p$RJT 2p%\!        T#4      P#                  RK4      '       * p&T!P                  RL4      p'\%        T&;'       d    T';'       d    T'P                  RM4      4      p(T&'       g   TP'                  RN\!        T#4      .4       MNT('       d   TP'                  RN\!        T#4      .4       M)TP'                  RORPRQ\!        T$4      RN\!        T#4      .4       T('       Ed   \)        T$T,          4      p)T'P                  RRRS4      p*T'P                  RTRU4      p+T'P                  RVRW4      p,T'P                  RXRW4      p-T'P                  RYRW4      p.T'P                  RZRW4      p/TP+                  RP-                  . R[NT NR\NT^,           NR]NT^,           NR^NT* NR_NT+ NR`NT* NRaNT) NRbNT+ NRcNT, NR_NT. NR`NT, NRaNT) NRdNT- NR_NT/ NR`NT- NRaNT) NReNT) NRfNT NRgNT NRhNT NRiNT% NRjN4      4       M'TP+                  R[T R\T R]T RkT R]T RlT R[T% Rj24       TP+                  T%4       TP+                  T$4       T P+                  T!P                  RR4      4       T^,          pEK  	  \/        T4      p0T0^ 8X  d   \        RRm/RR7      # / p1T FL  p2RT2P                  RR4      RT2P                  RRW4      /T1T2P                  Rn4      T2P                  Ro4      3&   KN  	  T0^8X  d   T^ ,          p3MT^ ,          p4T^ ,          p5\1        ^T04       F  p6T T6^,
          ,          T T6,          3p7T1P                  T7RRRRW/4      p2T2R,          p8T2R,          p9TP                  T84      p:T:f   Rp:Rpp9\3        ^ T4T9,
          4      p;T6T0^,
          8  d   RqT6 2MRrp<TP+                  R[T5 RsTT6,           RtT: RuT9Rv RwT;Rv R[T< Rj24       T<p5T4TT6,          T9,
          ,          p4K  	  T5p3TP                  RxR4      p=T=T9   d$   TT=,          p>TP+                  R[T3 RjT> Ry24       Rzp3TP                  R{T4      p?\5        T?4      P                  4       '       g   Tp?TP                  R|^x4      p@TP                  R}R~4      pATP                  RR4      pBTP                  R^4      pC. pDT F  pETEP                  R^ 4      pFTEP                  R. 4       Fx  pGTGP                  RR4      P7                  4       pHTH'       g   K-  XDP+                  RT! XH4      RXFXGP                  R^ 4      ,           RTFTGP                  R^ 4      ,           /4       Kz  	  K  	  XD'       dx   . pIXD FD  pGXIP+                  RTGR,           RT? RX@ RXA RXC RXB RTGR,          Rv RbTGR,          Rv R24       KF  	  RbP-                  XI4      pJTP+                  R[T3 RjTJ R24       Rp3. pK. pLT F  p!T!P                  RFR4      p"T"'       g   K  \        T"P                  RG4      ,          p#T#P                  4       '       g   KS  TP'                  RN\!        T#4      .4       XKP+                  T4       XLP+                  T!P                  RR4      4       T^,          pK  	  RpMXK'       EdU   \/        XK4      ^8X  d   XK^ ,           R2pMEM6T'       g<   RP-                  R XK 4       4      pNTP+                  TN R\/        TK4       R24       RpMMXK^ ,           R2pO\1        ^\/        TK4      4       F  p6RWp9T6^,
          \/        T 4      8  dk   T6\/        T 4      8  d[   T T6^,
          ,          T T6,          3p7T1P                  T74      p2T2'       d)   T2R,          p8TP                  T84      e   T2R,          p9MRpp9T6\/        XK4      ^,
          8  d   RT6 2MRpPTP+                  R[XO RsXKT6,           RT9Rv R[TP Rj2	4       TPpOK  	  RpMRP-                  T4      pQRR.pRTRP'                  T4       TRP'                  RTQ.4       TRP'                  RR[T3 Rj2.4       XM'       d   XRP'                  RR[XM Rj2.4       XRP'                  RRRRRRRRRRRRR\!        T4      .4       \        P9                  RRP-                  TR4      4       \:        P<                  ! TRR\:        P                  P>                  R\:        P                  P>                  / G Rj  xL
 pSTSPA                  4       G Rj  xL
 w  pTpUXSPB                  ^ 8w  d?   XUPE                  RRR7      RR pV\        PG                  RTV4       \        RRTV 2/RR7      # RT  R2pWRRRTWRTPI                  4       PJ                  /#  EL EL  \         d    \        RR/RR7      u # i ; i L L  \L         d    \        RR/RR7      u # \         d3   pX\        PO                  RT 4       \        RRTX 2/RR7      u RpX?X# RpX?Xii ; i5i)zExport final video using FFmpeg server-side composition.

Receives editor project JSON with clip timings, effects, and settings.
Composes all video/image/audio clips into a single MP4.
Returns download URL when complete.
Nr   rQ  r   r   zInvalid JSON bodyr   rv   rp  final_export.mp4Trw   tracksrQ   r5  rG   clipsr  r  subtitler  transitionszNo video clips in projectz(/usr/share/fonts/TTF/DejaVuSans-Bold.ttfi8  i  fade	crossfadez
slide-left	slideleftzslide-right
sliderightzslide-upslideupz
slide-down	slidedownzoomsmoothupz
cross-zoom
smoothdownspin
circleopenz	wipe-leftwipeleftz
wipe-right	wiperightzcircle-wipe
circlecropcutwarmz9eq=brightness=0.04:saturation=1.3:gamma_r=1.1:gamma_b=0.9coolz9eq=brightness=0.02:saturation=1.1:gamma_r=0.9:gamma_b=1.1	cinematicz/eq=brightness=-0.05:contrast=1.2:saturation=0.9vibrantzeq=saturation=1.5:contrast=1.1bwzeq=saturation=0vintagez+eq=brightness=0.06:saturation=0.7:gamma=0.9c                    V ^8  d   QhRRRR/# )r9   textr[   r:   r<   )r=   s   "r>   r?   "export_video.<locals>.__annotate__  s     	 	S 	S 	r@   c                    V P                  RR4      p V P                  RR4      p V P                  RR4      p V P                  RR4      p V # )	z)Escape special chars for FFmpeg drawtext.r  z\\'z'\''r  z\:%z%%)replace)r   s   &r>   _sanitize_drawtext(export_video.<locals>._sanitize_drawtext  sG    <<f-D<<W-D<<U+D<<T*DKr@   effectsc                &    V P                  R ^ 4      # 	startTimer  r   s   &r>   r  export_video.<locals>.<lambda>      quu[RS?Tr@   )r   c                &    V P                  R ^ 4      # r
  r  r  s   &r>   r  r    r  r@   videoUrlimageUrlsrcrz   zExport: missing file %sr  r   r2  kenBurnsenabledz-iz-loopr  z-t
startScaleg      ?endScalegffffff?startXg      ?startYendXendY[z	:v]scale=r  z,zoompan=z='min(z+(-z)*on/r  z
)':x='iw*(z)-iw/zoom/2':y='ih*(z)-ih/zoom/2':d=z:s=xz:fps=z
,setsar=1[]z*:force_original_aspect_ratio=decrease,pad=z(:(ow-iw)/2:(oh-ih)/2:black,setsar=1,fps=zNo valid video sources found
fromClipIdtoClipIdgMbP?xfvxfadez][z]xfade=transition=z
:duration=z.3fz:offset=colorGradingz	[vgraded]vgradedfontPathfontSize	fontColorwhitestrokeColorblackstrokeWidthr  r  r  r   r9  r  endTimezdrawtext=text='z':fontfile=z
:fontsize=z:fontcolor=z	:borderw=z:bordercolor=z1:x=(w-text_w)/2:y=(h-text_h)/2:enable='between(t,z)'z[vsub]vsubz:ac              3  .   "   T F  pR V R2x  K  	  R# 5i)r  z:a]Nr<   )rT  r  s   & r>   rV  export_video.<locals>.<genexpr>  s     E!C5s   z	concat=n=z:v=0:a=1[aout]aoutaxfz:a]acrossfade=d=;ffmpegz-yz-filter_complexz-mapz-c:vlibx264z-presetmediumz-crf23z-c:ar  z-b:a192kz	-movflagsz
+faststartz	-shortestzFFmpeg export command: %sr   stdoutstderrrC   r  )errorsr   zFFmpeg export failed: %szFFmpeg export failed: r  z/final_export.mp4r   rB  download_url	file_sizez5FFmpeg not found. Install it: sudo apt install ffmpegz"Video export failed for project %szExport failed: i)(r    r   rX   ra   rT   r   r]   r3  r4  dict
subprocessrV   lstriprU   r_   rb   r[   endswithr   extendrj  r   r   r   rangerd  r   r   r`   r   create_subprocess_execPIPEcommunicate
returncoder  r   r  r  FileNotFoundErrorr   )Yr;  r   rU  editor_datar&  
assets_direxport_path
raw_tracks	track_mapttidvideo_clipsaudio_clipssubtitle_clipsr  r  r>  DEFAULT_FONTWHFPS	XFADE_MAPCOLOR_PRESETSr  r  inputsfilter_partsvideo_clips_sortedaudio_clips_sorted	input_idxvideo_labelsclip_durationsclip_idsclipr  r`  clip_durationrH  is_imagekbuse_ken_burnsframess_scalee_scales_xs_ye_xe_yntrans_lookuptr	vid_labelcum_durprevrg  r   tr_typetr_durffmpeg_nameoffsetoutcolor_preset	eq_filter	font_path	font_size
font_colorstroke_colorstroke_width	all_wordssub_clip
clip_startr  	word_textdt_partsdt_chainaudio_inputsaudio_clip_ids	aud_labelarefsprev_aout_afilter_complexcmdprocr8  r9  	error_msgr;  rh   sY   &&                                                                                       r>   export_videor    s     Z((D|W&9:LLM#LLN* )J6Jh&J11KTD1 2.JI*d##A%%+22vr!2CUU7B/IN  
J	%	%	--,K--,K]]:r2Nz1-H//-4KW&ABPSTTc
 B$c1 FK+}l	<JlL\;<4	
	 TTJ9*F
	 //)R0  $K5TU#K5TU	 'D((:&UU$((:*>UU$((5RTBUC%

37I##%%8)D HHZ5M	{OEy>226::H*%B !F!Fb!F!FRVVI5FGMtS^45tS^45 wT3}3EtSQZ^\]}]S01&&s3&&T2ffXs+ffXs+ffVS)ffVS)##) )a )	{ )) )AaC5 ) )!A# ) 7& )&-Y).0)18	)9:);B))CH)IO)PQ)RYQZ)[)"e)#%)&)U)*+),/5)05)6<X)>)  #e) $&) '*U) +,) -05) 16) 7=X)>) !	) "%	) &'C	) ()	) *+	) ,1	) 25	)6 	)
 !&w)
 '() ##	{)A3as 3#Qqc "$$'5%3 &!!-0OODHHT2./NIk 'n 6*H IWZ[[ Bvv.BFF:s3HL"&&.z0BCD  6$QI$Q'G?D1a[A4!%%cFFJ+LMV*J'mmG4&"(K"FQ& 01"#a!e)1#h##vRQ00B;- HVCL#aI >!,v55' !( I {{>26=(%l3I!I;a	{) DE!I KK
L9	I%%''$IKK
C0	[[g6
{{=':{{=!4	&H!k15J\\'2.EE&"-335	   .y9Z!%%Q*??:i(;;" 	 / ' H%ai[ 1!!* !*~]<.**+G*S)91U8C.L  xx)H!I;az @AI &D((5"%C%

37I##%%MM4Y01	*!!$((4"45NI ' 	<< A%+A/r2	 EEE##ugYs<7H6I$XY"	 )O,B/q#l"34A F1us8},S]1B'A<)--c2&(jG(}}W5A)+J).)*S->-B)Bc!IE ''F82l1o%66FvclRSTYSZZ[\ #F# 5$ #	 ,/

6

%~67

Fa	{!,-.JJ!I;a 012

IxDEF	
 		 	/#?33
%%**
 %%**
 

  $//11??agi@GILL3Y?29+>?S  "*->?kL))+33
 	
k	 )
 + MW&9:LLM@	

 2   
MN
 	
  
=zJu-.C
 	

s3  rprp pp A?rB%r(r8Bp< p< %p<  3p< 4A,p< !	p< +p< 	$p< .Ap< =F0p< -r.J=p< ,Cp< :A'p< "%p< B9p< Cp< B/p< =p8>p< p:Ap< +r,%p< rp p52r4p55r8p< :p< <rrr!r"'r	r
rrrz(/api/projects/{project_id}/export-statusc                   V ^8  d   QhRR/# rO  r<   )r=   s   "r>   r?   r?      s       r@   c                  "   \        V 4      G Rj  xL
 pVf   \        RR/RR7      # \        R,          V ,          pVR,          VR,          VR	,          R,          .pV F[  pVP                  4       '       g   K  R
V RRR\	        VP                  \        4      4      RVP                  4       P                  RR/u # 	  R
V RRRRR^ RR/#  L5i)z3Check if an exported video exists and its metadata.Nr   rQ  r   r   rv   r  zfinal_video.mp4rp  r;  exportedTr`  rb  export_availableF)r    r   rT   rU   r[   relative_tor  r  )r;  rU  r&  
candidatesre   s   &    r>   get_export_statusr    s      Z((D|W&9:LL)J6J 	''&&X 11J ;;==jDS!1!1-!@A!499;#6#6"D   	jET1E / )s   CCA$C;ACz/ws/pipeline/{project_id}c                    V ^8  d   QhRRRR/# )r9   wsr   r;  r[   r<   )r=   s   "r>   r?   r?   '  s     G G) G Gr@   c                j  a"a#a$a%a&"   V P                  4       G R j  xL
  ^ R Ip\        VP                  4       4      p V P	                  4       G R j  xL
 pVP                  RR4      o&VP                  RR4      pVP                  RR4      pVP                  RR4      p\        VP                  R^4      4      pVP                  R	R
4      p\        VP                  R^4      4      p	VP                  RR4      p
VP                  RR4      pVP                  RR4      pVP                  RR4      pS&P                  4       '       gR   V P                  RRRR/4      G R j  xL
  V P                  4       G R j  xL
    V P                  4       G R j  xL
  R # R pV'       d   \        V4      G R j  xL
 pV'       g   V'       d   \        V4      G R j  xL
 p\        \        R,          V,          4      p\        4       G R j  xL
 pVP                  R4      '       d   VR,          \        P                   R&   VP                  R4      '       d   VR,          \        P                   R&   VP                  R4      '       d   VR,          \        P                   R&    ^ RIHp R pV'       d@   T! R?/ VP'                  4        UUu/ uF  w  ppVVP(                  9   g   K  VVbK  	  uppB p\+        TV'       g   TMR VVVVV	V
VVVR7      o"T'       d
   TR ,          MTp\-        TR!TR"TS&R#,          R$7      G R j  xL
  \.        P0                  ! 4       o#R% T#3R& llp\3        S"TR'7      o$T"T#T$T&3R( lp\.        P4                  ! T! 4       4      p S#P                  4       G R j  xL
 pTf   MTP7                  R)R*7      pTP8                  R+8X  dg   TP:                  '       dU   R,TP:                  R- R.2p\        \=        T4      R/,          T,          4      p\?        TTP:                  TR0R17      G R j  xL
   T P                  T4      G R j  xL
  K  TG R j  xL
 pTP7                  4       p\E        TR24      G R j  xL
  \G        TTTPH                  R37      G R j  xL
  TPJ                   F  o%\M        T4      G R j  xL
 p \O        T%3R4 lT  4       R 4      p!T!'       d=   \?        TS%PP                  S%PR                  T!R5,          T!R6,          R77      G R j  xL
  Kp  \?        TS%PP                  S%PR                  R8R97      G R j  xL
  K  	  T P                  RR:R;T/4      G R j  xL
   T P                  4       G R j  xL
  R #  ELb EL/ EL' EL EL  \         d     R # i ; i EL EL ELu uppi   \         dx   pT P                  RRR\        T4      /4      G R j  xL 
  T P                  4       G R j  xL 
   R p? T P                  4       G R j  xL 
  R #   \         d     R # i ; iR p?ii ; i EL EL EL EL  \@         dA    TPC                  4          T P                  4       G R j  xL 
  R #   \         d     R # i ; ii ; i EL; EL EL EL EL EL_ ELA  \@         d0    \T        PW                  R<T4       \E        TR=4      G R j  xL 
   ELx\         d   p\T        PY                  R>T4        \E        TR4      G R j  xL 
  M  \         d     Mi ; i T P                  RRR\        T4      /4      G R j  xL 
   R p?EL  \         d	      R p?EL i ; iR p?ii ; i EL  \         d     R # i ; i   T P                  4       G R j  xL 
  i   \         d     i i ; i; i5i)@NstoryrG   modeplancharacter_id	characterskeletonframes_per_minuteenable_coverage_shotsFcoverage_angles_per_scenecoverage_moder  r  r  rt  ru  rv  
event_typer   rA  zNo story providedrv   r   r   r   r   r   r   )CharacterTemplate)r  r  character_templater&  r  r  r  r  r  rt  rv  rE   runningr  :N   N)rQ   r   r  r  r  story_previewc                    V ^8  d   QhRRRR/# )r9   rY  r   r:   r;   r<   )r=   s   "r>   r?   !ws_pipeline.<locals>.__annotate__  s     	* 	*M 	*d 	*r@   c                *   < SP                  V 4       R# )z/Callback invoked from the sync pipeline thread.N)
put_nowait)rY  event_queues   &r>   on_eventws_pipeline.<locals>.on_event  s    ""5)r@   )r  c                   <"    \         P                  ! SP                  S4      G R j  xL
 p \        V SP                  4       \        V SP                  4       V SP                  R 4       #  LC  SP                  R 4       i ; i5irL  )r   r   runr   r&  r   r  )r  cfgr  pipeliner  s    r>   run_in_thread"ws_pipeline.<locals>.run_in_thread  sj     -$..x||UCCdCNN3$/ &&t, D &&t,s,   B$A/ A-1A/ B-A/ /BBT)exclude_noneimage_generatedr  r  r   rp  r   )r;  ra  r`  r   rB  )rn   c              3  Z   <"   T F   qR ,          SP                   8X  g   K  Vx  K"  	  R# 5ir  )ra  )rT  rg  r  s   & r>   rV  ws_pipeline.<locals>.<genexpr>  s#     NFq&75;M;M&MFs   +
+r`  r   r  rc  )r;  ra  r  r   rD  rg   zWebSocket disconnected: %sdisconnectedzPipeline error for project %sr<   )-r  rS   r[   r\   receive_jsonr]   rj  r   	send_jsonr  ra   r   r   rT   r   r   r   r  r  r   model_fieldsr   r*   r   rP  r   rQ  
model_dumpr  image_scene_numberr   r3   r	   cancelr2   r1   rn   r_  r!   r  ra  r  r_   r`   r   )'r  r;  rS   config_datar  r  character_namer  r  r  r  r  rt  rv  	char_dataproject_output_dirr   r  char_templater   r   rh   resolved_namer  r  pipeline_taskrY  evt_dictimg_fileimg_full_pathr  	plan_dictrY  img_rowr  r  r  r  r  s'   &&                                @@@@@r>   ws_pipeliner  &  s    
))+ TZZ\"JOO-- __Wb1OOFF3'OONB?)ook:F!$[__5H"%M!N&1oo6Mu&U),OO7;*
! )___eD'OONLI#.??3H$#O$/OO4JB$O{{}},,gyBUVWWW((*L	((*I 	+L99I^3NCCI !!9J!FG 011??;''&1+&>BJJ{#??+,,+67G+HBJJ'(??.//.9:M.NBJJ*+	0 M 1 ! %.OO$5$5DAq 1 > >> 1$5! 0=.4#0-"3&;*C+)$7%9C( .7	&)N#+
 	
 	
 <C==?	* 	* C(3		- 		-  ++MO< %//++E}''T':H #449Q9Q9Q#E$<$<S#AF #D);$<x$G($R S")!&!9!9+&	  ll8,,, #" OO%	#J<<<#J	LLL [[E-j99FNFNG ")!&!3!3!&!3!3%k2"8,   #)!&!3!3!&!3!3$	  ! !0 llh	
 	
 	
*	((*I  .$ XP  		G :C 2(  	,,gy#c(KLLL((*f	((* 		q		
D , -& $$&p	((* 		y
 # 	=L :	
  @0*=#J??? 	8*E	'
G<<< 			,,gy#c(KLLL 			  			((* 		s  ^3U=!^3Z! V D
Z! VZ! 4V5Z! ;V V	V ^3	Z! Z! -V.Z! :Z! Z! V!.Z! ?V$ Z! 0Z! 0Z! =Z! V- (V- ?V'V'!&V- Z! &Z! 5X26A'Z! X5=Z! AZ! +X8,Z! 1X> X;X> 
Z! Z#Z! 5Z6Z! Z!Z! 7Z8AZ! Z,Z! <Z= Z! ZZ! #]1 6].7]1 ;^3 Z! Z! Z! 	V V^3V^3Z! !Z! $Z! 'V- -X/8!X*WX*2W53X*8Z! =X XX ^3X'#^3&X''^3*X//Z! 5Z! 8Z! ;X> >Z	Z! Y6 .Y1/Y6 4^36Z^3Z^3Z		Z! Z! Z! Z! Z! Z! Z! !0]+[]+^ ]+#]+$]&;\
\\]&\]&\]&#!]]]
^ ]#]&^ "]##]&&]++^ .]1 1^ <^3?^  ^3^0^^^^0^-*^0,^--^00^3)r   )__doc__
__future__r   r   rX   loggingr   sys
contextlibr   r  r   fastapir   r   r   r	   fastapi.middleware.corsr
   fastapi.responsesr   r   r   r   fastapi.staticfilesr   __file__r  parentrT   r[   re   insertconfigr   r   r  r   r   output_formatterr   r   r  r   web.database_pgr   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   	getLogger__name__r_   _WEB_DIRr|   ri   rm   rk   add_middlewaremount_OUTPUT_DIRr   r]   r}   r   r   r   r   postr   r)  r   deleter   r   r   r   r   r  r  r(  r8  rE  rZ  rh  rl  rx  r  r  r  r  r  r  r  r  r  r2  patchr9  rJ  rM  rV  r\  r  r  r  r  r  r  r  ri  r  r  r  r  r  r  r  	websocketr  r<   r@   r>   <module>r     s   #    	 
 *  D D 2 U U + X&&(//66}SXX%HHOOAs=)* 9 . 5                  D 
		8	$ >!!#**! NF   /8T   %%%   		)[3{+;<8	 L h&   $  . 		)[3{+;<8	 L 9 9 ; ; 	5 5 	! ! 	$% & 
$/ $/N 	$%#( &#(L '(0 )0 
89+U :+U\ 	./) 0) 4 	 ( 
'; ';T 	#$BH %BHT 	 !
 "
 
!"1 #1h 
)*3B +3Bv 	%& ', 
&'C (CL 56; 7; 
/02B 12Bj 	%&FB 'FBX 
"#  $ F 	&')B ()BX 
&'$ ($N 
,-S .S@ 
*+ c , cF 
,-e .e@ 	*+)B ,)BX X Xv /43 43n #$N %N. 	 !@ "@F " " ()3 *3  	%& ' 	,-W .Wt 	78> 9>B 	12' 3'  
AB= C= AB< C<$ 
DE`W F`WP 
67J 8Jd 
67d 8dX	 
67g 8gT	 
JKBY LBYJ 
JKz LzD 
9:u= ;u=p 	343 53v 
34K
 5K
\
 	34 5L *+G ,Gr@   