Ë
    ¯"ëiM.  ã            
       ó  — d Z ddlZddlZddlmZ ddlmZmZ ej                  j                  dej                  j                  ej                  j                  ej                  j                  e«      «      «      «        G d„ d«      Zy)u7   
æœˆæ¬¡ãƒ¬ãƒ�ãƒ¼ãƒˆç”Ÿæˆ�ã‚µãƒ¼ãƒ“ã‚¹ - HTML/PDFç”Ÿæˆ�
é    N)Údatetime)ÚEnvironmentÚFileSystemLoaderc                   óŠ   — e Zd ZdZddedefd„Zd„ Zddedefd	„Zdd
e	dede	fd„Z
d
e	de	fd„Zde	dede	fd„Zdd
e	dede	fd„Zy)ÚMonthlyReportHTMLu)   æœˆæ¬¡ãƒ¬ãƒ�ãƒ¼ãƒˆHTML/PDFç”Ÿæˆ�ã‚¯ãƒ©ã‚¹NÚdataÚanalysesc           	      óš  — || _         |xs i | _        t        j                  j	                  t        j                  j                  t        j                  j                  t        j                  j                  t        «      «      «      d«      }t        t        |«      d¬«      | _
        | j                  | j                  j                  d<   y)u®   
        Args:
            data: ReportDataAggregator.collect_all_data()ã�®æˆ»ã‚Šå€¤
            analyses: LLMAnalyzer.analyze_all()ã�®æˆ»ã‚Šå€¤ï¼ˆã‚ªãƒ—ã‚·ãƒ§ãƒ³ï¼‰
        Ú	templatesT)ÚloaderÚ
autoescapeÚtojsonN)r   r	   ÚosÚpathÚjoinÚdirnameÚabspathÚ__file__r   r   ÚenvÚ_tojson_filterÚfilters)Úselfr   r	   Útemplate_dirs       ú1/var/www/html/chat/reports/core/html_generator.pyÚ__init__zMonthlyReportHTML.__init__   sŒ   € ð ˆŒ	Ø š BˆŒô —w‘w—|‘|Ü�G‰G�O‰OœBŸG™GŸO™O¬B¯G©G¯O©O¼HÓ,EÓFÓGØó
ˆô Ü# LÓ1Øô
ˆŒð
 &*×%8Ñ%8ˆ�‰×Ñ˜Ò"ó    c                 ó8   — ddl }d„ }|j                  |d|¬«      S )u   Jinja2ç”¨ã�®JSONãƒ•ã‚£ãƒ«ã‚¿ãƒ¼r   Nc                 ó€   — t        | d«      r| j                  «       S t        | d«      r| j                  S t        | «      S )NÚ	isoformatÚ__dict__)Úhasattrr   r    Ústr)Úobjs    r   Újson_serializerz9MonthlyReportHTML._tojson_filter.<locals>.json_serializer)   s5   € Ü�s˜KÔ(Ø—}‘}“Ð&Ü�s˜JÔ'Ø—|‘|Ð#Ü�s“8ˆOr   F)Úensure_asciiÚdefault)ÚjsonÚdumps)r   Úvaluer'   r$   s       r   r   z MonthlyReportHTML._tojson_filter%   s!   € ãò	ð �z‰z˜%¨e¸_ˆzÓMÐMr   Ú
standaloneÚreturnc                 óp  — | j                   j                  dg «      }i }d}t        |t        «      rW|D ]Q  }|j                  dd«      }|j                  dd«      }|j                  dd«      }||vri ||<   |||   |<   ||kD  sŒP|}ŒS nUt        |t        «      rE|}|j                  «       D ]0  }	t        |	t        «      sŒ|	j                  «       D ]
  }||kD  sŒ	|}Œ Œ2 i d| j                   d   “d| j                   d   “d| j                   d   “d	| j                   d	   “d
| j                   d
   “d| j                   d   “d|“d|“d| j                   d   “d| j                   j                  dg «      “d| j                   j                  dg «      “d| j                   j                  dg «      “d| j                   j                  dg «      “d| j                   j                  dg «      “d| j                   j                  dg «      “d| j                   j                  dg «      “d| j                   d   “| j                  t        j                  «       j                  d«      dœ¥}
