o
    \¯¦i[X  ã                	   @   s^  d dl Z d dlZd dlZd dlmZmZmZ d dlZd dlZd dl	m
Z
 d dlmZ d dlZd dlmZ d dlmZmZmZmZ d dlmZmZ d dlmZmZ d dlZeed	Ze d
¡ZdZeƒ ZG dd„ dƒZ G dd„ dƒZ!dZ"dgZ#dee$ dee$ fdd„Z%de$dee$ dee$ee$ f fdd„Z&dd„ Z'de$de$de$fdd„Z(ej)dd gd!ed"ƒfd#efd$d%„ƒZ*ej+d&d'gd!d(d)„ ƒZ,ej)d*d gd!d+efd,d-„ƒZ-ej)d.d/gd!d0d1„ ƒZ.ej+d2d3gd!dGd5e/fd6d7„ƒZ0ej)d8d9gd!d:e$d;efd<d=„ƒZ1ej+d>d9gd!d:e$fd?d@„ƒZ2ej)dAd9gd!d:e$fdBdC„ƒZ3ej)dDd9gd!d:e$fdEdF„ƒZ4dS )Hé    N)ÚDictÚListÚTuple)Úasync_playwright)ÚAsyncOpenAI)ÚKeywordFilter)Ú	APIRouterÚHTTPExceptionÚFileÚ
UploadFile)ÚloggerÚopenai_api_key)Ú
SpeechTextÚChatRequest)Úapi_keyÚs3z$shanri-ai-chatbot-for-text-to-speechc                   @   s*   e Zd Zdd„ Zdedee fdd„ZdS )ÚKeywordGeneratorc                 C   s   t ƒ | _d S )N)r   Úkeyword_filter©Úself© r   ú*/home/air/yokohama/back/yokohama_router.pyÚ__init__$   s   zKeywordGenerator.__init__ÚtitleÚreturnc              
   Ã   s°   d|› d}z1t jjjddddœd|dœgdd	d
I d H }|jd jj}dd„ | d¡D ƒ}| j 	||¡}|W S  t
yW } zt d|› d|› ¡ g W  Y d }~S d }~ww )Nuë   
        ã‚ãªãŸã¯æ›¸ç±ã®å†…å®¹åˆ†æžã®å°‚é–€å®¶ã§ã™ã€‚ä»¥ä¸‹ã®æ›¸ç±ã‚¿ã‚¤ãƒˆãƒ«ã‹ã‚‰ã€ãã®æœ¬ã®ã€Œå†…å®¹ãƒ»ãƒ†ãƒ¼ãƒžã€ã‚’è¡¨ã™æ¤œç´¢ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã‚’æŠ½å‡ºã—ã¦ãã ã•ã„ã€‚

        ## æ›¸ç±ã‚¿ã‚¤ãƒˆãƒ«
        uj  

        ## æŠ½å‡ºæ¡ä»¶ï¼ˆé‡è¦ï¼‰
        ### å«ã‚ã‚‹ã¹ãã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰:
        - æœ¬ã®ä¸»é¡Œã‚„ãƒ†ãƒ¼ãƒžï¼ˆä¾‹: å“²å­¦ã€çµŒæ¸ˆå­¦ã€å¿ƒç†å­¦ï¼‰
        - æ‰±ã£ã¦ã„ã‚‹ãƒˆãƒ”ãƒƒã‚¯ï¼ˆä¾‹: ãƒ¦ãƒ€ãƒ¤äººã®æ­´å²ã€AIæŠ€è¡“ã€ç¿’æ…£å½¢æˆï¼‰
        - ã‚¸ãƒ£ãƒ³ãƒ«ï¼ˆä¾‹: ãƒŸã‚¹ãƒ†ãƒªãƒ¼ã€ãƒ“ã‚¸ãƒã‚¹æ›¸ã€è‡ªå·±å•“ç™ºï¼‰
        - é‡è¦ãªæ¦‚å¿µã‚„ç†è«–ï¼ˆä¾‹: ãƒžã‚¤ãƒ³ãƒ‰ãƒ•ãƒ«ãƒã‚¹ã€è¡Œå‹•å¿ƒç†å­¦ï¼‰
        - å¯¾è±¡èª­è€…å±¤ï¼ˆä¾‹: åˆå¿ƒè€…å‘ã‘ã€çµŒå–¶è€…å‘ã‘ï¼‰

        ### çµ¶å¯¾ã«é™¤å¤–ã™ã¹ãã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰:
        - æ›¸ç±ã®ç‰©ç†çš„ç‰¹æ€§: æœ¬ã€å·»ã€ä¸Šå·»ã€ä¸‹å·»ã€ã‚»ãƒƒãƒˆã€è¡¨ç´™ã€ã‚«ãƒãƒ¼
        - è²©å£²æƒ…å ±: äºˆç´„ã€å…¥è·äºˆç´„ã€é™å®šã€é™å®šç‰¹å…¸ã€æ¥½å¤©ãƒ–ãƒƒã‚¯ã‚¹
        - å¹´å·ã‚„æ•°å­—: 2025ã€2026ã€ç¬¬1å·»ã€21
        - ä¸€èˆ¬çš„ã™ãŽã‚‹èªž: ã‚‚ã®ã€ã“ã¨ã€è¨˜éŒ²ã€çŸ¥è­˜
        - å‡ºç‰ˆç¤¾ã‚„æ›¸åº—å

        ## å‡ºåŠ›å½¢å¼
        ã‚«ãƒ³ãƒžåŒºåˆ‡ã‚Šã§5ã€œ10å€‹ã®ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã‚’å‡ºåŠ›ã—ã¦ãã ã•ã„ã€‚
        å„ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã¯2æ–‡å­—ä»¥ä¸Šã§ã€æ›¸ç±ã®å†…å®¹ã‚’å…·ä½“çš„ã«è¡¨ç¾ã™ã‚‹ã‚‚ã®ã«ã—ã¦ãã ã•ã„ã€‚
        zgpt-3.5-turboÚsystemui   ã‚ãªãŸã¯æ›¸ç±ã®å†…å®¹ã‚’åˆ†æžã—ã€é©åˆ‡ãªæ¤œç´¢ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã‚’ç”Ÿæˆã™ã‚‹å°‚é–€å®¶ã§ã™ã€‚©ÚroleÚcontentÚuserçffffffæ?é–   )ÚmodelÚmessagesÚtemperatureÚ
