o
    \h-                     @   sP   d dl Z d dlZd dlZddlmZ ddlmZ ddlmZ G dd deZ	dS )	    N   )AbstractFileSysteminfer_storage_options   )
MemoryFilec                       s   e Zd ZdZdZdZdZdZ	d& fdd	Ze	d	d
 Z
ed'ddZe	dd Ze	dd Ze	dd Zd(ddZd)ddZe fddZedd Z				d*ddZd(d d!Zd)d"d#Zd$d% Z  ZS )+GithubFileSystema  Interface to files in github

    An instance of this class provides the files residing within a remote github
    repository. You may specify a point in the repos history, by SHA, branch
    or tag (default is current master).

    For files less than 1 MB in size, file content is returned directly in a
    MemoryFile. For larger files, or for files tracked by git-lfs, file content
    is returned as an HTTPFile wrapping the ``download_url`` provided by the
    GitHub API.

    When using fsspec.open, allows URIs of the form:

    - "github://path/file", in which case you must specify org, repo and
      may specify sha in the extra args
    - 'github://org:repo@/precip/catalog.yml', where the org and repo are
      part of the URI
    - 'github://org:repo@sha/precip/catalog.yml', where the sha is also included

    ``sha`` can be the full or abbreviated hex of the commit you want to fetch
    from, or a branch or tag name (so long as it doesn't contain special characters
    like "/", "?", which would have to be HTTP-encoded).

    For authorised access, you must provide username and token, which can be made
    at https://github.com/settings/tokens
    z9https://api.github.com/repos/{org}/{repo}/git/trees/{sha}zChttps://api.github.com/repos/{org}/{repo}/contents/{path}?ref={sha}github)<   r
   Nc                    s   t  jd	i | || _|| _|d u |d u A rtd|| _|| _|d ur(|| _|d u rJd}tj	|j
||dfd| ji| j}	|	  |	 d }|| _| d zddlm}
 |
