Ë
    A¾Ši×S  ã            
       óî  — d Z ddlZddlZddlZddlmZmZ ddlmZ ej                  j                  dej                  j                  ej                  j                  ej                  j                  e«      «      «      «       ddlmZmZmZmZmZmZmZmZ 	 ddlmZ d„ Zd	„ Zd
„ Zd„ Zd„ Zd„ Zd„ Zd„ Zde fd„Z!d-de de"fd„Z#de de fd„Z$de de fd„Z%de de fd„Z&de'de'fd„Z(de de fd„Z)de de fd„Z*de de fd„Z+de de fd„Z,de de fd „Z-de de fd!„Z.d.de de d"e'fd#„Z/d.de de d"e'fd$„Z0d.d%e1d"e'fd&„Z2de de fd'„Z3d/de de d"e'fd(„Z4de de fd)„Z5d*„ Z6d.de de d"e'fd+„Z7d/de de d"e'fd,„Z8y# e$ r dZY ŒÔw xY w)0uM  
æœˆæ¬¡ãƒ¬ãƒ�ãƒ¼ãƒˆç”Ÿæˆ�ã‚µãƒ¼ãƒ“ã‚¹ - ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹æŽ¥ç¶šãƒ»ã‚¯ã‚¨ãƒª

DB_TYPEè¨­å®šå€¤:
  - 'sqlite'    : ãƒ­ãƒ¼ã‚«ãƒ«é–‹ç™ºç”¨SQLite
  - 'neon'      : Neon PostgreSQLï¼ˆå¤–éƒ¨ãƒ›ã‚¹ãƒˆã€�SSLå¿…é ˆï¼‰
  - 'lightsail' : Lightsailå†…PostgreSQLï¼ˆlocalhostã€�SSLä¸�è¦�ï¼‰
  - 'pgsql'     : å¾Œæ–¹äº’æ�›ï¼ˆneonã�¨å�Œã�˜å‹•ä½œï¼‰
é    N)ÚdatetimeÚ	timedelta)Ú
monthrange)ÚDB_TYPEÚSQLITE_PATHÚPG_HOSTÚPG_PORTÚ	PG_DBNAMEÚPG_USERÚPG_PASSWORDÚUNANSWERED_PATTERNS)Ú
PG_SSLMODEÚ c                  ó   — t         dv S )u"   PostgreSQLç³»ã�‹ã�©ã�†ã�‹ã‚’åˆ¤å®š)ÚneonÚ	lightsailÚpgsql)r   © ó    ú+/var/www/html/chat/reports/core/database.pyÚ_is_postgresr      s   € äÐ4Ð4Ð4r   c                  óV   — t         rt         S t        dk(  s	t        dk(  ryt        dk(  ryy)u@   SSLãƒ¢ãƒ¼ãƒ‰ã‚’å�–å¾—ï¼ˆDB_TYPEã�«å¿œã�˜ã�Ÿãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ï¼‰r   r   Úrequirer   ÚdisableÚprefer)r   r   r   r   r   Ú_get_sslmoder   #   s+   € åÜÐÜ�&ÒœG wÒ.ØÜ�+ÒØØr   c            	      ó$  — t        «       r;ddl} t        «       }| j                  t        t
        t        t        t        |¬«      }|S t        }t        j                  j                  |«      s{t        j                  j                  t        j                  j                  t        j                  j                  t        j                  j                  t         «      «      «      |«      }t#        j                  |«      }t"        j$                  |_        |S )u)   DBæŽ¥ç¶šã‚’å�–å¾—ï¼ˆèª­ã�¿å�–ã‚Šå°‚ç”¨ï¼‰r   N)ÚhostÚportÚdbnameÚuserÚpasswordÚsslmode)r   Úpsycopg2r   Úconnectr   r	   r
   r   r   r   ÚosÚpathÚisabsÚjoinÚdirnameÚabspathÚ__file__Úsqlite3ÚRowÚrow_factory)r$   r#   ÚconnÚdb_paths       r   Úget_connectionr2   .   s²   € ä„~ÛÜ“.ˆØ×ÑÜÜÜÜÜ Øð  ó 