|�r;t        j                  j                  t        j                  j                  t        j                  j                  t        «      «      «      }t        j                  j                  |ddd«      }t        j                  j                  |ddd«      }d}t        j                  j!                  |«      r't#        |dd¬ «      5 }|j%                  «       }d!d!d!«       d}t        j                  j!                  |«      r't#        |dd¬ «      5 }|j%                  «       }d!d!d!«       ||
d"<   ||
d#<   |
S # 1 sw Y   Œ]xY w# 1 sw Y   Œ!xY w)$u-   ãƒ†ãƒ³ãƒ—ãƒ¬ãƒ¼ãƒˆã�«æ¸¡ã�™ãƒ‡ãƒ¼ã‚¿ã‚’æº–å‚™Úhour_by_day_of_weekr   Úday_of_weekÚhourÚcountÚperiodÚsummaryÚ
comparisonÚdaily_statsÚhourly_statsÚday_of_week_statsÚhour_by_day_of_week_maxÚ	avg_turnsÚkeywordsÚunresolved_keywordsÚunanswered_questionsÚrecent_dislikedÚfeedback_daily_statsÚqa_usage_rankingÚcategory_usage_rankingÚestimated_savingsu   %Yå¹´%mæœˆ%dæ—¥ %H:%M)r	   Úgenerated_atÚstaticÚcssú
report.cssÚjsz	charts.jsÚ Úrúutf-8©ÚencodingNÚcss_contentÚ
js_content)r   ÚgetÚ
isinstanceÚlistÚdictÚvaluesr	   r   ÚnowÚstrftimer   r   r   r   r   r   ÚexistsÚopenÚread)r   r*   Úraw_hour_by_dowÚhour_by_dowÚ	max_countÚitemÚdayr/   r0   Úday_dataÚtemplate_dataÚbase_dirÚcss_pathÚjs_pathrK   ÚfrL   s                    r   Ú_prepare_template_dataz(MonthlyReportHTML._prepare_template_data2   s¢  € ð Ÿ)™)Ÿ-™-Ð(=¸rÓBˆð ˆØˆ	ä�o¤tÔ,Ø'ò &�Ø—h‘h˜}¨aÓ0�Ø—x‘x ¨Ó*�ØŸ™ ¨!Ó,�Ø˜kÑ)Ø')�K Ñ$Ø).�˜CÑ  Ñ&Ø˜9Ó$Ø %‘Iñ&ô ˜¬Ô.Ø)ˆKØ'×.Ñ.Ó0ò .�Ü˜h¬Õ-Ø!)§¡Ó!2ò .˜Ø  9Ó,Ø(-™Iñ.ð.ð
Ø�d—i‘i Ñ)ð
à�t—y‘y Ñ+ð
ð ˜$Ÿ)™) LÑ1ð
ð ˜4Ÿ9™9 ]Ñ3ð	
ð
 ˜DŸI™I nÑ5ð
ð   §¡Ð+>Ñ!?ð
ð " ;ð
ð & yð
ð ˜Ÿ™ ;Ñ/ð
ð ˜Ÿ	™	Ÿ™ j°"Ó5ð
ð " 4§9¡9§=¡=Ð1FÈÓ#Kð
ð # D§I¡I§M¡MÐ2HÈ"Ó$Mð
ð ˜tŸy™yŸ}™}Ð->ÀÓCð
ð # D§I¡I§M¡MÐ2HÈ"Ó$Mð
ð  §	¡	§¡Ð.@À"Ó Eð
ð  % d§i¡i§m¡mÐ4LÈbÓ&Qð!
ð"   §¡Ð+>Ñ!?ð#
ð$ Ÿ™Ü$ŸL™L›N×3Ñ3Ð4KÓLò'
ˆò. Ü—w‘w—‘¤r§w¡w§¡´r·w±w·±ÄxÓ7PÓ'QÓRˆHÜ—w‘w—|‘| H¨h¸¸|ÓLˆHÜ—g‘g—l‘l 8¨X°t¸[ÓIˆGàˆKÜ�w‰w�~‰~˜hÔ'Ü˜( C°'Ô:ð +¸aØ"#§&¡&£(�K÷+ð ˆJÜ�w‰w�~‰~˜gÔ&Ü˜' 3°Ô9ð *¸QØ!"§¡£�J÷*ð ,7ˆM˜-Ñ(Ø*4ˆM˜,Ñ'àÐ÷+ð +ú÷
*ð *ús   Ì3N Í;N,Î N)Î,N5Úoutput_pathc                 ó¸  — |r| j                   j                  d«      }n| j                   j                  d«      }| j                  |¬«      } |j                  di |¤Ž}|rnt        j
                  j                  |«      }|rt	        j                  |d¬«       t        |dd¬«      5 }|j                  |«       d	d	d	«       t        d