max_tokensr   c                 S   s   g | ]}|  ¡ ‘qS r   ©Ústrip)Ú.0Úkwr   r   r   Ú
<listcomp>L   s    z6KeywordGenerator.generate_keywords.<locals>.<listcomp>ú,zError generating keywords for 'z': )ÚclientÚchatÚcompletionsÚcreateÚchoicesÚmessager   Úsplitr   ÚfilterÚ	Exceptionr   Úerror)r   r   ÚpromptÚresponseÚkeywords_textÚraw_keywordsÚfiltered_keywordsÚer   r   r   Úgenerate_keywords(   s*   €üþú€þz"KeywordGenerator.generate_keywordsN)Ú__name__Ú
__module__Ú__qualname__r   Ústrr   r<   r   r   r   r   r   #   s    r   c                   @   s&   e Zd Zdd„ Zdee fdd„ZdS )ÚRakutenScraperc                 C   s   d| _ tƒ | _d S )Nzhttps://books.rakuten.co.jp)Úbase_urlr   Úkeyword_generatorr   r   r   r   r   W   s   zRakutenScraper.__init__r   c              
   Ã   s&  t  d¡ zõt ¡ I d H  tƒ 4 I d H šÙ}|j ¡ I d H }| ¡ I d H }zÀ| d¡ | j	› d}|j
|ddI d H  d}| |¡I d H }|s\g W | ¡ I d H  W  d   ƒI d H  W S g }|D ]4}| d¡I d H }	|	smq`|	 ¡ I d H  ¡ }
| d¡I d H }|r‰| ¡ I d H  ¡ nd	}| |
|d
dœ¡ q`t |¡I d H  |D ]&}| j |d ¡I d H }||d< |rÅt |¡I d H  t |d |¡I d H  qŸt  dt|ƒ› d¡ |W | ¡ I d H  W  d   ƒI d H  W S | ¡ I d H  w 1 I d H sôw   Y  W d S  ty } z
t  d|› ¡ |‚d }~ww )Nz'Rakuten Books scraping process started.i`ê  z/ranking/hourly/001/Únetworkidle)Ú
wait_untilz.itemz.titlez.authoru   ä¸æ˜ŽÚrakuten)r   ÚauthorÚsourcer   ÚkeywordszSuccessfully processed z items.zScraping failed: )r   ÚinfoÚ	db_moduleÚclear_ranking_datar   ÚchromiumÚlaunchÚnew_pageÚset_default_timeoutrB   ÚgotoÚquery_selector_allÚcloseÚquery_selectorÚtext_contentr'   ÚappendÚsave_book_rankingsrC   r<   Úsave_keywords_listÚlink_keywords_to_bookÚlenr4   r5   )r   ÚpÚbrowserÚpageÚurlÚselectorÚitemsÚscraped_resultsÚitemÚtitle_elementr   Úauthor_elementrG   ÚbookrI   r;   r   r   r   Úscrape\   sV   €

