
    F"%j<                       d dl mZ d dlZd dlZd dlmZ d dlmZ d dlm	Z	 d dl
mZmZ d dlmZ d dlmZmZmZmZmZmZmZmZ d d	lmZmZ d
ZdZdZg dZd1dZd2dZ d3dZ!d4dZ"d5dZ#d4dZ$d6d!Z%d7d&Z&d8d9d*Z'd:d+Z(d;d<d/Z)d:d0Z*dS )=    )annotationsN)Path)Any)HTTPException)Sessionselect)get_settings)ActivityEvent
ApiCallLogPlatformAccount	PostDraftProviderTikTokUploadAttempt
VideoAssetnow_utc)redact_jsonredact_upload_urlz"/v2/post/publish/inbox/video/init/zvideo.uploadFILE_UPLOAD)z#this small fee can expose your cardz(if you call this number, the scam startsu0   login prompt you didn’t start? don’t approvez,login prompt you didn't start? don't approvevideor   returnPath | Nonec                    | j         sd S t          | j                   }|                                s(t          j                    |z                                  }|S N)	file_pathr   is_absolutecwdresolver   paths     U/home/agent/projects/AutoShorts_Dashboard/backend/app/services/tiktok_verification.py_resolve_media_pathr!      sU    ? t  D -

T!**,,K    boolc                    t          |           }t          |oD|                                o0|                                o|                                j        dk              S )Ni@ )r!   r#   existsis_filestatst_sizer   s     r    _has_existing_mediar)   $   sM    u%%D[[4<<>>[diikk>QT[>[\\\r"   draftPostDraft | Nonec                `    t          | o| j        o| j                                                  S r   )r#   captionstrip)r*   s    r    _has_captionr/   )   s*    A%-AEM,?,?,A,ABBBr"   intc                    | j         pd                                }t          t                    D ]\  }}||v r|c S t	          t                    S )N )working_titlelower	enumerateRECORDING_DEMO_TITLE_PRIORITYlen)r   titleindexneedles       r    _title_priorityr;   -   s]     &B--//E"#@AA  vU??LLL ,---r"   sessionr   *tuple[VideoAsset | None, PostDraft | None]c                   |                      t          t                                                              }|                      t          t                                        t          j        t          j        k                                                        }d |D             dfd}d |D             }|	                    |d	           |D ]@}
                    |j                  }|r"t          |          r|j        pd
dk    r||fc S A|D ]3}
                    |j                  }|rt          |          r||fc S 4|D ])}|j        dv r|
                    |j                  fc S *|                      t          t                                        t          j                            g d                                        t          j                                                                      d                                                    }||r
                    |j                  ndfS )a0  Pick the cleanest real short for the TikTok recording stage.

    The recording page should not use the tiny Sprint 8.2 ffmpeg smoke-test clip
    when real prepared packages exist. Prefer real packages with TikTok captions,
    meaningful duration, existing media, and known visually useful titles.
    c                    i | ]
}|j         |S  )video_asset_id).0r*   s     r    
<dictcomp>z/select_recording_demo_video.<locals>.<dictcomp>>   s    FFFee*EFFFr"   r   r   r   -tuple[int, int, int, int, int, int, int, str]c                   
                     | j                  }t          | j        pd          }t	          | j        pd          }t          |           }t          |          }t          |           }| j	        pd
                    d          rdnd}|dk    rdnd}| j        dv rdnd}	|rdnd|rdnd||rdnd|| |	|dd| j        r| j                                        nd fS )	Nr   r2   package_real_   
   >   	in_review	scheduledneeds_metadataready_for_reviewuploaded_private012d:)getidfloatduration_secr0   	file_sizer)   r/   r;   
