
    r$j!Q                    "   d dl mZ d dlmZ d dlmZmZmZ d dlmZ d dl	m
Z
 d dlmZmZmZ d dlmZmZmZmZmZmZmZmZmZ d dlmZmZmZmZmZmZm Z  d	 Z!d
 Z"	 	 	 	 	 	 d<d=dZ#d>d?d#Z$d@d&Z%dAd*Z&dBd0Z'dCdDd3Z(dEd4Z)d5 Z*dFd7Z+dGd9Z,dHd;Z-dS )I    )annotations)defaultdict)datetimetimetimezone)median)Any)Sessionfuncselect)	AnalyticsDailyAggregateAnalyticsImportBatchAnalyticsImportFileAnalyticsPostSnapshotExternalPost	PostDraftProviderTheme
VideoAsset)UNKNOWNYOUTUBE_CHARTYOUTUBE_DAILY_TOTALSYOUTUBE_VIDEO_TABLEcompute_snapshot_metrics	file_hashparse_csv_by_typec                    | d S t          | t                    r| S t          j        | t          j        t
          j                  S )Ntzinfo)
isinstancer   combiner   minr   utcvalues    S/home/agent/projects/AutoShorts_Dashboard/backend/app/services/analytics_service.pyas_datetimer'       s?    }t%"" E48HLAAAA    c                    | |d S | |z
  S N )newolds     r&   
safe_deltar.   (   s    
{ckt9r(   youtubeNmanualFsessionr
   fileslist[tuple[str, bytes]]providerstr
account_id
str | Nonesnapshot_atdatetime | Nonesource_labelis_demoboolimport_batch_labelreturndict[str, Any]c                    t          |          }|pt          j        t          j                  }t          |||dt          |          |||p|          }	|                     |	           |                                  | 	                    |	           g }
g }d}d}d}d}g }g }|D 	]\   }t          |          }t          |          }||j        z  }|j        r|                    |j                   |j        r|                    |j                   |                     t#          t$                                        t$          j
        |k    t$          j        |j        k    t$          j        dk                                                        }t%          |	j         ||j        |j        t1          |j                  t1          |j                  |rdnd          }|                     |           |                                  | 	                    |           |r_|j        |_        |
                      d           g |j        d|_        |                     |           |                                  |j        t:          k    rdd	|_        |j        |_        |                     fd
|j        D                        |                     |           |                                  N|j        t>          k    rd}|j         D ]}tC          |"                    d                    }|'|                     tG          |	j        ||||"                    d          |"                    d          pi                      |dz  }||z  }||_$        |j        |z
  |_        d|_        n(|j        tJ          k    r|j&        r|
                      d|j&        "                    d           d|j&        "                    d           d|j&        "                    d           d|j&        "                    d           d|j&        "                    d                      d}|j         D ]}|"                    d          pd|"                    dd           }|                     t#          tN                                        tN          j(        |k    tN          j)        |k    tN          j*        |k                                                        }|stO          ||||"                    d          tC          |"                    d                    |"                    d          |||p| 
  
        }tW          | |"                    d          |          }|r$|j        |_,        |j-        |_-        |j.        |_.        |                     |           |                                  | 	                    |           |dz  }n|"                    d          p|j/        |_/        tC          |"                    d                    p|j0        |_0        |"                    d          p|j1        |_1        ||_2        ||_3        |p||_4         |_5        t          j        t          j                  |_6        |                     |           |                                  |                     t#          tn                                        tn          j(        |k    tn          j)        |k    tn          j*        |k              8                    tn          j9        :                                                                                    }tw          ||          }to          d6i d |	j        d!|d"|d|d#|j,        d$|d|"                    d          dtC          |"                    d                    d|"                    d          d|"                    d          d|"                    d          d|"                    d          d|"                    d          d|"                    d          d%|"                    d%          d&|"                    d&          d'|"                    d'          d(|"                    d(          d)|"                    d)          d*|"                    d          pi d+|d,|d-|p|d. }ty          ||           |                     |           |dz  }|dz  }||_$        |j        |z
  |j&        rdndz
  |_        d|_        nl|j        tz          k    r\t          |j                   |_$        t}          d|j        t          |j                   z
            |_        |j        dk    rd/nd|_        g |j        |j        |_        g |j?        |j        |_?        |
                     fd0|j        D                        |                     fd1|j        D                        |                     |           |                                  	|r!tC          t          |                    |	_        |r!tC          t}          |                    |	_        |r|s|sd	n|