ˆð ˆô ˆÜ�w‰w�}‰}˜WÔ%Ü—g‘g—l‘l¤2§7¡7§?¡?´2·7±7·?±?Ä2Ç7Á7Ç?Á?ÔS[ÓC\Ó3]Ó#^Ð`gÓhˆGÜ�‰˜wÓ'ˆÜ"Ÿ;™;ˆÔØˆr   c                 óŠ   — t        «       r*ddl}| j                  |j                  j                  ¬«      S | j                  «       S )u6   ã‚«ãƒ¼ã‚½ãƒ«ã‚’å�–å¾—ï¼ˆPostgreSQLã�¯RealDictCursorï¼‰r   N)Úcursor_factory)r   Úpsycopg2.extrasÚcursorÚextrasÚRealDictCursor)r0   r$   s     r   Ú
get_cursorr9   F   s1   € ä„~ÛØ�{‰{¨(¯/©/×*HÑ*Hˆ{ÓIÐIØ�;‰;‹=Ðr   c                  ó   — t        «       ryy)u2   DBã‚¿ã‚¤ãƒ—ã�«å¿œã�˜ã�Ÿæ—¥ä»˜ã‚­ãƒ£ã‚¹ãƒˆã‚’è¿”ã�™ztimestamp::datezDATE(timestamp)©r   r   r   r   Ú_get_date_castr<   N   s   € ä„~Ø Ør   c                  ó   — t        «       ryy)u,   DBã‚¿ã‚¤ãƒ—ã�«å¿œã�˜ã�Ÿæ™‚é–“æŠ½å‡ºã‚’è¿”ã�™z%EXTRACT(HOUR FROM timestamp)::INTEGERz*CAST(strftime('%H', timestamp) AS INTEGER)r;   r   r   r   Ú_get_hour_extractr>   U   s   € ä„~Ø6Ø7r   c                  ó   — t        «       ryy)ud   DBã‚¿ã‚¤ãƒ—ã�«å¿œã�˜ã�Ÿæ›œæ—¥æŠ½å‡ºã‚’è¿”ã�™ï¼ˆ0=æ—¥æ›œ, 6=åœŸæ›œ â†’ 0=æœˆæ›œ, 6=æ—¥æ›œã�«å¤‰æ�›ï¼‰z/(EXTRACT(DOW FROM timestamp)::INTEGER + 6) %% 7z4(CAST(strftime('%w', timestamp) AS INTEGER) + 6) % 7r;   r   r   r   Ú_get_day_of_week_extractr@   \   s   € ä„~ð AàAr   c                  ó¨   — g } t         D ]7  }t        «       r| j                  d|› d�«       Œ#| j                  d|› d�«       Œ9 dj                  | «      S )u$   æœªå›žç­”åˆ¤å®šã�®SQLæ�¡ä»¶ã‚’æ§‹ç¯‰zassistant_message LIKE '%%z%%'zassistant_message LIKE '%z%'z OR )r   r   Úappendr)   )Ú
conditionsÚpatterns     r   Ú_build_unanswered_conditionrE   f   s^   € à€JÜ&ò GˆäŒ>Ø×ÑÐ :¸7¸)À3ÐGÕHà×ÑÐ 9¸'¸À"ÐEÕFðGð �;‰;�zÓ"Ð"r   Úqueryc                 ó>   — t        «       r| j                  dd«      S | S )u5   DBã‚¿ã‚¤ãƒ—ã�«å¿œã�˜ã�¦ãƒ—ãƒ¬ãƒ¼ã‚¹ãƒ›ãƒ«ãƒ€ã‚’å¤‰æ�›ú?z%s)r   Úreplace)rF   s    r   Ú_prepare_queryrJ   r   s   € ä„~à�}‰}˜S $Ó'Ð'Ø€Lr   Úparamsc                 ó>   — t        |«      }| j                  ||«       y)u9   ã‚¯ã‚¨ãƒªã‚’å®Ÿè¡Œï¼ˆãƒ—ãƒ¬ãƒ¼ã‚¹ãƒ›ãƒ«ãƒ€å¤‰æ�›ä»˜ã��ï¼‰N)rJ   Úexecute)r6   rF   rK   Úconverted_querys       r   Ú_executerO   z   s   € ä$ UÓ+€OØ
‡N�N�? FÕ+r   Ú
start_dateÚend_datec                 óæ   — t        «       }t        |«      }t        «       }d|› d�}t        ||| |f«       |j	                  «       }|j                  «        |D �cg c]  }t        |«      ‘Œ c}S c c}w )u   æœŸé–“å†…ã�®ä¼šè©±ã‚’å�–å¾—zŒ
        SELECT id, session_id, user_message, assistant_message, timestamp, ip_address, user_agent
        FROM conversations
        WHERE ú4 BETWEEN ? AND ?
        ORDER BY timestamp ASC
    ©r2   r9   r<   rO   ÚfetchallÚcloseÚdict©rP   rQ   r0   r6   Ú	date_castrF   ÚrowsÚrows           r   Úget_conversationsr\   €   ót   € äÓ€DÜ˜Ó€FÜÓ €Iðð ˆkð ð€Eô ˆV�U˜Z¨Ð2Ô3Ø�?‰?Ó€DØ‡J�J„LØ!%Ö&˜#ŒD��IÒ&Ð&ùÒ&ó   ÁA.c                 óæ   — t        «       }t        |«      }t        «       }d|› d�}t        ||| |f«       |j	                  «       }|j                  «        |D �cg c]  }t        |«      ‘Œ c}S c c}w )u*   æœŸé–“å†…ã�®ãƒ•ã‚£ãƒ¼ãƒ‰ãƒ�ãƒƒã‚¯ã‚’å�–å¾—zw
        SELECT id, session_id, feedback, question, answer, timestamp, ip_address
        FROM feedbacks
        WHERE rS   rT   rX   s           r   Úget_feedbacksr`   ’   r]   r^   c                 óþ  — t        «       }t        |«      }t        «       }t        «       }i }d|› d�}t	        ||| |f«       |j                  «       d   |d<   d|› d|› d�}t	        ||| |f«       |j                  «       d   |d<   d|› d|› d�}t	        ||| |f«       |j                  «       d   |d	<   d
|› d�}t	        ||| |f«       |j                  «       d   |d<   d|› d�}t	        ||| |f«       |j                  «       d   |d<   d|› d�}t	        ||| |f«       |j                  «       d   |d<   d|› d�}t	        ||| |f«       |j                  «       d   |d<   |d   |d   z   |d<   |j                  «        |S )u   æœŸé–“ã�®çµ±è¨ˆã‚µãƒžãƒªãƒ¼zC
        SELECT COUNT(*) as count FROM conversations
        WHERE ú BETWEEN ? AND ?
    ÚcountÚtotal_conversationsz" BETWEEN ? AND ?
        AND NOT (ú)
    Úanswered_countú BETWEEN ? AND ?
        AND (Úunanswered_countzU
        SELECT COUNT(DISTINCT session_id) as count FROM conversations
        WHERE Úunique_sessionsz?
        SELECT COUNT(*) as count FROM feedbacks
        WHERE z3 BETWEEN ? AND ?
        AND feedback = 'like'
    Úlikes_countz6 BETWEEN ? AND ?
        AND feedback = 'dislike'
    Údislikes_countzU
        SELECT COUNT(DISTINCT ip_address) as count FROM conversations
        WHERE zM BETWEEN ? AND ?
        AND ip_address IS NOT NULL AND ip_address != ''
    Ú
unique_ipsÚtotal_feedbacks)r2   r9   r<   rE   rO   ÚfetchonerV   )rP   rQ   r0   r6   rY   Úunanswered_condÚstatsrF   s           r   Úget_statistics_for_periodrq   ¤   s(  € äÓ€DÜ˜Ó€FÜÓ €IÜ1Ó3€Oà€Eðàˆkð ð€Eô ˆV�U˜Z¨Ð2Ô3Ø#)§?¡?Ó#4°WÑ#=€EÐ
Ñ ðàˆkð Ø!Ð"ð #ð€Eô
 ˆV�U˜Z¨Ð2Ô3Ø$Ÿo™oÓ/°Ñ8€EÐ
Ñðàˆkð ØÐð ð€Eô
 ˆV�U˜Z¨Ð2Ô3Ø &§¡Ó 1°'Ñ :€EÐ
Ñðàˆkð ð€Eô ˆV�U˜Z¨Ð2Ô3Ø%Ÿ™Ó0°Ñ9€EÐ
Ñðàˆkð ð€Eô
 ˆV�U˜Z¨Ð2Ô3Ø!Ÿ?™?Ó,¨WÑ5€Eˆ-Ñðàˆkð ð€Eô
 ˆV�U˜Z¨Ð2Ô3Ø$Ÿo™oÓ/°Ñ8€EÐ
Ñðàˆkð ð€Eô
 ˆV�U˜Z¨Ð2Ô3Ø Ÿ/™/Ó+¨GÑ4€Eˆ,Ñð  % ]Ñ3°eÐ<LÑ6MÑM€EÐ
Ñà‡J�J„LØ€Lr   ÚyearÚmonthc                 óŠ  — t        | |«      \  }}| › d|d›d�}| › d|d›d|d›�}|dk(  r| dz
  }d}n| }|dz
  }t        ||«      \  }}|› d|d›d�}	|› d|d›d|d›�}
t        ||«      }t        |	|
«      }d„ }|| ||d   |d   «       ||d   |d   «       ||d	   |d	   «       ||d
   |d
   «       ||d   |d   «      dœdœS )u   å‰�æœˆæ¯”è¼ƒãƒ‡ãƒ¼ã‚¿ú-Ú02dz-01é   é   c                 óH   — |dk(  r	| dkD  rdS dS t        | |z
  |z  dz  d«      S )Nr   éd   rw   )Úround)ÚcurrentÚpreviouss     r   Úcalc_changez+get_monthly_comparison.<locals>.calc_change  s6   € Ø�qŠ=Ø! Aš+�3Ð,¨1Ð,Ü�g Ñ(¨HÑ4°sÑ:¸AÓ>Ð>r   rd   rf   rh   rj   rk   )rd   rf   rh   rj   rk   )r|   r}   Úchanges)r   rq   )rr   rs   Ú_Úlast_dayÚcurrent_startÚcurrent_endÚ	prev_yearÚ
prev_monthÚprev_last_dayÚ
prev_startÚprev_endÚcurrent_statsÚ
prev_statsr~   s                 r   Úget_monthly_comparisonr‹   ñ   sK  € ô ˜T 5Ó)�K€A€xØ�f˜A˜e C˜[¨Ð,€MØ�F˜!˜E #˜; a¨° ~Ð6€Kð �‚zØ˜1‘Hˆ	Ø‰
àˆ	Ø˜Q‘Yˆ
Ü! )¨ZÓ8Ñ€A€}Ø�;˜a 
¨3Ð/¨sÐ3€JØ�˜A˜j¨Ð-¨Q¨}¸SÐ.AÐB€Hä-¨m¸[ÓI€MÜ*¨:°xÓ@€Jò?ð !Øá#.¨}Ð=RÑ/SÐU_Ð`uÑUvÓ#wÙ)¨-Ð8HÑ*IÈ:ÐVfÑKgÓhÙ +¨MÐ:LÑ,MÈzÐZlÑOmÓ nÙ& }°]Ñ'CÀZÐP]ÑE^Ó_Ù)¨-Ð8HÑ*IÈ:ÐVfÑKgÓhñ
ñ
ð 
r   c                 óv  — t        «       }t        |«      }t        «       }t        «       }d|› d|› d|› d|› d|› d|› d�}t	        ||| |f«       |j                  «       }|j                  «        g }|D ]D  }	t        |	«      }
t        |
d   d	«      r|
d   j                  d
«      |
d<   |j                  |
«       ŒF |S )u   æ—¥åˆ¥çµ±è¨ˆú
        SELECT
            z� as date,
            COUNT(*) as total_conversations,
            COUNT(DISTINCT session_id) as unique_sessions,
            SUM(CASE WHEN (zI) THEN 1 ELSE 0 END) as unanswered_count,
            SUM(CASE WHEN NOT (zP) THEN 1 ELSE 0 END) as answered_count
        FROM conversations
        WHERE ú" BETWEEN ? AND ?
        GROUP BY ú
        ORDER BY ú	 ASC
    ÚdateÚstrftimeú%Y-%m-%d)r2   r9   r<   rE   rO   rU   rV   rW   Úhasattrr’   rB   )rP   rQ   r0   r6   rY   ro   rF   rZ   Úresultr[   Úds              r   Úget_daily_statisticsr—     sî   € äÓ€DÜ˜Ó€FÜÓ €IÜ1Ó3€OðàˆKð ð ,Ð,ð - Ø /Ð0ð 1àˆkð Ø�ð Ø�ð ð€Eô ˆV�U˜Z¨Ð2Ô3Ø�?‰?Ó€DØ‡J�J„Là€FØò ˆÜ�‹Iˆä�1�V‘9˜jÔ)Ø˜&™	×*Ñ*¨:Ó6ˆAˆf‰IØ�‰�aÕðð €Mr   c           	      ó   — t        «       }t        |«      }t        «       }t        «       }t	        «       }d|› d|› d|› d|› d�	}t        ||| |f«       |j                  «       }|j                  «        |D �	cg c]  }	t        |	«      ‘Œ c}	S c c}	w )u   æ™‚é–“å¸¯åˆ¥çµ±è¨ˆr�   zR as hour,
            COUNT(*) as total_conversations,
            SUM(CASE WHEN (úR) THEN 1 ELSE 0 END) as unanswered_count
        FROM conversations
        WHERE rŽ   z
        ORDER BY hour ASC
    ©	r2   r9   r<   r>   rE   rO   rU   rV   rW   ©
