
    z jX                        d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	  e
h d          Z e
h d          Z ed	
           G d d                      Z G d d          ZddZddZddZdS )zAManual YouTube Studio analytics CSV sanitizer and report builder.    )annotationsN)	dataclass)Path)Iterable>   likestitleviewssharesvideo_idimpressionscandidate_idpublish_dateengaged_viewsnotes_by_usershown_in_feedsnapshot_timecomments_counttraffic_sourceclick_through_ratedays_since_publishsubscribers_gainedaverage_view_durationviewed_vs_swiped_awayaverage_percentage_viewed>   urlbodylinkemailreplyauthorcommentmessageprofileraw_textusernamechannel_namecomment_textcomments_textexternal_textT)frozenc                  $    e Zd ZU ded<   ded<   dS )CsvImportResulttuple[dict[str, str], ...]rowstuple[str, ...]ignored_columnsN)__name__
__module____qualname____annotations__     Z/home/agent/jarvis_runtime/autoshortsbot/AutoShortsBot/autoshorts/youtube/analytics_csv.pyr,   r,   7   s*         $$$$$$$$$$r6   r,   c                  .    e Zd ZdZdZddZddZddZdS )YouTubeAnalyticsCsvSanitizerz@Allowlist-only sanitizer. No YouTube API calls; no raw comments.i,  columnsIterable[str]returnr/   c                   t          d |D                       }d |D             }|r%t          dd                    |                     d |D             }|r%t          dd                    |                     |S )Nc              3  B   K   | ]}|pd                                  V  dS ) N)strip.0cs     r7   	<genexpr>z@YouTubeAnalyticsCsvSanitizer.validate_headers.<locals>.<genexpr>C   s0      >>AG??,,>>>>>>r6   c                $    g | ]}|t           v |S r5   )FORBIDDEN_COLUMNSrA   s     r7   
<listcomp>zAYouTubeAnalyticsCsvSanitizer.validate_headers.<locals>.<listcomp>D   s#    EEE1a3D.D.DQ.D.D.Dr6   z+Forbidden YouTube analytics CSV column(s): z, c                $    g | ]}|t           v|S r5   )ALLOWED_COLUMNSrA   s     r7   rG   zAYouTubeAnalyticsCsvSanitizer.validate_headers.<locals>.<listcomp>G   s"    EEEA_,D,D1,D,D,Dr6   z1Unknown/blocked YouTube analytics CSV column(s): )tuple
ValueErrorjoin)selfr:   
normalized	forbiddenunknowns        r7   validate_headersz-YouTubeAnalyticsCsvSanitizer.validate_headersB   s    >>g>>>>>
EE
EEE	 	ca499U^K_K_aabbbEEjEEE 	geQUQZQZ[bQcQceefffr6   columnstrvaluec                \    |pd                                 }|dk    r|d | j                 S |S )Nr?   r   )r@   NOTES_MAX_CHARS)rM   rR   rT   s      r7   sanitize_cellz*YouTubeAnalyticsCsvSanitizer.sanitize_cellL   s;    "##%%_$$/4//00r6   path
str | Pathr,   c                    t          |          }|                    dd          5 }t          j        |          }|j        t          d                               |j                  }g }|D ]& fd|D             }|                    |           '	 d d d            n# 1 swxY w Y   t          t          |          d          S )Nr?   zutf-8)newlineencodingzCSV has no header rowc           
     f    i | ]-}|                     |                    |d                     .S )r?   )rW   get)rB   colrowrM   s     r7   