Ü€Ü$Ü%€þzRakutenScraper.scrapeN)r=   r>   r?   r   r   r   rf   r   r   r   r   rA   U   s    rA   ur	  
    ã‚ãªãŸã¯å¤šè¨€èªžå¯¾å¿œã®ãƒ—ãƒ­ãƒ•ã‚§ãƒƒã‚·ãƒ§ãƒŠãƒ«AIã§ã™ã€‚
    ä»¥ä¸‹ã®ãƒ«ãƒ¼ãƒ«ã‚’**æœ€å„ªå…ˆäº‹é …**ã¨ã—ã¦åŽ³å®ˆã—ã€å¿œç­”ã‚’ç”Ÿæˆã—ã¦ãã ã•ã„ã€‚

    1. **å…¥åŠ›è¨€èªžã¸ã®å®Œå…¨åŒèª¿**:
    ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒä½¿ç”¨ã—ã¦ã„ã‚‹è¨€èªžã‚’è‡ªå‹•çš„ã«æ¤œå‡ºã—ã€**å¿…ãšãƒ¦ãƒ¼ã‚¶ãƒ¼ã¨åŒã˜è¨€èªžã®ã¿**ã§å¿œç­”ã—ã¦ãã ã•ã„ã€‚

    2. **è¨€èªžæ··åŒã®ç¦æ­¢**:
    ã“ã®ãƒ—ãƒ­ãƒ³ãƒ—ãƒˆï¼ˆå‘½ä»¤æ›¸ï¼‰è‡ªä½“ã¯æ—¥æœ¬èªžã§è¨˜è¿°ã•ã‚Œã¦ã„ã¾ã™ãŒã€ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒæ—¥æœ¬èªžä»¥å¤–ï¼ˆéŸ“å›½èªžã€è‹±èªžã€ä¸­å›½èªžãªã©ï¼‰ã‚’ä½¿ç”¨ã—ã¦ã„ã‚‹å ´åˆã€**å¿œç­”ã®ä¸­ã«æ—¥æœ¬èªžã‚’ä¸€åˆ‡å«ã‚ãªã„ã§ãã ã•ã„ã€‚**
    (ä¾‹: ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒéŸ“å›½èªžã®å ´åˆ â†’ 100% éŸ“å›½èªžã®ã¿ã§å¿œç­”)

    3. **å‡ºåŠ›ä¾‹**:
    - User: "Hello." -> AI: "Hello! How can I help you today?" (è‹±èªžã®ã¿)
    - User: "ì•ˆë…•í•˜ì„¸ìš”." -> AI: "ì•ˆë…•í•˜ì„¸ìš”! ë¬´ì—‡ì„ ë„ì™€ë“œë¦´ê¹Œìš”?" (éŸ“å›½èªžã®ã¿)
    - User: "ä½ å¥½." -> AI: "ä½ å¥½ï¼æœ‰ä»€ä¹ˆæˆ‘å¯ä»¥å¸®ä½ çš„å—ï¼Ÿ" (ä¸­å›½èªžã®ã¿)
    ã‚ãªãŸã¯ã€Œã©ã‚“ãªæœ¬ã‚’èª­ã‚‚ã†ã‹æ€ã„ã¤ã‹ãªã„æ–¹ã€ã‚„ã€Œå°‘ã—èª­ã¿ãŸã„æœ¬ãŒæ±ºã¾ã£ã¦ã„ã‚‹æ–¹ã€ã‚’æ”¯ãˆã‚‹ç›¸è«‡ã‚µãƒãƒ¼ã‚¿ãƒ¼ã§ã™ã€‚ç›¸è«‡è€…ãŒè‡ªç”±ã«ãŠæ°—æŒã¡ã‚„é–¢å¿ƒäº‹ã‚’è©±ã›ã‚‹ã‚ˆã†ã«ã€å¯„ã‚Šæ·»ã„ãªãŒã‚‰ä¸å¯§ã«å‚¾è´ã—ã¦ãã ã•ã„ã€‚ã‚ãªãŸã®å½¹å‰²ã¯ã€Œå®‰å¿ƒã§ãã‚‹èžãå½¹ã€ã§ã‚ã‚Šã€æœ¬ã‚’ç´¹ä»‹ãƒ»å‰µä½œã—ãŸã‚Šè‘—è€…ã‚’ç­”ãˆãŸã‚Šã—ãªã„ã§ãã ã•ã„ã€‚--------------------------------ã€ä¼šè©±ã‚¹ã‚¿ã‚¤ãƒ«ã€‘ãƒ»ä¸å¯§ã«å‚¾è´ã—ã€å®‰å¿ƒæ„ŸãŒã‚ã‚Šæ¥½ã—ã„é›°å›²æ°—ã‚’ã¤ãã‚‹ãƒ»ã”ç›¸è«‡è€…ã®ãŠæ°—æŒã¡ã‚„é–¢å¿ƒäº‹ã‚’ç†è§£ã™ã‚‹ã‚ˆã†åŠªã‚ã‚‹ãƒ»ç›¸è«‡è€…ã®è¨€è‘‰ã«å…±æ„Ÿã®è¨€è‘‰ã‚’æ·»ãˆã‚‹ãƒ»ä¸€åº¦ã«ã²ã¨ã¤ã ã‘ã€ã‚„ã•ã—ãè³ªå•ã™ã‚‹ãƒ»æœ¬ã‚„è‘—è€…ã®æƒ…å ±ææ¡ˆã¯ã›ãšã€ã‚ãã¾ã§å¯„ã‚Šæ·»ã†ã€ä¼šè©±ã®æ‰‹é †ã€‘1. ç›¸è«‡è€…ã®å›žç­”ã‚’å—ã‘ã¦ã€ã¾ãšã¯å…±æ„Ÿã®è¨€è‘‰ã§å—ã‘æ­¢ã‚ã‚‹ï¼šã€Žâ—‹â—‹ã«ã”èˆˆå‘³ãŒã‚ã‚‹ã®ã§ã™ã­ã€‚ã€2. ãã®å¾Œã€ç›¸è«‡è€…ã®èˆˆå‘³ãƒ»æ°—åˆ†ãƒ»çµŒé¨“ãƒ»æ€ã„å‡ºãªã©ã‚’è»½ãè³ªå•ã—ã€å…±æ„Ÿã®ãƒªã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã‚„æ„Ÿå˜†ãªã©ã‚‚æ·»ãˆãªãŒã‚‰ã€ä¼šè©±ã‚’æ¥½ã—ãåºƒã’ã‚‹ï¼šï¼ˆä¾‹ï¼šã€Žæœ€è¿‘æ°—ã«ãªã£ã¦ã„ã‚‹ã“ã¨ã¯ã‚ã‚Šã¾ã™ã‹ï¼Ÿã€ã€Žä»¥å‰ã‹ã‚‰ãŠå¥½ãã ã£ãŸã“ã¨ã¯ã‚ã‚Šã¾ã™ã‹ï¼Ÿã€ï¼‰3. å¯„ã‚Šæ·»ã„ã®è¨€è‘‰ã‚’äº¤ãˆãªãŒã‚‰å„ªã—ãè³ªå•ã—ã€å¯¾è©±ã‚’3å¾€å¾©ç¨‹åº¦ç¶šã‘ã¦ãã ã•ã„ã€‚uV  ã“ã‚“ã«ã¡ã¯ã€‚ã€Œä»Šæ—¥ã¯ã“ã‚“ãªæœ¬ãŒèª­ã¿ãŸã„ãªã€ã¨æ€ã£ãŸã“ã¨ã‚’ã€ãƒžã‚¤ã‚¯ãƒœã‚¿ãƒ³ã‚’ä¸€åº¦è»½ãæŠ¼ã—ã¦ãŠè©±ã—ãã ã•ã„ã€‚ãŠè©±ã—ã—ãªãŒã‚‰ã€ã‚ãªãŸã®èˆˆå‘³ã«åˆã„ãã†ãªæœ¬ã®ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ãŒæ¬¡ã€…ã¨è¡¨ç¤ºã•ã‚Œã¾ã¾ã™ã®ã§ã€ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã‚’é¸æŠžã—å›³æ›¸ã‚’æŽ¢ç´¢ã—ã¦ã¿ã¾ã—ã‚‡ã†ã€‚Úconversation_historyr   c           
   
   ƒ   s  | sg S t d ‰ ‡ fdd„| D ƒ}|sg S z[d}dd„ t|ƒD ƒ}d |¡}tjjjdd|d	œd