rP   rQ   r0   r6   rY   Úhour_extractro   rF   rZ   r[   s
             r   Úget_hourly_statisticsr�   9  s¡   € äÓ€DÜ˜Ó€FÜÓ €IÜ$Ó&€LÜ1Ó3€OðàˆNð à+Ð,ð -àˆkð Ø�ð  ð	€Eô ˆV�U˜Z¨Ð2Ô3Ø�?‰?Ó€DØ‡J�J„LØ!%Ö&˜#ŒD��IÒ&Ð&ùÒ&ó   Á6Bc           	      ó   — t        «       }t        |«      }t        «       }t        «       }t	        «       }d|› d|› d|› d|› d�	}t        ||| |f«       |j                  «       }|j                  «        |D �	cg c]  }	t        |	«      ‘Œ c}	S c c}	w )u'   æ›œæ—¥åˆ¥çµ±è¨ˆï¼ˆæœˆæ›œ=0, æ—¥æ›œ=6ï¼‰r�   zY as day_of_week,
            COUNT(*) as total_conversations,
            SUM(CASE WHEN (r™   rŽ   z&
        ORDER BY day_of_week ASC
    )	r2   r9   r<   r@   rE   rO   rU   rV   rW   )
rP   rQ   r0   r6   rY   Údow_extractro   rF   rZ   r[   s
             r   Úget_day_of_week_statisticsr¡   Q  s¡   € äÓ€DÜ˜Ó€FÜÓ €IÜ*Ó,€KÜ1Ó3€OðàˆMð à+Ð,ð -àˆkð Ø�ð ð	€Eô ˆV�U˜Z¨Ð2Ô3Ø�?‰?Ó€DØ‡J�J„LØ!%Ö&˜#ŒD��IÒ&Ð&ùÒ&rž   c                 ó&  — t        «       }t        |«      }t        «       }t        «       }t	        «       }d|› d|› d|› d|› d|› d�}t        ||| |f«       |j                  «       }|j                  «        |D �	cg c]  }	t        |	«      ‘Œ c}	S c c}	w )u2   æ›œæ—¥Ã—æ™‚é–“å¸¯åˆ†å¸ƒï¼ˆãƒ’ãƒ¼ãƒˆãƒžãƒƒãƒ—ç”¨ï¼‰r�   z as day_of_week,
            zQ as hour,
            COUNT(*) as count
        FROM conversations
        WHERE rŽ   z, z(
        ORDER BY day_of_week, hour
    )	r2   r9   r<   r>   r@   rO   rU   rV   rW   )
rP   rQ   r0   r6   rY   rœ   r    rF   rZ   r[   s
             r   Úget_hour_by_day_of_weekr£   i  s¨   € äÓ€DÜ˜Ó€FÜÓ €IÜ$Ó&€LÜ*Ó,€KðàˆMð ØˆNð ð ˆkð Ø�˜b  ð /ð	€Eô ˆV�U˜Z¨Ð2Ô3Ø�?‰?Ó€DØ‡J�J„LØ!%Ö&˜#ŒD��IÒ&Ð&ùÒ&s   Á9Bc                 ól  — t        «       }t        |«      }t        «       }d|› d�}t        ||| |f«       |j	                  «       }|j                  «        |sdddddœS |D �cg c]  }|d   ‘Œ	 }}t        t        |«      t        |«      z  d«      t        |«      t        |«      t        |«      dœS c c}w )u6   å¹³å�‡ä¼šè©±ã‚¿ãƒ¼ãƒ³æ•°ï¼ˆã‚»ãƒƒã‚·ãƒ§ãƒ³ã�‚ã�Ÿã‚Šï¼‰zt
        SELECT
            session_id,
            COUNT(*) as turn_count
        FROM conversations
        WHERE z1 BETWEEN ? AND ?
        GROUP BY session_id
    r   )ÚaverageÚmaxÚminÚtotal_sessionsÚ
turn_counté   )r2   r9   r<   rO   rU   rV   r{   ÚsumÚlenr¦   r§   )	rP   rQ   r0   r6   rY   rF   rZ   r[   Úturnss	            r   Úget_average_turnsr®   �  sÁ   € äÓ€DÜ˜Ó€FÜÓ €Iðð
 ˆkð ð€Eô ˆV�U˜Z¨Ð2Ô3Ø�?‰?Ó€DØ‡J�J„LáØ Q¨qÀAÑFÐFà*.Ö/ 3ˆS�ÓÐ/€EÐ/äœ˜U›¤c¨%£jÑ0°!Ó4Ü�5‹zÜ�5‹zÜ˜e›*ñ	ð ùò 0s   Á"B1c           	      ó   — t        «       }t        |«      }t        «       }t        «       }t	        «       }d|› d|› d|› d|› d�	}t        ||| |f«       |j                  «       }|j                  «        |D �	cg c]  }	t        |	«      ‘Œ c}	S c c}	w )u   æœªè§£æ±ºã�Œå¤šã�„æ™‚é–“å¸¯r�   z\ as hour,
            COUNT(*) as unanswered_count
        FROM conversations
        WHERE rg   z)
        GROUP BY z,
        ORDER BY unanswered_count DESC
    rš   r›   s
             r   Úget_unresolved_by_hourr°   Ÿ  s£   € äÓ€DÜ˜Ó€FÜÓ €IÜ$Ó&€LÜ1Ó3€OðàˆNð ð ˆkð ØÐð Ø�ð  ð	€Eô ˆV�U˜Z¨Ð2Ô3Ø�?‰?Ó€DØ‡J�J„LØ!%Ö&˜#ŒD��IÒ&Ð&ùÒ&rž   Úlimitc                 óî   — t        «       }t        |«      }t        «       }d|› d�}t        ||| |f«       |j	                  «       }|j                  «        t        |D �cg c]  }|d   ‘Œ	 c}|«      S c c}w )u   é »å‡ºã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ú>
        SELECT user_message FROM conversations
        WHERE rb   Úuser_message)r2   r9   r<   rO   rU   rV   Ú_extract_keywords©	rP   rQ   r±   r0   r6   rY   rF   rZ   r[   s	            r   Úget_keywordsr·   ·  sz   € äÓ€DÜ˜Ó€FÜÓ €Iðàˆkð ð€Eô ˆV�U˜Z¨Ð2Ô3Ø�?‰?Ó€DØ‡J�J„Lä¸TÖB°c˜c .Ó1ÒBÀEÓJÐJùÒBs   ÁA2c                 ó  — t        «       }t        |«      }t        «       }t        «       }d|› d|› d�}t	        ||| |f«       |j                  «       }|j                  «        t        |D �	cg c]  }	|	d   ‘Œ	 c}	|«      S c c}	w )u!   æœªè§£æ±ºã�«å¤šã�„ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰r³   rg   re   r´   )r2   r9   r<   rE   rO   rU   rV   rµ   )