|› �«       |S # 1 sw Y   ŒxY w)u6  
        HTMLã‚’ç”Ÿæˆ�

        Args:
            output_path: å‡ºåŠ›ãƒ•ã‚¡ã‚¤ãƒ«ãƒ‘ã‚¹ï¼ˆNoneã�®å ´å�ˆã�¯HTMLæ–‡å­—åˆ—ã�®ã�¿è¿”ã�™ï¼‰
            standalone: Trueã�®å ´å�ˆã€�CSS/JSã‚’ã‚¤ãƒ³ãƒ©ã‚¤ãƒ³åŒ–ã�—ã�¦ã‚¹ã‚¿ãƒ³ãƒ‰ã‚¢ãƒ­ãƒ³HTMLã‚’ç”Ÿæˆ�

        Returns:
            ç”Ÿæˆ�ã�•ã‚Œã�ŸHTMLæ–‡å­—åˆ—
        zreport_standalone.htmlzreport.html)r*   T©Úexist_okÚwrH   rI   Nu   HTMLå‡ºåŠ›: © )r   Úget_templaterb   Úrenderr   r   r   ÚmakedirsrU   ÚwriteÚprint)r   rc   r*   Útemplater]   ÚhtmlÚ
output_dirra   s           r   Úgenerate_htmlzMonthlyReportHTML.generate_htmly   s¾   € ñ Ø—x‘x×,Ñ,Ð-EÓF‰Hà—x‘x×,Ñ,¨]Ó;ˆHà×3Ñ3¸zÐ3ÓJˆØˆx�‰Ñ/ Ñ/ˆáäŸ™Ÿ™¨Ó5ˆJÙÜ—‘˜J°Õ6ä�k 3°Ô9ð ¸QØ—‘˜”÷ä�L  Ð.Ô/àˆ÷	ð ús   Â&CÃCc                 óª  — 	 ddl m}m} i }	 ddlm}  || j                  «      }t        d«       | j                  «       }|r| j                  ||«      }t        j                  t        j                  j                  |«      d
¬«       t        j                  j                  t        j                  j                  t        j                  j                  t         «      «      «      }t        j                  j#                  |ddd«      }	 |d¬«      }
 |||¬«      }|
g}t        j                  j%                  |	«      r|j'                  d ||	¬«      «       |j)                  ||¬«       t        d|› �«       |S # t        $ r t        d«      ‚w xY w# t        $ r}t        d|› �«       Y d}~�Œ}d}~wt        $ r}t        d	|› �«       Y d}~�Œ�d}~ww xY w)uÊ   
        PDFã‚’ç”Ÿæˆ�ï¼ˆHTMLâ†’PDFå¤‰æ�›ã€�ã‚°ãƒ©ãƒ•ç”»åƒ�åŸ‹ã‚�è¾¼ã�¿ï¼‰

        Args:
            output_path: å‡ºåŠ›ãƒ•ã‚¡ã‚¤ãƒ«ãƒ‘ã‚¹

        Returns:
            å‡ºåŠ›ãƒ•ã‚¡ã‚¤ãƒ«ãƒ‘ã‚¹
        r   )ÚHTMLÚCSSu·   weasyprintã�Œã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã�•ã‚Œã�¦ã�„ã�¾ã�›ã‚“ã€‚