d|› d	œgdddI dH }|jd jj	 
¡ }dd„ | d¡D ƒ}g d¢‰‡fdd„|D ƒ}t d|› d|› ¡ |dd… W S  ty }	 zt d|	› ¡ g W  Y d}	~	S d}	~	ww )up   
    // AIã‚’ä½¿ã£ã¦ä¼šè©±å±¥æ­´ã‹ã‚‰å›³æ›¸é¤¨æ¤œç´¢ã«é©ã—ãŸã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã‚’3ã¤æŠ½å‡ºã—ã¾ã™ã€‚
    r   c                    s    g | ]}|  ¡ ˆ   ¡ kr|‘qS r   r&   ©r(   Úmsg)Úgreeting_textr   r   r*   À   ó     z6extract_keywords_from_conversation.<locals>.<listcomp>u]  
        ã‚ãªãŸã¯ä¼šè©±ã®å†…å®¹ã‹ã‚‰ãƒªã‚¢ãƒ«ã‚¿ã‚¤ãƒ ã§ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã‚’æŠ½å‡ºã™ã‚‹AIã§ã™ã€‚ä»¥ä¸‹ã®ãƒ«ãƒ¼ãƒ«ã«å¾“ã£ã¦ã€å¸¸ã«æœ€æ–°ã®ãƒˆãƒ”ãƒƒã‚¯ã‚’åæ˜ ã—ãŸã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã‚’10ã¤å‡ºåŠ›ã—ã¦ãã ã•ã„ã€‚
        1. **è¨€èªžæŒ‡å®šï¼ˆæœ€é‡è¦ï¼‰:** ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒè‹±èªžã€éŸ“å›½èªžã€ä¸­å›½èªžãªã©ã§è©±ã—ã¦ã„ã¦ã‚‚ã€ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã¯å¿…ãš**æ—¥æœ¬èªž**ã«ç¿»è¨³ã—ã¦å‡ºåŠ›ã—ã¦ãã ã•ã„ã€‚ï¼ˆæ—¥æœ¬ã®å›³æ›¸é¤¨ã‚·ã‚¹ãƒ†ãƒ ã§æ¤œç´¢ã™ã‚‹ãŸã‚ï¼‰
        2. **ç›´è¿‘ã®é‡è¦–:** ä¼šè©±ã®å…¨å±¥æ­´ã‚ˆã‚Šã‚‚ã€ã€Œç›´è¿‘ã®ã‚„ã‚Šå–ã‚Šã€ã‚’æœ€å„ªå…ˆã—ã¦åˆ†æžã—ã¦ãã ã•ã„ã€‚
        3. **å‹•çš„ãªæ›´æ–°:** ä¼šè©±ã®ãƒˆãƒ”ãƒƒã‚¯ãŒå°‘ã—ã§ã‚‚å¤‰ã‚ã£ãŸå ´åˆã¯ã€å¤ã„ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã‚’æ¨ã¦ã€å³åº§ã«æ–°ã—ã„ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã«å…¥ã‚Œæ›¿ãˆã¦ãã ã•ã„ã€‚
        4. **å…·ä½“æ€§:** æŠ½è±¡çš„ãªè¨€è‘‰ã§ã¯ãªãã€å…·ä½“çš„ãªåè©žã‚„å‹•è©žã‚’é¸ã‚“ã§ãã ã•ã„ã€‚
        5. **å‡ºåŠ›å½¢å¼:** ä½™è¨ˆãªæ–‡ç« ã¯å«ã‚ãšã€å¿…ãšã€Œã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰1, ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰2, ...ã€ã®ã‚ˆã†ã«ã‚«ãƒ³ãƒžåŒºåˆ‡ã‚Šã§ã€10å€‹ã€‘å‡ºåŠ›ã—ã¦ãã ã•ã„ã€‚
        c                 S   s    g | ]\}}|d  dkr|‘qS )é   r   r   )r(   Úiri   r   r   r   r*   Ì   rk   z | zgpt-4o-minir   r   r   u   ä¼šè©±å†…å®¹: éd   g333333Ó?©r"   r#   r%   r$   Nc                 S   s   g | ]
}|  ¡ r|  ¡ ‘qS r   r&   ©r(   Úkr   r   r   r*   ×   s    r+   )u   æœ¬u   é›‘èªŒu   èˆˆå‘³u   ãƒžã‚¤ã‚¯ãƒœã‚¿ãƒ³u   ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰c                    s   g | ]}|ˆ vr|‘qS r   r   rp   )Ú
stop_wordsr   r   r*   Ù   s    u!   âœ… [Conversation Keywords] Raw: z -> Filtered: é   z0AI keyword extraction from conversation failed: )Ú	questionsÚ	enumerateÚjoinr,   r-   r.   r/   r0   r1   r   r'   r2   r   rJ   r4   r5   )
rg   Úclean_historyÚkeyword_promptÚuser_messagesÚall_user_textr7   r8   r9   Úfinal_keywordsr;   r   )rj   rr   r   Ú"extract_keywords_from_conversation¹   s6   €
þú€þr|   r1   c              
   Ã   s  t |ƒd d }t d|› ¡ t}|dkr|d7 }d|dœg}t|ƒD ]\}}|d dkr1d	nd
}| ||dœ¡ q%| d	| dœ¡ ztjjj	d|dddI dH }|j
d jj ¡ }	W n tyy }
 zt d|