rP   rQ   r±   r0   r6   rY   ro   rF   rZ   r[   s
             r   Úget_unresolved_keywordsr¹   È  s�   € äÓ€DÜ˜Ó€FÜÓ €IÜ1Ó3€Oðàˆkð ØÐð ð€Eô
 ˆV�U˜Z¨Ð2Ô3Ø�?‰?Ó€DØ‡J�J„Lä¸TÖB°c˜c .Ó1ÒBÀEÓJÐJùÒBs   Á+A?Úmessagesc                 óø   — ddl }h d£}i }| D ]J  }|sŒ|j                  d|«      }|D ].  }||vsŒt        |«      dk\  sŒ|j                  |d«      dz   ||<   Œ0 ŒL t	        |j                  «       d„ d¬	«      }|d| S )
u-   ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã�‹ã‚‰ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã‚’æŠ½å‡ºr   N>"   õ   ã�‹õ   ã�Œõ   ã�§õ   ã�¨õ   ã�«õ   ã�®õ   ã�¯õ   ã‚’õ   ã�‚ã‚‹õ   ã�„ã‚‹õ   ã�“ã�®õ   ã�™ã‚‹õ   ã��ã�®õ   ã�Ÿã�„õ   ã�¦ã�„õ   ã�¦ã‚‹õ   ã�§ã�™õ   ã�¨ã�¯õ   ã�©ã�†õ   ã�©ã�®õ   ã�ªã�„õ   ã�ªã‚‹õ   ã�ªã‚“õ   ã�¾ã�™õ   ã‚Œã‚‹õ	   ã�—ã�¾ã�†õ	   ã�§ã��ã‚‹õ	   ã�§ã�™ã�‹õ	   ã�»ã�—ã�„õ	   ã�¾ã�™ã�‹õ	   ã‚‰ã‚Œã‚‹õ   ã�Šã�­ã�Œã�„õ   ã��ã� ã�•ã�„õ   ã�«ã�¤ã�„ã�¦u*   [ã��-ã‚“ã‚¡-ãƒ¶ãƒ¼ä¸€-é¾ ã€…ã€†ãƒµãƒ¶]{2,}rª   rw   c                 ó   — | d   S ©Nrw   r   ©Úxs    r   ú<lambda>z#_extract_keywords.<locals>.<lambda>ï  s
   € ¸Q¸q¹T€ r   T©ÚkeyÚreverse)ÚreÚfindallr¬   ÚgetÚsortedÚitems)	rº   r±   ræ   Ú