s|rd2nd|	_        ||	_A        |
|	_        ||	_?        |                     |	           |                                  | 	                    |	           |	B                    d34          ||z   t}          d||z
  |z
            |
||||d5S )7N	importing)r4   r6   r8   statustotal_filesr:   r;   r=   r   importedskipped_duplicate)batch_id	file_namer   detected_type	row_countwarnings_jsonerrors_jsonrB   z: duplicate file hash skippedzDuplicate file hash skippedfailedc                    g | ]	} d | 
S z: r+   .0efilenames     r&   
<listcomp>z,import_youtube_csv_files.<locals>.<listcomp>w   s'    EEE!h--!--EEEr(   metric_dateviewsraw)rF   r4   r6   rT   rU   raw_json   z: total row views=z watch_time=watch_time_hoursz subscribers=subscribers_deltaz impressions=impressionsz ctr=impression_ctr_pctexternal_post_idztitle:titleuntitledpublished_atduration_sec)
r4   r]   r6   r^   r`   ra   r:   r;   r=   source_file_namerF   r4   r6   video_asset_idr8   avg_view_duration_secretention_proxy_pctviews_per_impressionsubscribers_per_1000_viewsviews_per_day_since_publishrW   r:   r;   r=   rb   empty_validc                    g | ]	} d | 
S rN   r+   )rP   wrR   s     r&   rS   z,import_youtube_csv_files.<locals>.<listcomp>   s'    EEEH++++EEEr(   c                    g | ]	} d | 
S rN   r+   rO   s     r&   rS   z,import_youtube_csv_files.<locals>.<listcomp>   s'    AAAa())a))AAAr(   imported_with_warningsjsonmode)batchimported_rowsskipped_rowswarningserrorscreated_postscreated_snapshotscreated_daily_metricsr+   )Cr   r   nowr   r#   r   lenaddcommitrefreshr   r   rI   date_range_startappenddate_range_endexecr   r   whererH   rB   firstidlistrt   ru   rs   rJ   r   extendr   rowsr'   getr   rr   r   	total_rowr   r4   r]   r6   match_video_assetrc   topic_idseriesr^   r`   ra   r:   r;   r=   rb   
updated_atr   order_byr8   descr   apply_deltasr   maxrK   r"   
total_rows
model_dump)!r1   r2   r4   r6   r8   r:   r;   r=   provider_enumrq   rt   ru   r   rv   	snapshotsdaily_metricsdate_starts	date_endscontentdigestparsed	duplicateimport_filerD   rowrT   external_idpostlinkedpreviousderivedsnapshotrR   s!                                   @r&   import_youtube_csv_filesr   .   s    X&&M;hl!;!;K JJ!-=	 	 	E KKNNOOEHFJMIMKI" a a'7##"7++f&&
" 	8v6777  	4V2333LL&''--#-7#1V5II#*j8 
 
 %'' 	 *X .&v//V]++*3D&&	
 	
 	
 	K   $$$ 	'-'7K$OOxFFFGGG(c+*C(cEb(cK%KK$$$NN7**!)K'-'7K$MMEEEEv}EEEFFFKK$$$NN#777H{  )#''-*@*@AA&3"X*) +'''** WWU^^1r      AX%M(0K%'-'7('BK$!+K!%888   d  d63C3G3G3P3P  d  d^d^n^r^r  tF  _G  _G  d  d  V\  Vf  Vj  Vj  k~  V  V  d  d  NT  N^  Nb  Nb  cp  Nq  Nq  d  d  x~  xH  xL  xL  Ma  xb  xb  d  d   H{ Q Q!gg&899c=ccgggV`FaFa=c=c||<((..$->$5D$/:=   %''    %'!.)4#-!ggg..%01H1H%I%I%(WW^%<%<%1 '+=+M)1  D /w8H8H+VVF 4.4i+(.&,mKK%%%NN$$$OOD)))!Q&MM!$!1!1!?TZDJ(3CGGN4K4K(L(L(aPTPaD%(+(?(?(T4CTD%(4D%#*DL.@.PLD+,4D)&.l8<&@&@DOKK%%%NN$$$"<<011U-6-G->+M-8JF 
 X3?DDFFGG  %''  33DD0   "XX*]  *z &1[	
 $(#6#6 !, '''*** "-SWW^-D-D!E!E!E "%!8!8!8 '''*** &)WW-?%@%@%@ '*gg.A&B&B&B !$ 6 6 6 (+ww/C'D'D'D +2++6M*N*N*N  )04I(J(J(J!" *15K)L)L)L#$ 07{{;W/X/X/X%& 18<Y0Z0Z0Z'( !WWU^^1r)* ".+, $G-. (:'I\/0 &.X14 Xx000H%%%AQ		(0K%'-'7('B6K[Fbaaab'cK$!+K!]22(+FK(8(8K%'*1f.>V[AQAQ.Q'R'RK$282Ba2G2GZK$Rk&?$R&/$R!"LK$;"Lfm"LEEEEV_EEEFFFAAAA6=AAABBBK    ?!,S-=-=!>!> ;*3y>>::%  Oy  OM  O88lt  QOx~  QOPhPh  EOEL!E"EEKKNNOOE !!v!.."]2AzI5EFF&&!.	 	 	r(   r^   r   VideoAsset | Nonec                &   |r|                                 }|                     t          t                                        t          j        |k                                                        }|r|S |                     t          t                                        t          j        |k                                                        }|r$| 	                    t          |j
                  }|r|S |                     t          t                                                              D ]X}|j        pi }t          |                                           }	|r*||	v r&| 	                    t          |j
                  }|r|c S Y|sd S t          |          }