pip install weasyprint ã�§ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã�—ã�¦ã��ã� ã�•ã�„ã€‚
Windowsã�®å ´å�ˆã�¯GTKã�®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚‚å¿…è¦�ã�§ã�™ã€‚é   )Úgenerate_all_chartsu$   ã‚°ãƒ©ãƒ•ç”»åƒ�ã‚’ç”Ÿæˆ�ã�—ã�¾ã�—ã�ŸuS   è­¦å‘Š: matplotlibã�Œè¦‹ã�¤ã�‹ã‚Šã�¾ã�›ã‚“ã€‚ã‚°ãƒ©ãƒ•ã�ªã�—ã�§PDFç”Ÿæˆ�ã�—ã�¾ã�™: Nu.   è­¦å‘Š: ã‚°ãƒ©ãƒ•ç”Ÿæˆ�ã�«å¤±æ•—ã�—ã�¾ã�—ã�Ÿ: Tre   rB   rC   rD   uF  
            @font-face {
                font-family: 'NotoSansCJKJP';
                src: url('/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc');
                font-weight: normal;
            }
            @font-face {
                font-family: 'NotoSansCJKJP';
                src: url('/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc');
                font-weight: bold;
            }
            @page {
                size: A4;
                margin: 15mm;
            }
            body {
                background: white;
                font-family: 'NotoSansCJKJP', sans-serif;
            }
            .report-container {
                max-width: none;
            }
            .page {
                box-shadow: none;
                margin-bottom: 0;
                page-break-after: always;
            }
            .page:last-child {
                page-break-after: auto;
            }
            /* Chart.jsã�®canvasã�¯é�žè¡¨ç¤ºã€�ä»£ã‚�ã‚Šã�«img.chart-imageã‚’è¡¨ç¤º */
            canvas {
                display: none;
            }
            .chart-container {
                min-height: auto;
                background: transparent;
            }
            .chart-image {
                max-width: 100%;
                height: auto;
            }
            /* ã‚°ãƒ©ãƒ•ç”»åƒ�ã�Œã�ªã�„å ´å�ˆã�®ãƒ•ã‚©ãƒ¼ãƒ«ãƒ�ãƒƒã‚¯ */
            .chart-container:not(:has(img))::after {
                content: "ã‚°ãƒ©ãƒ•ã�¯HTMLãƒ—ãƒ¬ãƒ“ãƒ¥ãƒ¼ã�§ç¢ºèª�ã�—ã�¦ã��ã� ã�•ã�„";
                font-size: 10pt;
                color: #999;
            }
        )Ústring)rw   Úbase_url)Úfilename)Ústylesheetsu   PDFå‡ºåŠ›: )Ú
weasyprintrs   rt   ÚImportErrorÚ
pdf_chartsrv   r   rm   Ú	Exceptionrq   Ú_embed_chart_imagesr   rk   r   r   r   r   r   rT   ÚinsertÚ	write_pdf)r   rc   rs   rt   Úchart_imagesrv   ÚeÚhtml_contentr^   r_   Úpdf_cssÚhtml_docrz   s                r   Úgenerate_pdfzMonthlyReportHTML.generate_pdf™   s™  € ð	ß,ð ˆð	HÝ7Ù.¨t¯y©yÓ9ˆLÜÐ8Ô9ð ×)Ñ)Ó+ˆñ Ø×3Ñ3°LÀ,ÓOˆLô 	�‰”B—G‘G—O‘O KÓ0¸4Õ@ô —7‘7—?‘?¤2§7¡7§?¡?´2·7±7·?±?Ä8Ó3LÓ#MÓNˆÜ—7‘7—<‘< ¨(°E¸<ÓHˆñ ð 0ô 0ˆñf ˜|°hÔ?ˆà�iˆÜ�7‰7�>‰>˜(Ô#Ø×Ñ˜q¡#¨xÔ"8Ô9à×Ñ˜;°KÐÔ@Ü�˜K˜=Ð)Ô*àÐøô{ ò 	ÜðPóð ð	ûô ò 	mÜÐgÐhiÐgjÐk×lÒlûÜò 	HÜÐBÀ1À#ÐF×GÒGûð	Hús.   ‚E8 �#F Å8FÆ	GÆF-Æ-GÆ9GÇGr„   r‚   c           
      óŽ  — ddl }|j                  d«      |j                  d«      |j                  d«      |j                  d«      |j                  d«      |j                  d«      |j                  d	«      |j                  d
«      dœ}|j                  «       D ]*  \  }}|sŒ	d|› d�}d|› d|› d�}|j                  |||«      }Œ, |S )uò   
        HTMLã�«ã‚°ãƒ©ãƒ•ç”»åƒ�ã‚’åŸ‹ã‚�è¾¼ã‚€

        Args:
            html_content: å…ƒã�®HTML
            chart_images: ã‚°ãƒ©ãƒ•ç”»åƒ�ã�®è¾žæ›¸ {chart_id: base64_image}

        Returns:
            ç”»åƒ�åŸ‹ã‚�è¾¼ã�¿æ¸ˆã�¿HTML
        r   NÚdailyr3   Úhourlyr.   Úresolution_pier9   r:   Úcategory_ranking)Ú