stop_wordsÚkeywordsÚmessageÚwordsÚwordÚsorted_keywordss	            r   rµ   rµ   Û  s˜   € ãòj€Jð
 €HØò ;ˆÙØà—
‘
ÐHÈ'ÓRˆØò 	;ˆDØ˜:Ò%¬#¨d«)°q«.Ø!)§¡¨d°AÓ!6¸Ñ!:�˜’ñ	;ð;ô ˜XŸ^™^Ó-±>È4ÔP€OØ˜6˜EÐ"Ð"r   c                 ó   — t        «       }t        |«      }t        «       }t        «       }d|› d|› d�}t	        ||| |f«       |j                  «       }|j                  «        |D �cg c]  }t        |«      ‘Œ c}S c c}w )u$   å›žç­”ã�§ã��ã�ªã�‹ã�£ã�Ÿè³ªå•�ä¸€è¦§z]
        SELECT user_message, timestamp, session_id
        FROM conversations
        WHERE rg   z&)
        ORDER BY timestamp DESC
    )r2   r9   r<   rE   rO   rU   rV   rW   )	rP   rQ   r0   r6   rY   ro   rF   rZ   r[   s	            r   Úget_unanswered_questionsrò   ó  s‡   € äÓ€DÜ˜Ó€FÜÓ €IÜ1Ó3€Oðð ˆkð ØÐð ð	€Eô ˆV�U˜Z¨Ð2Ô3Ø�?‰?Ó€DØ‡J�J„LØ!%Ö&˜#ŒD��IÒ&Ð&ùÒ&s   Á&A;c                 óè   — t        «       }t        |«      }t        «       }d|› d�}t        ||| ||f«       |j	                  «       }|j                  «        |D �cg c]  }t        |«      ‘Œ c}S c c}w )u   ä½Žè©•ä¾¡ãƒ•ã‚£ãƒ¼ãƒ‰ãƒ�ãƒƒã‚¯zQ
        SELECT question, answer, timestamp
        FROM feedbacks
        WHERE zf BETWEEN ? AND ?
        AND feedback = 'dislike'
        ORDER BY timestamp DESC
        LIMIT ?
    rT   r¶   s	            r   Úget_recent_dislikedrô     sv   € äÓ€DÜ˜Ó€FÜÓ €Iðð ˆkð ð€Eô ˆV�U˜Z¨°5Ð9Ô:Ø�?‰?Ó€DØ‡J�J„LØ!%Ö&˜#ŒD��IÒ&Ð&ùÒ&s   ÁA/c           	      óV  — t        «       }t        |«      }t        «       }d|› d|› d|› d|› d�	}t        ||| |f«       |j	                  «       }|j                  «        g }|D ]D  }t        |«      }	t        |	d   d«      r|	d   j                  d«      |	d<   |j                  |	«       ŒF |S )	u!   æ—¥åˆ¥ãƒ•ã‚£ãƒ¼ãƒ‰ãƒ�ãƒƒã‚¯çµ±è¨ˆr�   zå as date,
            SUM(CASE WHEN feedback = 'like' THEN 1 ELSE 0 END) as likes,
            SUM(CASE WHEN feedback = 'dislike' THEN 1 ELSE 0 END) as dislikes,
            COUNT(*) as total
        FROM feedbacks
        WHERE rŽ   r�   r�   r‘   r’   r“   )