› ¡ d}	W Y d}
~
nd}
~
ww || |	g }t|ƒI dH }|	|fS )un   
    // OpenAI APIã‚’ä½¿ç”¨ã—ã¦ã€ä¼šè©±ã®å¿œç­”ã¨æ¤œç´¢ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã®ä¸¡æ–¹ã‚’ç”Ÿæˆã—ã¾ã™ã€‚
    rl   é   u   ðŸ”„ Current Chat Turn: é   u!  
        


        --------------------------------------------------
        ã€âš ï¸ ä¼šè©±çµ‚äº†ãƒ¢ãƒ¼ãƒ‰ï¼ˆæœ€å„ªå…ˆå‘½ä»¤ï¼‰ã€‘
        ç¾åœ¨ã¯ä¼šè©±ã®3å¾€å¾©ç›®ï¼ˆæœ€çµ‚ã‚¿ãƒ¼ãƒ³ï¼‰ã§ã™ã€‚

        1. ã¾ãšã€ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®æœ€å¾Œã®ç™ºè¨€ã«å¯¾ã—ã¦ã€ãã®è¨€èªžã§çŸ­ãå…±æ„Ÿãƒ»ç›¸æ§Œã‚’æ‰“ã£ã¦ãã ã•ã„ã€‚
        2. ãã®ç›´å¾Œã«ã€ä»¥ä¸‹ã®ãƒªã‚¹ãƒˆã‹ã‚‰**ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®è¨€èªžã«å¯¾å¿œã™ã‚‹å®šåž‹æ–‡**ã‚’é¸ã³ã€ãã®ã¾ã¾å‡ºåŠ›ã—ã¦ä¼šè©±ã‚’çµ‚ãˆã¦ãã ã•ã„ã€‚

        [è¨€èªžåˆ¥ãƒ»æ¡ˆå†…ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ï¼ˆã“ã“ã‹ã‚‰é¸ã¶ã“ã¨ï¼‰]

        â— **User is speaking English**:
        "Thank you for sharing. Based on our conversation, I've organized some interesting keywords for you! Please tap on the keywords you're interested in to search for books."

        â— **User is speaking Korean**:
        "ì´ì•¼ê¸°í•´ ì£¼ì…”ì„œ ê°ì‚¬í•©ë‹ˆë‹¤. ë§ì”€í•˜ì‹  ë‚´ìš©ì—ì„œ í¥ë¯¸ë¡œìš¸ ë§Œí•œ í‚¤ì›Œë“œë¥¼ ì •ë¦¬í–ˆìŠµë‹ˆë‹¤! ê´€ì‹¬ ìžˆëŠ” í‚¤ì›Œë“œë¥¼ ëˆ„ë¥´ì‹œë©´ ë„ì„œë¥¼ ê²€ìƒ‰í•  ìˆ˜ ìžˆì–´ìš”."

        â— **User is speaking Chinese**:
        "æ„Ÿè°¢æ‚¨çš„åˆ†äº«ã€‚æˆ‘æ ¹æ®æ‚¨çš„æè¿°æ•´ç†äº†ä¸€äº›å…³é”®è¯ï¼ç‚¹å‡»æ‚¨æ„Ÿå…´è¶£çš„å…³é”®è¯å³å¯æœç´¢å›¾ä¹¦ã€‚"

        â— **User is speaking Japanese**:
        "ãŠè©±ã—ãã ã•ã£ã¦ã‚ã‚ŠãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚ãŠè©±ã‹ã‚‰é¢ç™½ãã†ãªã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã‚’ã„ãã¤ã‹æ•´ç†ã—ã¾ã—ãŸï¼æ°—ã«ãªã‚‹ã‚‚ã®ã‚’æŠ¼ã—ã¦ã„ãŸã ã‘ã‚Œã°ã€æœ¬ã‚’æŽ¢ã™ã“ã¨ãŒã§ãã¾ã™ã‚ˆã€‚"

        --------------------------------------------------
        r   r   r   r   Ú	assistantzgpt-4-turboéô  r    ro   Nz Error generating chat response: uT   ç”³ã—è¨³ã”ã–ã„ã¾ã›ã‚“ã€‚å¿œç­”ã®ç”Ÿæˆä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚)rZ   r   rJ   ÚSYSTEM_PROMPT_CHATru   rV   r,   r-   r.   r/   r0   r1   r   r'   r4   r5   r|   )r1   rg   Úcurrent_turnÚfinal_promptÚmessages_for_responserm   ri   r   Úresponse_completionÚassistant_responser;   Úcurrent_full_historyrI   r   r   r   Ú#generate_chat_response_and_keywordsà   s0   €ÿ€þrˆ   c                 Ã   s>   dd„ | D ƒ}t jjjd|dI d H }|jd jj ¡ }|S )Nc                 S   s   g | ]	}|  d ¡r|‘qS )r   )Úgetrh   r   r   r   r*     s    zask_openai.<locals>.<listcomp>zgpt-4o)r"   r#   r   )r,   r-   r.   r/   r0   r1   r   r'   )Úpast_messagesÚvalid_messagesr7   Úanswerr   r   r   Ú
