a
    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}Zgithub)<   r	   Nc                    s   t  jf i | || _|| _|d u |d u A r6td|| _|| _|d urP|| _|d u rd}tj	|j
||dfd| ji| j}	|	  |	 d }|| _| d z ddlm}
 |
f i || _W n ty   d | _Y n0 d S )	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__ K/var/www/auris/lib/python3.9/site-packages/fsspec/implementations/github.pyr   ,   s6    
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/ZusersZorgs/z/repos)r   c                 S   s   g | ]}|d  qS namer'   ).0r   r'   r'   r(   
<listcomp>f       z*GithubFileSystem.repos.<locals>.<listcomp>)r   r   r   r   r   )clsZorg_or_userZis_orgr$   r'   r'   r(   reposP   s    zGithubFileSystem.reposc                 C   sF   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   s   g | ]}|d  qS r,   r'   r.   tr'   r'   r(   r/   q   r0   z)GithubFileSystem.tags.<locals>.<listcomp>r   r   r   r   r   r   r   r   r    r$   r'   r'   r(   tagsh   s    zGithubFileSystem.tagsc                 C   sF   t jd| j d| j dfd| ji| j}|  dd | D S )zNames of branches in the repor3   r+   z	/branchesr   c                 S   s   g | ]}|d  qS r,   r'   r4   r'   r'   r(   r/   |   r0   z-GithubFileSystem.branches.<locals>.<listcomp>r6   r7   r'   r'   r(   branchess   s    zGithubFileSystem.branchesc                 C   s   | j | jdS )z#Named references, tags and branchesr8   r9   r:   r*   r'   r'   r(   refs~   s    zGithubFileSystem.refsFc           
         s  |     dkr|p| j}|du r dd}d|p@| j}|D ]z}| jd||d}rjd| n|7 fdd|D }|st |d }|d	 d
kr|r|g  S    S |d }qF | jvs|| jdfvrftj| j	j
| j| j|dfd| ji| j}	|	jdkrt |	  d
dd fdd|	 d D }|| jdfv rp|| j < n
| j  }|rz|S tdd |D S 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(   r/      r0   z'GithubFileSystem.ls.<locals>.<listcomp>r   typefiler!   )r   r   r!   r     	directory)Zblobtreec              	      sX   g | ]P}|d  v r r( d |d  n|d |d |d   | dd|d dqS )r?   r+   pathmodesizer   r!   )r-   rE   r?   rF   r!   )r   r.   f)rD   typesr'   r(   r/      s   

rC   c                 S   s   g | ]}|d  qS r,   r'   rG   r'   r'   r(   r/      r0   )_strip_protocolr   rstripsplitr   FileNotFoundErrordircacher   r   urlr   r   r   r   r   status_coder   r   sorted)
r    rD   Zdetailr!   r<   r"   partspartoutr$   r'   )rD   r>   rI   r(   r      sP    







zGithubFileSystem.lsc                 C   s   | j   d S )N)rN   clear)r    rD   r'   r'   r(   invalidate_cache   s    z!GithubFileSystem.invalidate_cachec                    s*   t |}d|vrt |S |d dS )Nr   rD   r+   )r   r   rJ   lstrip)r1   rD   optsr%   r'   r(   rJ      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   )rD   rX   rT   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rVt||  | }	|	d rt|	d }
|
dstd d |
S | jd u rtd| jj|	d f|||d	|S )
Nr\   r   r   rD   r!   r   rA   contents#   version https://git-lfs.github.com/zRPlease install fsspec[http] to access github files >1 MB or git-lfs tracked files.download_url)rE   
block_sizecache_options)NotImplementedErrorcontent_urlr   r   r   r   r   r   r   r   rP   rM   r   r   base64	b64decode
startswithr   r   r   open)r    rD   rE   r`   ra   r!   r"   rO   r$   Zcontent_jsonr^   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    rD   ri   rj   rk   pr'   r'   r(   rm  s    zGithubFileSystem.rmc                 K   s&  | j std| |}| |}|s| jj| j| j|d| j	d}t
j|fd| ji| j}|jdkrrt||  | d }| jj| j| j|| j	d}| j	}|pd| |d|rd	|ini }	t
j|f|	| jd
| j}| dd}
td|
rd}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+   r]   r   rA   r!   zDelete )rk   r!   branch)r   r   rk   r   zBranch .+ not foundzTRemove only works when the filesystem is initialised from a branch or default (None)N)r   r   rJ   _get_sha_from_cacherc   r   r   r   rW   r   r   r   r   r   rP   rM   r   r   deleteresearchrV   )r    rD   rk   r"   r!   rO   r$   Z
delete_urlrp   dataerror_messageerrorr'   r'   r(   rm     s:    


zGithubFileSystem.rm_filec                 C   sL   | j  D ]<}|D ]2}|d}|r||krd|v r|d     S qq
d S )Nr-   r!   )rN   valuesr   )r    rD   entriesentry
entry_pathr'   r'   r(   rq   G  s    
z$GithubFileSystem._get_sha_from_cache)NNNN)T)FNN)N)r\   NNN)FNN)N)__name__
__module____qualname____doc__rO   rc   protocolr   r   propertyr   classmethodr2   r8   r9   r;   r   rV   rJ   staticmethodr[   rh   ro   rm   rq   __classcell__r'   r'   r%   r(   r      s>    






B

    
3

6r   )
rd   rs   r   specr   utilsr   Zmemoryr   r   r'   r'   r'   r(   <module>   s   