d	i || _W d S  typ   d | _Y d S w )
Nz%Auth required both username and tokenz)https://api.github.com/repos/{org}/{repo}orgrepotimeoutdefault_branch r   )HTTPFileSystem )super__init__r   r   
ValueErrorusernametokenr   requestsgetformatkwraise_for_statusjsonrootlshttpr   http_fsImportError)selfr   r   shar   r   r   kwargsurr   	__class__r   `/home/air/segue/gemini/backup/venv/lib/python3.10/site-packages/fsspec/implementations/github.pyr   ,   s8   
zGithubFileSystem.__init__c                 C   s   | j rd| j | jfiS i S )Nauth)r   r   r#   r   r   r*   r   J   s   zGithubFileSystem.kwTc                 C   s@   t jdddg|  d| d| jd}|  dd | D S )	av  List repo names for given org or user

        This may become the top level of the FS

        Parameters
        ----------
        org_or_user: str
            Name of the github org or user to query
        is_org: bool (default True)
            Whether the name is an organisation (True) or user (False)

        Returns
        -------
        List of string
        zhttps://api.github.com/usersorgs/z/repos)r   c                 S      g | ]}|d  qS namer   ).0r   r   r   r*   
<listcomp>f       z*GithubFileSystem.repos.<locals>.<listcomp>)r   r   r   r   r   )clsorg_or_useris_orgr'   r   r   r*   reposP   s   zGithubFileSystem.reposc                 C   F   t jd| j d| j dfd| ji| j}|  dd | D S )zNames of tags in the repohttps://api.github.com/repos/r/   z/tagsr   c                 S   r0   r1   r   r3   tr   r   r*   r4   q   r5   z)GithubFileSystem.tags.<locals>.<listcomp>r   r   r   r   r   r   r   r   r#   r'   r   r   r*   tagsh      zGithubFileSystem.tagsc                 C   r:   )zNames of branches in the repor;   r/   z	/branchesr   c                 S   r0   r1   r   r<   r   r   r*   r4   |   r5   z-GithubFileSystem.branches.<locals>.<listcomp>r>   r?   r   r   r*   branchess   rA   zGithubFileSystem.branchesc                 C   s   | j | jdS )z#Named references, tags and branchesr@   rB   rC   r,   r   r   r*   refs~   s   zGithubFileSystem.refsFc           
         s  |     dkr|p| j}|du ra dd}d|p | j}|D ]=}| jd||d}r5d| n|7 fdd|D }|sGt |d }|d	 d
kr\|rX|g  S    S |d }q# | jvsm|| jdfvrtj| j	j
| j| j|dfd| ji| j}	|	jdkrt |	  d
dd fdd|	 d D }|| jdfv r|| j < n| j  }|r|S tdd |D S )a	  List files at given path

        Parameters
        ----------
        path: str
            Location to list, relative to repo root
        detail: bool
            If True, returns list of dicts, one per file; if False, returns
            list of full filenames only
        sha: str (optional)
            List at the given point in the repo history, branch or tag name or commit
            SHA
        _sha: str (optional)
            List this specific tree object (used internally to descend into trees)
        r   Nr/   T)r$   _shac                    s   g | ]
}|d   kr|qS r1   r   )r3   o)so_farr   r*   r4      s    z'GithubFileSystem.ls.<locals>.<listcomp>r   typefiler$   )r   r   r$   r     	directory)blobtreec              	      sX   g | ](}|d  v r r d |d  n|d |d |d   | dd|d dqS )rH   r/   pathmodesizer   r$   )r2   rO   rH   rP   r$   )r   r3   f)rN   typesr   r*   r4      s    

rM   c                 S   r0   r1   r   rQ   r   r   r*   r4      r5   )_strip_protocolr   rstripsplitr   FileNotFoundErrordircacher   r   urlr   r   r   r   r   status_coder   r   sorted)
r#   rN   detailr$   rE   r%   partspartoutr'   r   )rN   rG   rS   r*   r      sR   









zGithubFileSystem.lsc                 C   s   | j   d S N)rX   clear)r#   rN   r   r   r*   invalidate_cache   s   z!GithubFileSystem.invalidate_cachec                    s*   t |}d|vrt |S |d dS )Nr   rN   r/   )r   r   rT   lstrip)r6   rN   optsr(   r   r*   rT      s   z GithubFileSystem._strip_protocolc                 C   s>   t | }d|vr
i S |d |d d}|d r|d |d< |S )Nr   passwordr   hostr$   r   )rN   rd   r_   r   r   r*   _get_kwargs_from_urls   s   z&GithubFileSystem._get_kwargs_from_urlsrbc                 K   s   |dkrt | jj| j| j||p| jd}tj|fd| ji| j	}|j
dkr+t||  | }	|	d rIt|	d }
|
dsItd d |
S | jd u rRtd| jj|	d f|||d	|S )
Nrh   r   r   rN   r$   r   rJ   contents#   version https://git-lfs.github.com/zRPlease install fsspec[http] to access github files >1 MB or git-lfs tracked files.download_url)rO   
block_sizecache_options)NotImplementedErrorcontent_urlr   r   r   r   r   r   r   r   rZ   rW   r   r   base64	b64decode
startswithr   r!   r"   open)r#   rN   rO   rl   rm   r$   r%   rY   r'   content_jsonrj   r   r   r*   _open   s6   	


zGithubFileSystem._openc                 C   s0   | j |||d}t|D ]	}| j||d qd S )N)	recursivemaxdepth)message)expand_pathreversedrm_file)r#   rN   rv   rw   rx   pr   r   r*   rm  s   zGithubFileSystem.rmc                 K   s$  | j std| |}| |}|sC| jj| j| j|d| j	d}t
j|fd| ji| j}|jdkr9t||  | d }| jj| j| j|| j	d}| j	}|pYd| |d|rbd	|ini }	t
j|f|	| jd
| j}| dd}
td|
rd}t||  | | dS )aW  
        Remove a file from a specified branch using a given commit message.

        Since Github DELETE operation requires a branch name, and we can't reliably
        determine whether the provided SHA refers to a branch, tag, or commit, we
        assume it's a branch. If it's not, the user will encounter an error when
        attempting to retrieve the file SHA or delete the file.

        Parameters
        ----------
        path: str
            The file's location relative to the repository root.
        message: str, optional
            The commit message for the deletion.
        zAuthentication requiredr/   ri   r   rJ   r$   zDelete )rx   r$   branch)r   r   rx   r   zBranch .+ not foundzTRemove only works when the filesystem is initialised from a branch or default (None)N)r   r   rT   _get_sha_from_cachero   r   r   r   rc   r   r   r   r   r   rZ   rW   r   r   deleteresearchrb   )r#   rN   rx   r%   r$   rY   r'   
delete_urlr~   dataerror_messageerrorr   r   r*   r{     s:   


zGithubFileSystem.rm_filec                 C   sL   | j  D ]}|D ]}|d}|r"||kr"d|v r"|d     S q	qd S )Nr2   r$   )rX   valuesr   )r#   rN   entriesentry
entry_pathr   r   r*   r   G  s   
z$GithubFileSystem._get_sha_from_cache)NNNN)T)FNNr`   )rh   NNN)__name__
__module____qualname____doc__rY   ro   protocolr   r   propertyr   classmethodr9   r@   rB   rD   r   rb   rT   staticmethodrg   ru   r}   r{   r   __classcell__r   r   r(   r*   r      s@    







B


3
6r   )
rp   r   r   specr   utilsr   memoryr   r   r   r   r   r*   <module>   s    