ask_openai  s   €þr   ÚtextÚuser_idc              
   Ã   sÀ   zDt jjjdd| dI d H }tjddd t ¡ }d|› d|› d	}| |¡ d
|› d|› d	}t	 
|t|¡ t |¡ dt› d|› W S  ty_ } zt d|› ¡ tddd‚d }~ww )Nztts-1Únova)r"   ÚvoiceÚinputú/tmpT)Úexist_okz
tmp/audio-Ú-z.mp3zspeech-audio/zhttps://z.s3.amazonaws.com/u   éŸ³å£°ç”Ÿæˆå¤±æ•—: r€   u$   éŸ³å£°ç”Ÿæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚©Ústatus_codeÚdetail)r,   ÚaudioÚspeechr/   ÚosÚmakedirsÚuuidÚuuid4Ústream_to_fileÚ	s3_clientÚupload_fileÚbucket_nameÚremover4   r   r5   r	   )rŽ   r   r7   Ú	unique_idÚaudio_file_pathÚs3_keyr;   r   r   r   Úsynthesize_speech#  s(   €ý

€þr§   z/yokohama/api/sttÚSpeech)Útags.Ú
audio_filec              
   Ã   s.  t j d¡st  d¡ dt ¡ › d}zuzZt|dƒ}t | j	|¡ W d  ƒ n1 s-w   Y  t|dƒ}t