<dictcomp>z;YouTubeAnalyticsCsvSanitizer.import_csv.<locals>.<dictcomp>[   s:    gggPSS$"4"4S#''#r:J:J"K"Kgggr6   r5   )r.   r0   )
r   opencsv
DictReader
fieldnamesrK   rQ   appendr,   rJ   )rM   rX   freaderallowed_headersr.   	sanitizedr`   s   `      @r7   
import_csvz'YouTubeAnalyticsCsvSanitizer.import_csvR   s   DzzYYrGY44 	'^A&&F ( !8999"33F4EFFO)+D ' 'gggggWfggg	I&&&&'	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' E$KKDDDDs   A0B&&B*-B*N)r:   r;   r<   r/   )rR   rS   rT   rS   r<   rS   )rX   rY   r<   r,   )r1   r2   r3   __doc__rV   rQ   rW   rk   r5   r6   r7   r9   r9   =   sa        JJO      E E E E E Er6   r9   rX   rY   r<   r-   c                N    t                                          |           j        S )N)r9   rk   r.   )rX   s    r7   import_youtube_analytics_csvrn   `   s    '))44T::??r6   r`   dict[str, str]keyrS   floatc                    	 t          |                     |          pd                    dd                    S # t          $ r Y dS w xY w)N0%r?   g        )rq   r^   replacerK   )r`   rp   s     r7   	_to_floatrv   d   sV    cggcll)c223;;<<<   sss   7: 
AAc                N   t          t          |                     }|sdS t          |d           }t          |d           }t          |d           }d |D             }d |D             }d                    d	 |d d
         D                       pd}d                    dddddt	          |           d|                    d          p|                    d           d|                    dd           dd|                    d          p|                    d           d|                    dd           dd|                    d          p|                    d           d|                    dd           ddt	          |           ddd d!d"dd#|g          S )$NzKYouTube manual CSV learning report
No rows imported. No external API calls.c                "    t          | d          S )Nr	   rv   rs    r7   <lambda>z0build_learning_report_from_csv.<locals>.<lambda>o   s    	!W(=(= r6   )rp   c                "    t          | d          S )Nr
   ry   rz   s    r7   r|   z0build_learning_report_from_csv.<locals>.<lambda>p   s    1h)?)? r6   c                "    t          | d          S )Nr   ry   rz   s    r7   r|   z0build_learning_report_from_csv.<locals>.<lambda>q   s    y4H'I'I r6   c                Z    g | ](}t          |d           t          |d           dk     &|)S )r   2   ry   rB   r{   s     r7   rG   z2build_learning_report_from_csv.<locals>.<listcomp>r   sl      G  G  GA16Q)R)R  GW`abd  XA  XA  DF  XF  XFa  XF  XF  XFr6   c                d    g | ]-}|                     d           |                     d d          .S )r   r?   )r^   r   s     r7   rG   z2build_learning_report_from_csv.<locals>.<listcomp>s   s7    PPPA9O9OPQUU?B''PPPr6   
c              3      K   | ]	}d | V  
dS )z- Nr5   )rB   notes     r7   rD   z1build_learning_report_from_csv.<locals>.<genexpr>t   s(      ==4;;;======r6      z- nonez"YouTube manual CSV learning reportz@Source: user-exported sanitized CSV only; no external API calls.z/Viewer comment content: blocked / not imported.r?   zRows imported: zBest by views: r   r   z (r	   rs   z views)zBest by shares: r
   z shares)zBest by subscribers gained: r   )z.Videos with weak retention (<50% avg viewed): zAllowed analysis:ze- compare themes, hooks, first frames, thumbnails, shares, subscribers, retention, and comments_countz+- propose next video topics and safer hooksz(- never quote or analyze viewer commentszUser notes summaries:)listrn   maxrL   lenr^   )rX   r.   	top_views
top_sharestop_subspoor_retentionnotes
note_liness           r7   build_learning_report_from_csvr   k   sH   ,T2233D ^]]D==>>>IT??@@@J4IIJJJH G  G  G  G  GNPPPPPE==5!9=====IJ990N=)c$ii)) AimmN;;Xy}}Z?X?X  A  A\e\i\ijqsv\w\w  A  A  A Gz~~n==[PZA[A[  G  G_i_m_mnvx{_|_|  G  G  G R8<<+G+G+c8<<XbKcKc  R  Rgogsgs  uI  KN  hO  hO  R  R  RRS=P=PRRs96##	
  r6   )rX   rY   r<   r-   )r`   ro   rp   rS   r<   rq   )rX   rY   r<   rS   )rl   
__future__r   rc   dataclassesr   pathlibr   typingr   	frozensetrI   rF   r,   r9   rn   rv   r   r5   r6   r7   <module>r      s\   G G " " " " " " 



 ! ! ! ! ! !            )   0 I    * $% % % % % % % %
 E  E  E  E  E  E  E  EF@ @ @ @        r6   