d }d}|                     t          t                                                              D ]0}t          |
t          |j        pd                    }||k    r|}|}1|dk    r|nd S )N         g?)lowerr   r   r   r   external_youtube_idr   r   r]   r   rc   allmetadata_jsonr5   normalize_textjaccardworking_title)r1   r^   r   needledirectdraft_directvideodraftmeta	flattened
normalizedbest
best_scorescores                 r&   r   r     s    !""$$fZ0066z7UYd7deeffllnn 	M||F9$5$5$;$;I<VZe<e$f$fggmmoo 	KK
L,GHHE \\&"3"34488:: 	! 	!E&,"DD		))I !&I--J0DEE ! LLL t&&JDJfZ00115577  
N53F3L"$M$MNN:DJ%%444/r(   r%   set[str]c                x    d d                     d | D                                                       D             S )Nc                8    h | ]}t          |          d k    |S )   rz   )rP   parts     r&   	<setcomp>z!normalize_text.<locals>.<setcomp>,  s-    sssTehimenenqrererDerererr(   r   c              3  j   K   | ].}|                                 r|                                nd V  /dS ) N)isalnumr   )rP   chs     r&   	<genexpr>z!normalize_text.<locals>.<genexpr>,  s;      $Y$YR2::<<%HRXXZZZS$Y$Y$Y$Y$Y$Yr(   )joinsplitr$   s    r&   r   r   +  s>    ssRWW$Y$YSX$Y$Y$YYY__aassssr(   abfloatc                X    | r|sdS t          | |z            t          | |z            z  S )Nr   r   )r   r   s     r&   r   r   /  s5     A sq1u::AE

""r(   r   r   r   AnalyticsPostSnapshot | NoneNonec                b   |s	d| _         d S t          | j        |j                  | _        | j        |j        r| j        |j        z  dz  | _        t          | j        |j                  | _        t          | j        |j                  | _        t          | j	        |j	                  | _
        t          | j        |j                  | _        t          | j        |j                  | _        | j        }|j        }|j         |                    t$          j                  }|j         |                    t$          j                  }t)          d||z
                                  dz            }|| _        | j        2| j        |z  | _        | j        dk    rdn| j        dk     rd	nd