package_id
startswithstatus
created_at	isoformat)r   r*   durationsize	has_mediahas_draft_captiontitle_priorityreal_packagelong_enoughreadyishdraft_by_videos             r    scorez*select_recording_demo_video.<locals>.score@   s)   ""58,,+0q115?'a(('..	(//(//"-3??PPWqqVW#b==aaa(|||11  CD AAA")AA!AAOUUU5;KS5+55777QSUU	
 		
r"   c                0    g | ]}t          |          |S r@   )r)   )rB   r   s     r    
<listcomp>z/select_recording_demo_video.<locals>.<listcomp>V   s&    JJJE/B5/I/IJ%JJJr"   T)keyreverser   rH   >   rI   rJ   rK   rL   rM   )rL   rI   rK   importedrM   rJ   rG   N)r   r   r   rD   )execr   r   allr   whereproviderr   tiktoksortrP   rQ   r/   rS   rW   in_order_byrX   desclimitfirst)	r<   videosdraftsrc   
candidatesr   r*   fallbackrb   s	           @r    select_recording_demo_videorx   5   sf    \\&,,--1133F\\&++11)2D2WXXYY]]__FFFvFFFN
 
 
 
 
 
, KJVJJJJOOtO,,,    ""58,, 	 \%(( 	 e.@.EA-K-K%<    ""58,, 	 \%(( 	 %< 7 7<ooo.,,UX666666 p||z	z $$  &F  &F  &F  G  G  
H  
H	*',,..	/	/	q	 
 egg  J^''444dJJr"   c                *   | j         r| j         S | j        r}t          | j                  }|                                s(t          j                    |z                                  }|                                r|                                j        S dS )Nr   )	rT   r   r   r   r   r   r%   r'   r(   r   s     r    _video_sizerz   l   s      'EO$$!! 	1HJJ%..00D;;== 	'99;;&&1r"   r[   dict[str, int]c                h    | r| dk     rt          | d          nd}| |k    rdn
| |z   dz
  |z  }| ||dS )Ni   rG   )
video_size
chunk_sizetotal_chunk_count)max)r[   r~   totals      r    _chunk_planr   y   sT    !%U$*@*@T1oJ##AA$*;a*?J)NEjuUUUr"   r   modestrdict[str, Any]c                    t          t          |                     }t          t          |t          |j        p|j        p| j        ddddddt          i|dd          S )NSELF_ONLY_DRAFTF)r8   privacy_leveldisable_duetdisable_commentdisable_stitchsourcez
[REDACTED])endpointr   scope	post_infosource_infoauthorization)	r   rz   r   TIKTOK_UPLOAD_ENDPOINTVIDEO_UPLOAD_SCOPEr-   r8   r3   FILE_UPLOAD_SOURCE)r   r*   r   plans       r    _redacted_requestr      s    {5))**D*#]HekHU5H.!$#
 
 (

 &    r"   attemptr   VideoAsset | Nonec                    |                      d          }|r|j        |d<   |j        |d<   |r|j        |d<   |j        |d<   t
          |d<   |S )Njsonr   video_titlevideo_candidate_idr-   hashtagsr   )
model_dumpr3   candidate_idr-   hashtags_jsonr   )r   r   r*   datas       r    _attempt_payloadr      sj    6**D 8#1]%*%7!" /-Y .Z-DKr"   c                   t                      }|                     t          t                                        t          j        t          j        k                                                        }t          |j
        o|j                  }|                     t          t                                        t          j                                                                      d                                                    }|                     t          t$                                        t$          j        dk                                  t$          j                                                                      d                                                    }t'          |           \  }}ddddddd|d uddddd	ddd
dddt          |          ddddddddt)          d                                          p t)          d                                          ddddg}g }	|s|	                    d           |s|	                    d           i ddd|r|j        dv rdndd|rdnddddt0          d t2          d!|r|d"         j        nd#d$|d%t          |j
                  d&t          |j                  d'|r,|d"         j        r|d"         j                                        nd d(|r|j                                        nd d)|r |j        r|j                                        nd d*|r|j                                        nd d+|r|                    d,-          nd d.|r|                    d,-          nd d/|r|                    d,-          nd ||	t          |o|j        dv           dt          |o|o