dailyChartÚcomparisonChartÚhourlyChartÚdayOfWeekChartÚresolutionPieChartÚkeywordsChartÚunresolvedKeywordsChartÚcategoryRankingChartz<canvas id="z"[^>]*></canvas>z
<img src="z" class="chart-image" alt="z">)ÚrerM   ÚitemsÚsub)	r   r„   r‚   r•   ÚreplacementsÚ	canvas_idÚimg_dataÚpatternÚreplacements	            r   r   z%MonthlyReportHTML._embed_chart_images  sç   € ó 	ð '×*Ñ*¨7Ó3Ø+×/Ñ/°Ó=Ø'×+Ñ+¨HÓ5Ø*×.Ñ.¨}Ó=Ø".×"2Ñ"2Ð3CÓ"DØ)×-Ñ-¨jÓ9Ø'3×'7Ñ'7Ð8MÓ'NØ$0×$4Ñ$4Ð5GÓ$Hñ	
ˆð $0×#5Ñ#5Ó#7ò 	JÑˆI�xÚà(¨¨Ð3CÐD�Ø *¨8¨*Ð4OÐPYÈ{ÐZ\Ð]�Ø!Ÿv™v g¨{¸LÓI‘ð	Jð Ðr   c                 óJ   — |s| j                  |«      S | j                  |«      S )u$  
        ã‚°ãƒ©ãƒ•ç”»åƒ�ä»˜ã��ã�§PDFã‚’ç”Ÿæˆ�

        Args:
            output_path: å‡ºåŠ›ãƒ•ã‚¡ã‚¤ãƒ«ãƒ‘ã‚¹
            chart_images: ã‚°ãƒ©ãƒ•ç”»åƒ�ã�®ãƒ‘ã‚¹è¾žæ›¸ {chart_id: image_path}

        Returns:
            å‡ºåŠ›ãƒ•ã‚¡ã‚¤ãƒ«ãƒ‘ã‚¹

        Note:
            Chart.jsã�¯JavaScriptä¾�å­˜ã�®ã�Ÿã‚�ã€�PDFã�«ç›´æŽ¥ãƒ¬ãƒ³ãƒ€ãƒªãƒ³ã‚°ã�§ã��ã�¾ã�›ã‚“ã€‚
            äº‹å‰�ã�«ã‚µãƒ¼ãƒ�ãƒ¼ã‚µã‚¤ãƒ‰ã�§ã‚°ãƒ©ãƒ•ç”»åƒ�ã‚’ç”Ÿæˆ�ã�™ã‚‹ã�‹ã€�
            puppeteerã�ªã�©ã�®ãƒ˜ãƒƒãƒ‰ãƒ¬ã‚¹ãƒ–ãƒ©ã‚¦ã‚¶ã‚’ä½¿ç”¨ã�™ã‚‹å¿…è¦�ã�Œã�‚ã‚Šã�¾ã�™ã€‚
        )r‡   )r   rc   r‚   s      r   Úgenerate_pdf_with_chartsz*MonthlyReportHTML.generate_pdf_with_charts&  s+   € ñ" Ø×$Ñ$ [Ó1Ð1ð × Ñ  Ó-Ð-r   )N)F)NT)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rP   r   r   Úboolrb   r"   rq   r‡   r   rž   rh   r   r   r   r      sž   „ Ù3ñ9˜Tð 9¨Tó 9ò*NñE°ð EÀ$ó EñN¨ð Àð ÐQTó ð@i¨ð i°ó iðV °ð  À4ð  ÈCó  ñD.°Cð .Àtð .ÐWZô .r   r   )r¢   r   Úsysr   Újinja2r   r   r   r€   r   r   r   r   rh   r   r   ú<module>r¦      s_   ðñó 
Û 
Ý ß 0ð ‡�‡���2—7‘7—?‘? 2§7¡7§?¡?°2·7±7·?±?À8Ó3LÓ#MÓNÔ O÷o.ò o.r   