| _         d S d S )Nr,   d   r   g{Gz?iQ 
   risingrX   slowingstable)trendr.   rU   views_deltaviews_delta_pctrY   watch_time_deltar[   impressions_deltarZ   subscriber_delta_changer\   
ctr_changere   retention_proxy_changer8   r   replacer   r#   r   total_secondsdays_since_previous_snapshotviews_velocity_per_day)r   r   
current_atprevious_atdayss        r&   r   r   5  s    %hnhnEEH'HN'#+#7(.#H3#N  *8+DhF_ ` `H!+H,@(BV!W!WH'1(2LhNh'i'iH$$X%@(B]^^H&01MxOk&l&lH#%J&K ''x|'<<
!!)))>>tj;.==??%GHHD,0H)'*2*>*E'%-%9B%>%>QYQehiQiQiIIow ('r(   include_demolist[AnalyticsPostSnapshot]c                   t          t                                        t          j                                                  }|s#|                    t          j        dk              }|                     |                                          }t                      }g }|D ]E}|j
        |j        |j        f}||v r|                    |           |                    |           F|S )NF)r   r   r   r8   r   r   r;   r   r   setr4   r6   r]   r{   r   )r1   r   stmtr   seenlatestr   keys           r&   latest_snapshotsr   N  s    '((112G2S2X2X2Z2Z[[D Bzz/75@AA<<!!##D55DF  |S^S-AB$;;cMr(   c           	        t          |           }|                     t          t                                        t          j                                                            }|                     t          t                                        t          j        	                                                                                    }t          d |D                       }t          d |D                       }t          d |D                       }t          d |D                       }t          |d d           }t          |d d           }	d |D             }
