o
    Zh                     @   sT   d dl mZmZ d dlZd dlmZ d dlmZ d dlm	Z	 dZ
G dd deZdS )	    )ListOptionalN)Document)
BaseLoader)WebBaseLoaderzhttps://www.ifixit.com/api/2.0c                	   @   s   e Zd ZdZdefddZdee fddZe	dd
ededee fddZ
	ddee dee fddZ	ddee dedee fddZddee dee fddZdS )IFixitLoadera  Load `iFixit` repair guides, device wikis and answers.

    iFixit is the largest, open repair community on the web. The site contains nearly
    100k repair manuals, 200k Questions & Answers on 42k devices, and all the data is
    licensed under CC-BY.

    This loader will allow you to download the text of a repair guide, text of Q&A's
    and wikis from devices on iFixit using their open APIs and web scraping.
    web_pathc                    s   | ds	td|dd g d}	 t fdd|D s#tddd	  d
D }	 |d dkr8|d nd| _| jdksE| jdkrK|d | _n|d | _|| _dS )zInitialize with a web path.zhttps://www.ifixit.comz1web path must start with 'https://www.ifixit.com' )z/Devicez/Guidez/Answersz	/Teardownc                 3   s    | ]}  |V  qd S N)
startswith).0Zallowed_pathpath b/var/www/html/lang_env/lib/python3.10/site-packages/langchain_community/document_loaders/ifixit.py	<genexpr>!   s    z(IFixitLoader.__init__.<locals>.<genexpr>z?web path must start with /Device, /Guide, /Teardown or /Answersc                 S   s   g | ]}|r|qS r   r   )r   xr   r   r   
<listcomp>&       z)IFixitLoader.__init__.<locals>.<listcomp>/r   TeardownGuideAnswers      N)r   
ValueErrorreplaceanysplit	page_typeidr   )selfr   Zallowed_pathspiecesr   r   r   __init__   s    


zIFixitLoader.__init__returnc                 C   sN   | j dkr	|  S | j dks| j dkr|  S | j dkr |  S td| j  )NDevicer   r   r   zUnknown page type: )r   load_device
load_guideload_questions_and_answersr   )r!   r   r   r   load2   s   

zIFixitLoader.loadr	   allquerydoc_typec              	   C   s   t td |  d | }|jdkrtd|  d |  | }|d }g }|D ]'}zt|d }|jdkrA||jd	d
7 }n||	 7 }W q* tyQ   Y q*w |S )zLoad suggestions.

        Args:
            query: A query string
            doc_type: The type of document to search for. Can be one of "all",
              "device", "guide", "teardown", "answer", "wiki".

        Returns:

        z	/suggest/z
?doctypes=   z Could not load suggestions for "z"
resultsurlr%   F)include_guides)
requestsgetIFIXIT_BASE_URLstatus_coder   jsonr   r   r&   r)   )r+   r,   resdatar.   outputresultloaderr   r   r   load_suggestions<   s*   

zIFixitLoader.load_suggestionsNurl_overridec           
      C   s  t |du r| jn|}| }g }|ddj}|d|  ||dj  |dd}|r<|d|j   |d	D ]5}|	d
rTd|d
 v rT|d nd|d v r`|d n|d |dd |dD 7 }|d qAd
| }| j|d}	t||	dgS )zLoad a list of questions and answers.

        Args:
            url_override: A URL to override the default URL.

        Returns: List[Document]

        NZh1z
post-title# z.post-content .post-textdivzpost-answers-headerz
## z".js-answers-list .post.post-answerZitempropZacceptedAnswerz
### Accepted Answerzpost-helpfulclassz
### Most Helpful Answerz
### Other Answerc                 S   s   g | ]}|j  qS r   )textstrip)r   ar   r   r   r      s    
z;IFixitLoader.load_questions_and_answers.<locals>.<listcomp>
sourcetitleZpage_contentmetadata)r   r   Zscrapefindr@   appendZ
select_onerA   selectZhas_attrjoinr   )
r!   r<   r:   Zsoupr8   rF   ZanswersHeaderZanswerr@   rH   r   r   r   r(   b   s,   
z'IFixitLoader.load_questions_and_answersTr0   c           
         s   g }|du rt d | j }n|}t|}|  d fdddD  }| j d d}|t	||d	 |rT	 d
d  d D }|D ]}	|t
|	 d  qF|S )zLoads a device

        Args:
            url_override: A URL to override the default URL.
            include_guides: Whether to include guides linked to from the device.
              Defaults to True.

        Returns:

        Nz/wikis/CATEGORY/rC   c                    s   g | ]
}| v r | qS r   r   )r   keyr7   r   r   r      s
    z,IFixitLoader.load_device.<locals>.<listcomp>)rF   descriptionZcontents_rawrF   rD   rG   c                 S   s   g | ]}|d  qS )r/   r   )r   Zguider   r   r   r      r   Zguidesr   )r3   r    r1   r2   r5   rL   rA   r   rJ   r   r   r)   )
r!   r<   r0   Z	documentsr/   r6   r@   rH   Z
guide_urlsZ	guide_urlr   rN   r   r&      s*   

zIFixitLoader.load_devicec                 C   s~  |du rt d | j }n|}t|}|jdkr%td| j d |  | }d|d  |d g}|d	 t	|d
 dkrF|d n|d
 D ]}|d|d   qJ|d t	|d dkri|d n|d D ]}|d|d   qm|d D ]&}|d|d dkr|d nd
|d   |d D ]	}	||	d  qq}||d  d|}
| j|d d}t|
|dgS )zLoad a guide

        Args:
            url_override: A URL to override the default URL.

        Returns: List[Document]

        Nz/guides/r-   zCould not load guide: rC   r=   rF   Zintroduction_rawz

###Tools Required:Ztoolsr   z
 - Nonez
 - r@   z

###Parts Required:partsZstepsz

## r	   zStep {}ZorderbylinesZtext_rawZconclusion_rawrD   rG   )r3   r    r1   r2   r4   r   r   r5   rJ   lenformatrL   r   )r!   r<   r/   r6   r7   Z	doc_partsZtoolpartrowliner@   rH   r   r   r   r'      sF   	



	
zIFixitLoader.load_guide)r	   r*   r
   )NT)__name__
__module____qualname____doc__strr#   r   r   r)   staticmethodr;   r   r(   boolr&   r'   r   r   r   r   r      s*    

&
-
 (r   )typingr   r   r1   Zlangchain_core.documentsr   Z)langchain_community.document_loaders.baser   Z-langchain_community.document_loaders.web_baser   r3   r   r   r   r   r   <module>   s    