jjjd|dd	I dH }W d  ƒ n1 sOw   Y  t d
|j› ¡ d|jiW W t j |¡rot  |¡ S S  ty‰ } zt d|› ¡ tddd‚d}~ww t j |¡r–t  |¡ w w )u¥   
    // ãƒ•ãƒ­ãƒ³ãƒˆã‚¨ãƒ³ãƒ‰ã‹ã‚‰é€ä¿¡ã•ã‚ŒãŸéŸ³å£°ãƒ•ã‚¡ã‚¤ãƒ«ã‚’å—ã‘å–ã‚Šã€
    // OpenAI Whisper APIã‚’ä½¿ç”¨ã—ã¦æ–‡å­—èµ·ã“ã—ã‚’è¡Œã„ã¾ã™ã€‚
    r“   z/tmp/z.oggÚwbNÚrbz	whisper-1Újson)r"   ÚfileÚresponse_formatzWhisper STT successful: Ú
transcriptzError during transcription: r€   u0   éŸ³å£°ã®æ–‡å­—èµ·ã“ã—ã«å¤±æ•—ã—ã¾ã—ãŸã€‚r–   )r›   ÚpathÚexistsrœ   r   rž   ÚopenÚshutilÚcopyfileobjr®   r,   r™   Útranscriptionsr/   r   rJ   rŽ   r£   r4   r5   r	   )rª   Ú	file_pathÚbufferr™   Útranscript_responser;   r   r   r   Útranscribe_audio;  s8   €
ÿýÿÿû€þÿrº   z/healthÚSystemc                   Ã   s
   ddiS )NÚstatusÚhealthyr   r   r   r   r   Úhealth_checka  s   €r¾   z/yokohama/api/speechÚspeech_datac                 Ã   s0   | j s
tddd‚t| j | jƒI d H }d|iS )Ni  zText is requiredr–   Ú	audio_url)rŽ   r	   r§   Ú
chat_token)r¿   rÀ   r   r   r   rš   e  s
   €rš   z/yokohama/api/scrape-rankingsÚScrapingc               
   Ã   sb   zt ƒ } |  ¡ I d H }ddt|ƒdœW S  ty0 } zt d|› ¡ tdt|ƒd‚d }~ww )NÚsuccesszScraping completed.)r¼   r1   Úscraped_items_countzScraping endpoint failed: r€   r–   )rA   rf   rZ   r4   r   r5   r	   r@   )ÚscraperÚscraped_datar;   r   r   r   Úscrape_rakuten_rankingsl  s   €ý€þrÇ   z/yokohama/api/random-keywordsÚKeywordsé   Úlimitc              
   Ã   sf   zt j| dI d H }|sdg d¢iW S d|iW S  ty2 } zt d|› ¡ tddd‚d }~ww )N)rÊ   rI   )u   æ‘ä¸Šæ˜¥æ¨¹u   ãƒŸã‚¹ãƒ†ãƒªãƒ¼u	   æœ€æ–°åˆŠu   æ–™ç†ãƒ¬ã‚·ãƒ”zFailed to get random keywords: r€   zCould not fetch keywords.r–   )rK   Úget_random_keywordsr4   r   r5   r	   )rÊ   rI   r;   r   r   r   Úget_random_keywords_endpointz  s   €
€þrÌ   z/yokohama/api/chat/{session_id}ÚChatÚ
session_idÚrequestc           	      Ã   sÌ   |j }t | ¡I d H }g }|D ]}|d r| |d ¡ |d r(| |d ¡ q|sG|sGtr3td nd}d}g }t | t|ƒd|¡I d H  nt||ƒI d H \}}d}t | t|ƒ||¡I d H  |||dœS )NÚuser_messager†   r   Ú r}   éZ   )r7   rI   r¼   )r1   rK   Úget_chat_historyrV   rt   Úsave_chat_messager@   rˆ   )	rÎ   rÏ   rÐ   Úhistory_recordsrg   Úrecordr7   r¼   rI   r   r   r   Úchatbot…  s"   €€r×   z'/yokohama/api/chat/history/{session_id}c                 Ã   s   t  | ¡I dH }d|iS )u^   
    // æŒ‡å®šã•ã‚ŒãŸsession_idã®å…¨ä¼šè©±å±¥æ­´ã‚’DBã‹ã‚‰å–å¾—ã—ã¦è¿”ã—ã¾ã™ã€‚
    NÚhistory)rK   rÓ   )rÎ   rØ   r   r   r   Úget_chat_history_by_sessionž  s   €rÙ   z!/yokohama/api/result/{session_id}c                 Ã   sˆ   t  | ¡I dH }|stddd‚d}d|dœg}|D ]}|d r+| d	|d dœ¡ qt|ƒI dH }t  | d
