o
    _Zh-                     @   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}Z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timeoutZ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   L/var/www/auris/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   L   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/ZusersZorgs/z/repos)r   c                 S      g | ]}|d  qS namer   ).0r   r   r   r(   
<listcomp>h       z*GithubFileSystem.repos.<locals>.<listcomp>)r   r   r   r   r   )clsZorg_or_userZis_orgr%   r   r   r(   reposR   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   r,   r-   r   r/   tr   r   r(   r0   s   r1   z)GithubFileSystem.tags.<locals>.<listcomp>r   r   r   r   r   r   r   r   r!   r%   r   r   r(   tagsj      zGithubFileSystem.tagsc                 C   r4   )zNames of branches in the repor5   r+   z	/branchesr   c                 S   r,   r-   r   r6   r   r   r(   r0   ~   r1   z-GithubFileSystem.branches.<locals>.<listcomp>r8   r9   r   r   r(   branchesu   r;   zGithubFileSystem.branchesc                 C   s   | j | jdS )z#Named references, tags and branchesr:   r<   r=   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 r-   r   )r/   o)so_farr   r(   r0      s    z'GithubFileSystem.ls.<locals>.<listcomp>r   typefiler"   )r   r   r"   r     	directory)Zblobtreec              	      sX   g | ](}|d  v r r d |d  n|d |d |d   | dd|d dqS )rB   r+   pathmodesizer   r"   )r.   rH   rB   rI   r"   )r   r/   f)rG   typesr   r(   r0      s    

rF   c                 S   r,   r-   r   rJ   r   r   r(   r0      r1   )_strip_protocolr   rstripsplitr   FileNotFoundErrordircacher   r   urlr   r   r   r   r   status_coder   r   sorted)
r!   rG   detailr"   r?   r#   partspartoutr%   r   )rG   rA   rL   r(   r      sR   









zGithubFileSystem.lsc                 C   s   | j   d S N)rQ   clear)r!   rG   r   r   r(   invalidate_cache   s   z!GithubFileSystem.invalidate_cachec                    s*   t |}d|vrt |S |d dS )Nr   rG   r+   )r   r   rM   lstrip)r2   rG   optsr&   r   r(   rM      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   )rG   r]   rX   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 )
Nra   r   r   rG   r"   r   rD   contents#   version https://git-lfs.github.com/zRPlease install fsspec[http] to access github files >1 MB or git-lfs tracked files.Zdownload_url)rH   
block_sizecache_options)NotImplementedErrorcontent_urlr   r   r   r   r   r   r   r   rS   rP   r   r   base64	b64decode
startswithr   r   r    open)r!   rG   rH   rd   re   r"   r#   rR   r%   Zcontent_jsonrc   r   r   r(   _open   s6   	


zGithubFileSystem._openc                 C   s0   | j |||d}t|D ]	}| j||d qd S )N)	recursivemaxdepth)message)Zexpand_pathreversedrm_file)r!   rG   rm   rn   ro   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+   rb   r   rD   r"   zDelete )ro   r"   branch)r   r   ro   r   zBranch .+ not foundzTRemove only works when the filesystem is initialised from a branch or default (None)N)r   r   rM   _get_sha_from_cacherg   r   r   r   r\   r   r   r   r   r   rS   rP   r   r   deleteresearchr[   )r!   rG   ro   r#   r"   rR   r%   Z
delete_urlrt   dataerror_messageerrorr   r   r(   rq     s:   


zGithubFileSystem.rm_filec                 C   sL   | j  D ]}|D ]}|d}|r"||kr"d|v r"|d     S q	qd S )Nr.   r"   )rQ   valuesr   )r!   rG   entriesentry
entry_pathr   r   r(   ru   I  s   
z$GithubFileSystem._get_sha_from_cache)NNNN)T)FNNrY   )ra   NNN)__name__
__module____qualname____doc__rR   rg   protocolr   r   propertyr   classmethodr3   r:   r<   r>   r   r[   rM   staticmethodr`   rl   rs   rq   ru   __classcell__r   r   r&   r(   r      s@    





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

3
6r   )
rh   rw   r   specr   utilsr   Zmemoryr   r   r   r   r   r(   <module>   s    