r2   r9   r<   rO   rU   rV   rW   r”   r’   rB   )
rP   rQ   r0   r6   rY   rF   rZ   r•   r[   r–   s
             r   Úget_feedback_daily_statsrö     sÐ   € äÓ€DÜ˜Ó€FÜÓ €IðàˆKð ð
 ˆkð Ø�ð Ø�ð ð
€Eô ˆV�U˜Z¨Ð2Ô3Ø�?‰?Ó€DØ‡J�J„Là€FØò ˆÜ�‹IˆÜ�1�V‘9˜jÔ)Ø˜&™	×*Ñ*¨:Ó6ˆAˆf‰IØ�‰�aÕð	ð
 €Mr   c                  óv  — t         j                  j                  t         j                  j                  t         j                  j                  t        «      «      d«      } i }t         j                  j                  | «      s|S 	 t        | dd¬«      5 }|D ]g  }|j                  «       }d|v sŒ|j                  dd«      \  }}|j                  d«      d   }||vsŒF|j                  «       j                  d	«      ||<   Œi 	 d
d
d
«       |S # 1 sw Y   |S xY w# t        $ r}t        d|› �«       Y d
}~|S d
}~ww xY w)u<   category.txtã�‹ã‚‰ã‚«ãƒ†ã‚´ãƒªãƒžãƒƒãƒ”ãƒ³ã‚°ã‚’èª­ã�¿è¾¼ã�¿zcategory.txtÚrzutf-8)Úencodingú:rw   ru   r   ú"Nu/   ã‚«ãƒ†ã‚´ãƒªãƒ•ã‚¡ã‚¤ãƒ«èª­ã�¿è¾¼ã�¿ã‚¨ãƒ©ãƒ¼: )r&   r'   r)   r*   r,   ÚexistsÚopenÚstripÚsplitÚ	ExceptionÚprint)Úcategory_pathÚ
categoriesÚfÚlineÚcat_idÚcat_nameÚmain_idÚes           r   Úload_category_mappingr
  9  s  € ä—G‘G—L‘L¤§¡§¡´·±·±ÄÓ1JÓ!KÈ^Ó\€MØ€Jä�7‰7�>‰>˜-Ô(ØÐðEÜ�- ¨wÔ7ð 	J¸1Øò J�Ø—z‘z“|�Ø˜$’;Ø'+§z¡z°#°qÓ'9Ñ$�F˜Hà$Ÿl™l¨3Ó/°Ñ2�GØ jÒ0Ø.6¯n©nÓ.>×.DÑ.DÀSÓ.I˜
 7Ò+ñJ÷	Jð Ð÷	Jð Ðûô ò EÜÐ?À¸sÐC×DÐDàÐûðEúsB   ÂD ÂD	Â,-D	Ã$D	Ã?D Ä	DÄD ÄD Ä	D8ÄD3Ä3D8c                 ó|  — ddl }t        «       }t        |«      }t        «       }d|› d�}t	        ||| |f«       |j                  «       }|j                  «        i }	|D ]<  }