|j        d0k              |d1d2S )3NrG   rm   z0Produktname und Website-Copy sind creator-facingT)labelokzNur Scope video.upload sichtbaru   Vorbereitetes Video verfügbarzTikTok-Text ist bearbeitbarz$Synthetic-Media-Offenlegung sichtbarzZustimmung ist erforderlichz Upload-Draft-Ablauf funktioniertu   Protokolle sind geschwärztzKeine Secrets sichtbarz)Website-/Domain-Entscheidung dokumentiertz*../docs/tiktok-verification-domain-plan.mdz'docs/tiktok-verification-domain-plan.mdz-Sandbox fehlt klar markiert oder konfiguriertzTikTok Sandbox not configured. Demo can run in simulated API mode for UI recording, but final review video should use sandbox credentials if available.z8No TikTok sandbox account is connected in the dashboard.r8   zTikTok Verification DemorW   >   mocksandboxzReady to recordz	Not readyr   SandboxMock	real_modeDisabledrequested_scopeupload_methodconnected_tiktok_accountr   zsandbox / not connectedsandbox_configuredclient_id_presentclient_secret_present
last_oauthlast_upload_initlast_upload_transferlast_status_checklast_attemptr   r   current_test_videorecording_demo_draftr   )ready_to_recordready_for_internal_rehearsal!ready_for_tiktok_submission_video	checklist)r   blocking_issues	readiness) r	   ri   r   r   rk   rl   r   rm   rj   r#   tiktok_client_idtiktok_client_secretr   rp   rX   rq   rr   rs   r   rx   r   r%   appendr   r   r   display_namelast_successful_api_callrY   transfer_status
updated_atr   )
r<   settingsaccountsr   r   last_apirecording_videorecording_draftr   blockings
             r    tiktok_config_statusr      s   ~~H||F?3399/:RV^Ve:effggkkmmHh7YH<YZZ<<': ; ; D DEXEcEhEhEjEj k k q qrs t tuu{{}}L||F:..44Z5HH5TUU^^_i_t_y_y_{_{||  C  C  DE  F  F  G  G  M  M  O  OH'B7'K'K$O_DDQQ34@@2/QU:UVV/t<<8EE/t<<4D<N<NOO/t<<*$77=TJvEwEwE~E~  FA  FA  F}  EI  Js  Et  Et  E{  E{  E}  E}  	~  	~ANNI H s  r  	s  	s  	s TRSSS+|q8IM`8`8`##fq 	/;		V 	Z	
 	- 	+ 	#$gHQK$<$<Ng 	0 	T(";<< 	 h&C!D!D 	(  FW_`aWbW{  Fhqk:DDFFF  BF 	<YL3==???UY 	| ~XdXt ~ 7 A A C C Cz~ 	RX0::<<<d 	V//V/<<<RV  	bo88f8EEE^b!" 	? d : : : G G G`d#$ ##L$]\5FJ]5]^^,0156H6|\6|^j^os|^|1}1}"	
 
)   r"   post_draft_idpayloaddict[str, Any] | Nonec                v   |pi }|                      t          |          }|st          dd          |j        t          j        k    rt          dd          |                      t          |j                  }|st          dd          |                     d          st          dd          |                     dd	          }|d
vrt          dd          |dk    rt          dd          t                      }t          |j
        o|j                  }|}|dk    r|st          dd          |                     t          d|j        dd|t          t           d                     t#          |||          }	dt%          j        |j        |j        z   t)          t+          j                              z                                                                             d d          }