|t          d	 |
d
d          D                       t          d |
dd          D                       |t          |d          ||r|j        nd |	r|	j        nd d|
d |D             d |D             dS )Nc              3  (   K   | ]}|j         pd V  dS r   NrU   rP   ss     r&   r   z%analytics_overview.<locals>.<genexpr>b  s(      33qagl333333r(   c              3  (   K   | ]}|j         pd V  dS r   )rY   r   s     r&   r   z%analytics_overview.<locals>.<genexpr>c  s*      >>!a(-A>>>>>>r(   c              3  (   K   | ]}|j         pd V  dS r   )rZ   r   s     r&   r   z%analytics_overview.<locals>.<genexpr>d  s*      DD1.3!DDDDDDr(   c                    g | ]	}|j         
S r+   re   r   s     r&   rS   z&analytics_overview.<locals>.<listcomp>e  s    CCCqQ2CCCr(   c                    | j         pdS )Nr   r   s    r&   <lambda>z$analytics_overview.<locals>.<lambda>f  s    agm r(   )r   defaultc                    | j         pdS )Nrg   r   s    r&   r   z$analytics_overview.<locals>.<lambda>g  s    Q-I-TW r(   c                x    g | ]7}|j                                                                         |j        pd d8S )r   )daterU   )rT   r  	isoformatrU   )rP   ds     r&   rS   z&analytics_overview.<locals>.<listcomp>h  sB    eeeZ[Q]//11;;==STUUeeer(   c              3  &   K   | ]}|d          V  dS rU   Nr+   rP   ps     r&   r   z%analytics_overview.<locals>.<genexpr>l  s&      $K$KAQwZ$K$K$K$K$K$Kr(   ic              3  &   K   | ]}|d          V  dS r  r+   r  s     r&   r   z%analytics_overview.<locals>.<genexpr>m  s&      %M%MQaj%M%M%M%M%M%Mr(   i   )total_views_latestviews_last_7_daysviews_last_28_dayssubscriber_deltatotal_watch_time_hoursaverage_retention_proxy
best_video best_video_subscriber_conversionc                ,    g | ]}t          |          S r+   )snapshot_to_dictr   s     r&   rS   z&analytics_overview.<locals>.<listcomp>u  s!    7771#A&&777r(   c                :    g | ]}|                     d           S )rn   ro   )r   )rP   r   s     r&   rS   z&analytics_overview.<locals>.<listcomp>v  s&    ???!ALLfL--???r(   )kpisdaily_viewsvideosimports)r   r   r   r   r   rT   r   r   imported_atr   sumaverager   roundr^   )r1   r   dailybatchestotal_viewstotal_watchr  avg_retentionbest_by_viewsbest_by_subsdaily_pointss              r&   analytics_overviewr%  ^  s    g&&FLL 788AABYBeffggkkmmEll6"677@@AUAaAfAfAhAhiijjnnppG33F33333K>>v>>>>>KDDVDDDDDCCFCCCDDM$;$;TJJJMv#T#T^bcccLee_deeeL #.!$$K$Kbcc9J$K$K$K!K!K"%%M%M,stt:L%M%M%M"M"M 0&+K&;&;'41>H---DFR0\0B0BX\	
 	
 $77777??w???  r(   c                `    d | D             }|sd S t          |          t          |          z  S )Nc                    g | ]}||S r*   r+   )rP   vs     r&   rS   zaverage.<locals>.<listcomp>{  s    333aQ]]]]r(   )r  rz   )valuesfiltereds     r&   r  r  z  s9    336333H tx==3x==((r(   r   c                h    |                      d          }| j        dn| j        dk    rdnd|d<   |S )Nrn   ro   unknown-   strongweakretention_label)r   re   )r   datas     r&   r  r    sI    <<V<$$D+,+@+HiiZ[ZosuZuZuhh  |BD	Kr(   list[dict[str, Any]]c           	        t          |           }|sdddddgS d |D             }d |D             }d |D             }d	 |D             }d
 |D             }|rt          |          nd}|rt          |          nd}|rt          |          nd}	|rt          |          nd}
|rt          |          nd}g }|D ]c}|j        p|j        }|j        pd|k    r0|j        pd|k    r#|                    ddd| d|j        d           |j        pd|k    r0|j        pd|k    r#|                    ddd| d|j        d           |j        pd|	k    r0|j        pd|
k     r#|                    ddd| d|j        d           |j        pd|k    r0|j        pd|k     r#|                    ddd| d|j        d           |j	        pd|k    r#|                    ddd| d|j        d           |j
        dk    r#|                    d dd!| d"|j        d           e|                    t          | |                     |d d#         S )$Nemptyinfoz0Import YouTube CSV to start performance learningz)No analytics snapshots are available yet.)typeseverityr^   messagec                     g | ]}|j         pd S r   r   r   s     r&   rS   z&analytics_insights.<locals>.<listcomp>  s    111QAGLq111r(   c                *    g | ]}|j         	|j         S r*   r   r   s     r&   rS   z&analytics_insights.<locals>.<listcomp>  s#    ccc!AVAb-AbAbAbr(   c                     g | ]}|j         pd S r:  )r[   r   s     r&   rS   z&analytics_insights.<locals>.<listcomp>  s    ===!-,1===r(   c                *    g | ]}|j         	|j         S r*   )r\   r   s     r&   rS   z&analytics_insights.<locals>.<listcomp>  s#    [[[1!:N:Z!&:Z:Z:Zr(   c                *    g | ]}|j         	|j         S r*   r   r   s     r&   rS   z&analytics_insights.<locals>.<listcomp>  s#    lllA1C_Ck1/CkCkCkr(   r   winnersuccesszWinner patternz: keep this topic/hook style.)r6  r7  r^   r8  r]   packaging_problemwarningzPackaging opportunityzM: viewers who watch stay longer, but distribution/click packaging looks weak.hook_problemzHook/CTR problemzO: high exposure but weak click-through. Rework title/thumbnail/opening promise.retention_problemzRetention problemzE: topic attracts views, but pacing or first seconds may lose viewers.r   subscriber_converterzSubscriber converterzA: converts viewers into subscribers. Reuse a similar promise/CTA.r   negative_trendzDistribution slowingzR: distribution flattened since previous import. Consider follow-up or repackaging.   )r   r   r^   r]   rU   re   r   r[   r\   rg   r   r   topic_opportunities)r1   r   views_valuesretention_valuesimpressions_values
ctr_valuessubs_valuesviews_medianretention_medianimpressions_median
ctr_mediansubs_medianinsightsr   r^   s                  r&   analytics_insightsrT    s   g&&F l f?q  j  k  k  l  	l11&111Lccvccc==f===[[[[[JlllllK+7>6,'''QL3CJv.///7IP 2333q'18
###qJ)4;&%%%!K%'H ~ ~-1-GLqL((a.C.HqL\-\-\OOX9O_ot  mT  mT  mT  jk  j|  }  }  ~  ~  ~!&Q*:::1Q]?]?]OO%8iZq  BG  V  V  V  lm  l~      @  @  @MQ"444!:N:SRSWa9a9aOO^Ugw|  uN  uN  uN  de  dv  w  w  x  x  xGLqL((a.C.HqL\-\-\OO%8iZm  ~C  {J  {J  {J  `a  `r  s  s  t  t  t(3G{BBOO%;]s  DI  AL  AL  AL  bc  bt  u  u  v  v  v7iOO%56Tjz  xT  xT  xT  jk  j|  }  }  ~  ~  ~OO'88999CRC=r(   r   c           	        t          t                    }d |                     t          t                                                              D             }|D ]E}|                    |j                  }|r'|j        r ||j                 	                    |           Ft          d |D                       pd}g }|                                D ]{\  }}	t          d |	D                       pd}
t          |	          dk     rH|
|k    rB|                     t          |          }|	                    ddd|r|j        n| d	|d
           ||S )Nc                    i | ]
}|j         |S r+   )r]   r  s     r&   
<dictcomp>z'topic_opportunities.<locals>.<dictcomp>  s    UUUqQUUUr(   c                    g | ]	}|j         
S r+   r   r   s     r&   rS   z'topic_opportunities.<locals>.<listcomp>  s    ///1qw///r(   r   c                    g | ]	}|j         
S r+   r   r   s     r&   rS   z'topic_opportunities.<locals>.<listcomp>  s    333QW333r(   r	  topic_opportunityr@  zTopic opportunityzR: few videos but above-average views. Make 3 more variants before switching topic.)r6  r7  r^   r8  r   )r   r   r   r   r   r   r   r]   r   r   r  itemsrz   r   r^   )r1   r   groupspostsr   r   all_avgoutr   r   	topic_avgtopics               r&   rH  rH    s   5@5F5FFUUGLL9M9M,N,N,R,R,T,TUUUE , ,yy+,, 	,DM 	,4=!((+++/////005AG
C ,,.. G G$33d333449	t99q==Y00KKx00EJJ 3Uh  HM  y[x}  yD  yD  S[  vo  vo  vo  }E  F  F  G  G  GJr(   )r/   NNr0   FN)r1   r
   r2   r3   r4   r5   r6   r7   r8   r9   r:   r5   r;   r<   r=   r7   r>   r?   r*   )r1   r
   r^   r7   r   r7   r>   r   )r%   r5   r>   r   )r   r   r   r   r>   r   )r   r   r   r   r>   r   )F)r1   r
   r   r<   r>   r   )r1   r
   r>   r?   )r   r   r>   r?   )r1   r
   r>   r2  )r1   r
   r   r   r>   r2  ).
__future__r   collectionsr   r   r   r   
statisticsr   typingr	   sqlmodelr
   r   r   app.models.corer   r   r   r   r   r   r   r   r   "app.services.analytics_youtube_csvr   r   r   r   r   r   r   r'   r.   r   r   r   r   r   r   r%  r  r  rT  rH  r+   r(   r&   <module>ri     s   " " " " " " # # # # # # - - - - - - - - - -             * * * * * * * * * *
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 B B B   !#' %)[ [ [ [ [|0 0 0 0 0>t t t t# # # #x x x x2        8) ) )      B     r(   