|
d   xs d}|j                  d|«      }|D ]  }|	j                  |d«      dz   |	|<   Œ Œ> t        |	j                  «       d	„ d
¬«      }|d| S )u'   ã‚ˆã��å�‚ç…§ã�•ã‚Œã‚‹Q&Aãƒ©ãƒ³ã‚­ãƒ³ã‚°r   NúC
        SELECT assistant_message FROM conversations
        WHERE rb   Úassistant_messager   ú\*\*Q(\d+(?:-\d+)?):rw   c                 ó   — | d   S rß   r   rà   s    r   râ   z&get_qa_usage_ranking.<locals>.<lambda>k  s
   € ¸¸!¹€ r   Trã   )ræ   r2   r9   r<   rO   rU   rV   rç   rè   ré   rê   )rP   rQ   r±   ræ   r0   r6   rY   rF   rZ   Ú	qa_countsr[   ÚmsgÚidsÚqa_idÚ	sorted_qas                  r   Úget_qa_usage_rankingr  Q  sá   € ãäÓ€DÜ˜Ó€FÜÓ €Iðàˆkð ð€Eô ˆV�U˜Z¨Ð2Ô3Ø�?‰?Ó€DØ‡J�J„Lð €IØò ;ˆØÐ%Ñ&Ò,¨"ˆà�j‰jÐ0°#Ó6ˆØò 	;ˆEØ(Ÿ}™}¨U°AÓ6¸Ñ:ˆI�eÒñ	;ð	;ô �y—‘Ó(©nÀdÔK€IØ�V�eÐÐr   c                 ó0  — ddl }t        «       }t        |«      }t        «       }d|› d�}t	        ||| |f«       |j                  «       }|j                  «        t        «       }	i }
|D ]i  }|d   xs d}|j                  d|«      }|D ]G  }|j                  d«      d   }|	j                  |d	|› �«      }||
vr|dd
œ|
|<   |
|   dxx   dz  cc<   ŒI Œk t        |
j                  «       d„ d¬«      }|D ��cg c]  \  }}||d   |d   f‘Œ }}}|d| S c c}}w )u'   ã‚«ãƒ†ã‚´ãƒªåˆ¥Q&Aå�‚ç…§ãƒ©ãƒ³ã‚­ãƒ³ã‚°r   Nr  rb   r  r   r  ru   u   ã‚«ãƒ†ã‚´ãƒª)Únamerc   rc   rw   c                 ó   — | d   d   S )Nrw   rc   r   rà   s    r   râ   z,get_category_usage_ranking.<locals>.<lambda>”  s   € �a˜‘d˜7‘m€ r   Trã   r  )ræ   r2   r9   r<   rO   rU   rV   r
  rç   rÿ   rè   ré   rê   )rP   rQ   r±   ræ   r0   r6   rY   rF   rZ   r  Úcategory_countsr[   r  r  r  r  r  Úsorted_categoriesÚdatar•   s                       r   Úget_category_usage_rankingr  o  s^  € ãäÓ€DÜ˜Ó€FÜÓ €Iðàˆkð ð€Eô ˆV�U˜Z¨Ð2Ô3Ø�?‰?Ó€DØ‡J�J„Lô 'Ó(€Jð €OØò 2ˆØÐ%Ñ&Ò,¨"ˆà�j‰jÐ0°#Ó6ˆØò 	2ˆEà—[‘[ Ó% aÑ(ˆFØ!—~‘~ f°¸V¸HÐ.EÓFˆHà˜_Ñ,Ø3;ÀaÑ*H� Ñ'Ø˜FÑ# GÓ,°Ñ1Ô,ñ	2ð	2ô Ø×ÑÓÙ#ØôÐð IZ×Z¹¸Àˆv�t˜F‘| T¨'¡]Ò3ÐZ€FÑZØ�&�5ˆ>Ðùó [s   Ã5D)r   )é   )é
   )9Ú__doc__r-   r&   Úsysr   r   Úcalendarr   r'   Úinsertr*   r+   r,   Úconfigr   r   r   r	   r
   r   r   r   r   ÚImportErrorr   r   r2   r9   r<   r>   r@   rE   ÚstrrJ   ÚtuplerO   r\   r`   rq   Úintr‹   r—   r�   r¡   r£   r®   r°   r·   r¹   Úlistrµ   rò   rô   rö   r
  r  r  r   r   r   ú<module>r)     sX  ðñó Û 	Û 
ß (Ý ð ‡�‡���2—7‘7—?‘? 2§7¡7§?¡?°2·7±7·?±?À8Ó3LÓ#MÓNÔ O÷÷ ó ðÝ!ò
5ò
òò0òò8òBò	#ð˜#ó ñ,˜Cð ,¨ó ,ð' #ð '°ó 'ð$'˜cð '¨Só 'ð$J¨#ð J¸ó JðZ$ ð $¨Só $ðN Sð °Có ðB' cð '°Só 'ð0'¨3ð '¸#ó 'ð0'¨ð '°só 'ð0 #ð °ó ð<' sð '°có 'ñ0K˜Sð K¨Cð K¸ó Kñ"K¨ð K°sð KÀ3ó Kñ&# ð #¨Só #ð0'¨ð '¸ó 'ñ(' Cð '°3ð '¸só 'ð(¨ð ¸ó ò<ñ0 Sð °Cð Àó ñ<+¨3ð +¸#ð +Àcô +øðk ò Ø‚Jðús   ÂE* Å*E4Å3E4