|d	k    r_d|
t3          d          ddd}t5          |j        |j        |j        d	t          t           |
ddddd|	|          }t9          d t:          d!d"|	|#          }d$|_        |
|_        |                     |           |                     |           |                     |           |                     |           |                     t          d%|j        d&d'|
dd(                     |                     t          d%|j        d)d*d	di                     |                                   | !                    |           tE          |||          S d+dd,d-d.}t5          |j        |j        |j        dt          t           d/d0|	|d1d23          }t9          d t:          d!d4|	|d15          }|                     |           |                     |           |                     t          d%|j        d6d7d8d1i                     |                                   | !                    |           tE          |||          S )9Ni  zDraft not foundi  zNot a TikTok draftzVideo not foundconsent_confirmedzRExplicit creator consent is required before creating a TikTok Upload Draft attemptr   r   >   r   r   real_disabledzUnsupported TikTok demo moder   zRDirect Post is not enabled. This verification flow demonstrates Upload Draft only.r   zCTikTok Sandbox not configured; use mock mode for internal rehearsalr   tiktok_demo_startedz TikTok verification demo started)r   r   r   )entity_type	entity_id
event_typer   payload_jsonmock_publish_   TzEhttps://upload.tiktok.mock/inbox/video?upload_token=mock-secret-tokenmock_uploaded_to_draftz%No external TikTok API call was made.)r   
publish_idupload_url_redactedrW   messagemock_file_transfer_succeededdraft_created)r   rW   )rA   r   platform_account_idr   r   r   r   upload_statusr   status_fetch_result_jsonrequest_redacted_jsonresponse_redacted_jsonrm   POST   )rl   r   methodstatus_coder   r   tiktok_mock_draft_createdtiktok_upload_attempttiktok_upload_init_mockedzTikTok Upload Draft mocked)r   r   tiktok_file_upload_succeededzMock file transfer succeededF*sandbox_configured_but_oauth_not_connectedzrSandbox credentials are present, but token exchange/upload transfer is not implemented in this local verifier yet.)r   r   rW   r   sandbox_not_connectednot_startedsandbox_oauth_not_connectedz<Sandbox credentials present, OAuth/token flow not connected.)rA   r   r   r   r   r   r   r   r   r   
error_codeerror_messagei  )rl   r   r   r   r   r   r   tiktok_upload_failedzTikTok Sandbox upload blockedreason)#rP   r   r   rl   r   rm   r   rA   r	   r#   r   r   addr
   rQ   r   r   r   hashlibsha256r   uuiduuid4encode	hexdigestr   r   r   r   r   rW   external_tiktok_idcommitrefreshr   )r<   r   r   r*   r   requested_moder   r   r   request_jsonfake_idresponse_jsonr   api_logs                 r    create_tiktok_draft_attemptr     s3   mGKK	=11E 4C!2333~((C!5666KK
E$899E 4C!2333;;*++ wC!uvvv[[00NAAAC!?@@@((C!uvvv~~Hh7YH<YZZDy!3C!fgggKK'UXRg  pR  jn  yK  Wi  aj  aj  k  k  k  l  l  l$UE488Lsgneh.AC
DUDU.U-]-]-_-_``jjllmpnpmpqssGv~~!#45|#}#}.>
 
 & 8( % 9$%2:.2o%N%N".#0
 
 
 h9OX^lo  HT  mz  {  {  {2#* Ggkk'222GKK4F4F4FTYHZHZHZM.EQXQ[  iD  Lh  FM  W[  w\  w\  ]  ]  ]  	^  	^  	^M.EQXQ[  iG  Om  }C  EI  |J  K  K  K  	L  	L  	L'//'222666 #t?k  ym  n  nM!xh!5 !-%*,0T  G (5KTZhk  DP  iv  C`  a  a  aGKK'++g...KK*AWZdz  Cb  rz  |Y  qZ  [  [  [  \  \  \NNgoog...GUE222r"   c                   |                      t          t                                        t          j                                                                      d                                                    }g }|D ]f}|                     t          |j
                  }|                     t          |j                  }|                    t          |||                     gd|iS )Nd   items)ri   r   r   rp   rX   rq   rr   rj   rP   r   rA   r   r   r   r   )r<   attemptsr  r   r   r*   s         r    list_tiktok_attemptsr
  *  s    ||F#677@@ATA_AdAdAfAfggmmnqrrsswwyyHE > >J(>??Iw'<==%gue<<====Ur"   )r   r   r   r   )r   r   r   r#   )r*   r+   r   r#   )r   r   r   r0   )r<   r   r   r=   )r[   r0   r   r{   )r   r   r*   r   r   r   r   r   )NN)r   r   r   r   r*   r+   r   r   )r<   r   r   r   r   )r<   r   r   r   r   r   r   r   )+
__future__r   r   r   pathlibr   typingr   fastapir   sqlmodelr   r   app.core.configr	   app.models.corer
   r   r   r   r   r   r   r   app.security.redactionr   r   r   r   r   r6   r!   r)   r/   r;   rx   rz   r   r   r   r   r  r
  r@   r"   r    <module>r     sY   " " " " " "               ! ! ! ! ! ! $ $ $ $ $ $ $ $ ( ( ( ( ( ( F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F  F A A A A A A A A= # " ! ! !    ] ] ] ]
C C C C. . . .4K 4K 4K 4Kn
 
 
 
V V V V   *	 	 	 	 	3 3 3 3lQ3 Q3 Q3 Q3 Q3h     r"   