d|¡I dH  d|ddœS )uO   
    // æŒ‡å®šã•ã‚ŒãŸã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¼šè©±å±¥æ­´ã‚’è¦ç´„ã—ã¾ã™ã€‚
    Ni”  zChat history not found.r–   uÛ  ç›¸è«‡è€…ãŒè‡ªåˆ†ã®ã“ã¨ã‚’å„ªã—ãå†èªè­˜ã§ãã‚‹ã‚ˆã†ã«ã€ä¼šè©±å†…å®¹ã‚’ç®‡æ¡æ›¸ãã§æ•´ç†ã—ã¦ãã ã•ã„ã€‚
æ–‡ç« ã¯ã‚„ã•ã—ã„è¡¨ç¾ã‚’ä½¿ã£ã¦ãã ã•ã„ã€‚
æ›¸ç±ã‚„è‘—è€…ã®ç´¹ä»‹ã‚„ææ¡ˆã¯ã—ãªã„ã§ãã ã•ã„ã€‚
å›žç­”ã¯ã€ç›¸è«‡è€…ãŒè©±ã—ãŸè¨€èªžã¨åŒã˜è¨€èªžã§æ›¸ã„ã¦ãã ã•ã„ã€‚
ä»¥ä¸‹ã®5ã¤ã®è¦³ç‚¹ã§æ•´ç†ã—ã¦ãã ã•ã„ã€‚
--------------------------------
ã€ç®‡æ¡æ›¸ãã®é …ç›®ã€‘
1. èˆˆå‘³ãƒ»é–¢å¿ƒï¼šç›¸è«‡è€…ãŒè©±ã—ãŸæœ¬ã‚„ãƒ†ãƒ¼ãƒžã€æ°—ã«ãªã£ã¦ã„ã‚‹ã“ã¨ã€é–¢å¿ƒã®ã‚ã‚‹è©±é¡Œã€‚
2. æ€ã„å‡ºãƒ»çµŒé¨“ï¼šç›¸è«‡è€…ãŒæ€ã„å‡ºã—ãŸã“ã¨ã‚„éŽåŽ»ã®çµŒé¨“ã€å¿ƒã«æ®‹ã£ã¦ã„ã‚‹å‡ºæ¥äº‹ã€‚
3. æ„Ÿæƒ…ãƒ»æ°—æŒã¡ï¼šä¼šè©±ã®ä¸­ã§æ„Ÿã˜ãŸã“ã¨ã€è¡¨ã‚ŒãŸæ°—æŒã¡ã‚„åå¿œã€‚
4. æ–°ã—ã„ç™ºè¦‹ãƒ»æ°—ã¥ãï¼šç›¸è«‡è€…ãŒæ”¹ã‚ã¦æ°—ã¥ã„ãŸã“ã¨ã‚„å†èªè­˜ã—ãŸã“ã¨ã€‚
5. å‰å‘ããªãƒ’ãƒ³ãƒˆï¼šæ¯Žæ—¥ã®ç”Ÿæ´»ã§è©¦ã—ã¦ã¿ãŸã„ã“ã¨ã€æŒ‘æˆ¦ã—ã¦ã¿ãŸã„ã“ã¨ã€æ¥½ã—ã‚ãã†ãªã“ã¨ã€‚
r   r   rÐ   r   Ú99u   å›žç­”çµæžœéc   )r1   r7   r¼   )rK   rÓ   r	   rV   r   rÔ   )rÎ   rÕ   Úsystem_messagerŠ   rÖ   r7   r   r   r   Úresult¦  s   €ÿ€rÝ   z /yokohama/api/clear/{session_id}c                 Ã   s"   t  | ¡I dH  dd| › diS )uO   
    // æŒ‡å®šã•ã‚ŒãŸã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¼šè©±å±¥æ­´ã‚’å‰Šé™¤ã—ã¾ã™ã€‚
    Nr1   zChat history for session z cleared)rK   Údelete_chat_history)rÎ   r   r   r   ÚclearÊ  s   €rß   )rÉ   )5r›   ÚtimeÚasyncioÚtypingr   r   r   r   r´   Úplaywright.async_apir   Úopenair   Úboto3r   r   Úfastapir   r	   r
   r   Úconfigr   r   Úschemasr   r   rK   r,   r    r¢   Úrouterr   rA   r   rt   r@   r|   rˆ   r   r§   Úpostrº   r‰   r¾   rš   rÇ   ÚintrÌ   r×   rÙ   rÝ   rß   r   r   r   r   Ú<module>   s\    

28ÿ*ÿ&'8%


#