U
    h                     @   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edddZee dddZe	deeee d
ddZ
dee ee dddZdee eee dddZdee ee d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 ddddg}t fdd	|D sHtd
dd  dD }|d dkrp|d nd| _| jdks| jdkr|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 O/tmp/pip-unpacked-wheel-9gdii04g/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>&   s      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   sR   | j dkr|  S | j dks&| j dkr.|  S | j dkr@|  S td| j  d S )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_typer"   c              	   C   s   t td |  d | }|jdkr<td|  d |  | }|d }g }|D ]V}z8t|d }|jdkr||jd	d
7 }n||	 7 }W qT tk
r   Y qTY qTX qT|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_overrider"   c           
      C   s  t |dkr| jn|}| }g }|ddj}|d|  ||dj  |dd}|rx|d|j   |d	D ]j}|	d
rd|d
 kr|d n"d|d kr|d n
|d |dd |dD 7 }|d qd
| }| 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]

        N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_oner@   selectZhas_attrjoinr   )
r   r:   r8   Zsoupr6   rE   ZanswersHeaderZanswerr?   rG   r   r   r   r&   b   s,    
z'IFixitLoader.load_questions_and_answersT)r:   r.   r"   c           
         s   g }|dkrt d | j }n|}t|}|  d fdddD  }| j d d}|t	||d	 |rd
d  d D }|D ]}	|t
|	 d  q|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/rB   c                    s   g | ]}| kr | qS r   r   )r   keyr5   r   r   r      s   z,IFixitLoader.load_device.<locals>.<listcomp>)rE   descriptionZcontents_rawrE   rC   rF   c                 S   s   g | ]}|d  qS )r-   r   )r   Zguider   r   r   r      s     Zguidesr   )r1   r   r/   r0   r3   rK   r@   r   rI   r   r   r'   )
r   r:   r.   Z	documentsr-   r4   r?   rG   Z
guide_urlsZ	guide_urlr   rM   r   r$      s$    

zIFixitLoader.load_devicec                 C   s  |dkrt d | j }n|}t|}|jdkrJtd| j d |  | }d|d  |d g}|d	 t	|d
 dkr|d n |d
 D ]}|d|d   q|d t	|d dkr|d n |d D ]}|d|d   q|d D ]P}|d|d dkr|d nd
|d   |d D ]}	||	d  q4q||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: rB   r<   rE   Zintroduction_rawz

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

###Parts Required:partsZstepsz

## r	   zStep {}ZorderbylinesZtext_rawZconclusion_rawrC   rF   )r1   r   r/   r0   r2   r   r   r3   rI   lenformatrK   r   )r   r:   r-   r4   r5   Z	doc_partsZtoolpartrowliner?   rG   r   r   r   r%      sD    	




	
zIFixitLoader.load_guide)r	   r(   )N)NT)N)__name__
__module____qualname____doc__strr!   r   r   r'   staticmethodr9   r   r&   boolr$   r%   r   r   r   r   r      s$   

& -    (r   )typingr   r   r/   Zlangchain_core.documentsr   Z)langchain_community.document_loaders.baser   Z-langchain_community.document_loaders.web_baser   r1   r   r   r   r   r   <module>   s   