o
    i(                     @   s   d dl Z d dlZd dlZd dlmZmZ d dlmZ d dlm	Z	m
Z
 d dlZd dlmZ dd ZG dd	 d	ed
ZG dd deZG dd deZG dd deZi ZG dd deZdS )    N)ABCMetaabstractmethod)Path)	GeneratorUnion)urlparsec                 C   s   t | }d }|jd urOt|jdkrOt }|| }t j}tj	
|s*t| tj	|tj	| }t|d}|| W d    n1 sJw   Y  |d usZJ d|  |S )Nr   wbzfailed to download: )r   schemelenHTTPStoragereadtempfileTemporaryDirectorynameospathexistsmakedirsjoinbasenameopenwrite)urlresult	file_pathstoragedatawork_dirfb r   H/home/ubuntu/.local/lib/python3.10/site-packages/funasr/download/file.pydownload_from_url   s   


r!   c                
   @   s~   e Zd ZdZedefddZedefddZedede	ee
f dd	fd
dZeddede	ee
f dedd	fddZd	S )StoragezAbstract class of storage.

    All backends need to implement two apis: ``read()`` and ``read_text()``.
    ``read()`` reads the file as a byte stream and ``read_text()`` reads
    the file as texts.
    filepathc                 C      d S Nr   selfr#   r   r   r    r   '      zStorage.readc                 C   r$   r%   r   r&   r   r   r    	read_text+   r(   zStorage.read_textobjreturnNc                 C   r$   r%   r   r'   r*   r#   r   r   r    r   /   r(   zStorage.writeutf-8encodingc                 C   r$   r%   r   r'   r*   r#   r.   r   r   r    
write_text3   r(   zStorage.write_textr-   )__name__
__module____qualname____doc__r   strr   r)   bytesr   r   r   r0   r   r   r   r    r"      s     *r"   )	metaclassc                	   @   s   e Zd ZdZdeeef defddZddeeef dedefdd	Z	d
edeeef ddfddZ
dd
edeeef deddfddZejdeeef deeeef ddf fddZdS )LocalStoragezLocal hard disk storager#   r+   c                 C   s8   t |d}| }W d   |S 1 sw   Y  |S )Read data from a given ``filepath`` with 'rb' mode.

        Args:
            filepath (str or Path): Path to read data.

        Returns:
            bytes: Expected bytes object.
        rbNr   r   )r'   r#   fcontentr   r   r    r   ;   s   	

zLocalStorage.readr-   r.   c                 C   s<   t |d|d}| }W d   |S 1 sw   Y  |S )>  Read data from a given ``filepath`` with 'r' mode.

        Args:
            filepath (str or Path): Path to read data.
            encoding (str): The encoding format used to open the ``filepath``.
                Default: 'utf-8'.

        Returns:
            str: Expected text reading from ``filepath``.
        rr.   Nr<   )r'   r#   r.   r=   	value_bufr   r   r    r)   H   s   

zLocalStorage.read_textr*   Nc                 C   sd   t j|}|rt j|st j|dd t|d}|| W d   dS 1 s+w   Y  dS ))  Write data to a given ``filepath`` with 'wb' mode.

        Note:
            ``write`` will create a directory if the directory of ``filepath``
            does not exist.

        Args:
            obj (bytes): Data to be written.
            filepath (str or Path): Path to write data.
        Texist_okr   Nr   r   dirnamer   r   r   r   )r'   r*   r#   rG   r=   r   r   r    r   W   s   "zLocalStorage.writec                 C   sh   t j|}|rt j|st j|dd t|d|d}|| W d   dS 1 s-w   Y  dS )  Write data to a given ``filepath`` with 'w' mode.

        Note:
            ``write_text`` will create a directory if the directory of
            ``filepath`` does not exist.

        Args:
            obj (str): Data to be written.
            filepath (str or Path): Path to write data.
            encoding (str): The encoding format used to open the ``filepath``.
                Default: 'utf-8'.
        TrD   wrA   NrF   )r'   r*   r#   r.   rG   r=   r   r   r    r0   i   s   "zLocalStorage.write_textc                 c   s    |V  dS z$Only for unified API and do nothing.Nr   r&   r   r   r    as_local_path}   s   
zLocalStorage.as_local_pathr1   )r2   r3   r4   r5   r   r6   r   r7   r   r)   r   r0   
contextlibcontextmanagerr   rK   r   r   r   r    r9   8   s     $2r9   c                	   @   s   e Zd ZdZdd Zdd Zejdede	e
eef ddf fd	d
Zdede
eef ddfddZddede
eef deddfddZdS )r   zHTTP and HTTPS storage.c                 C      t |}|  |jS r%   )requestsgetraise_for_statusr>   r'   r   r@   r   r   r    r      s   
zHTTPStorage.readc                 C   rN   r%   )rO   rP   rQ   textrR   r   r   r    r)      s   
zHTTPStorage.read_textr#   r+   Nc              	   c   P    zt jdd}|| | |  |jV  W t|j dS t|j w )ah  Download a file from ``filepath``.

        ``as_local_path`` is decorated by :meth:`contextlib.contextmanager`. It
        can be called with ``with`` statement, and when exists from the
        ``with`` statement, the temporary path will be released.

        Args:
            filepath (str): Download a file from ``filepath``.

        Examples:
            >>> storage = HTTPStorage()
            >>> # After existing from the ``with`` clause,
            >>> # the path will be removed
            >>> with storage.get_local_path('http://path/to/file') as path:
            ...     # do something here
        FdeleteNr   NamedTemporaryFiler   r   closer   r   remover'   r#   r=   r   r   r    rK         
zHTTPStorage.as_local_pathr*   r   c                 C      t d)Nz&write is not supported by HTTP StorageNotImplementedError)r'   r*   r   r   r   r    r         zHTTPStorage.writer-   r.   c                 C   r]   )Nz+write_text is not supported by HTTP Storager^   )r'   r*   r   r.   r   r   r    r0      r`   zHTTPStorage.write_textr1   )r2   r3   r4   r5   r   r)   rL   rM   r6   r   r   r   rK   r7   r   r0   r   r   r   r    r      s    &(r   c                	   @   s   e Zd ZdZdddZdd Zddd	Zejd
e	de
ee	ef ddf fddZded
ee	ef ddfddZdde	d
ee	ef de	ddfddZdS )
OSSStoragezOSS storage.Nc                 C   r]   )Nz3OSSStorage.__init__ to be implemented in the futurer^   )r'   oss_config_filer   r   r    __init__   s   zOSSStorage.__init__c                 C   r]   )Nz/OSSStorage.read to be implemented in the futurer^   r&   r   r   r    r      r`   zOSSStorage.readr-   c                 C   r]   )Nz4OSSStorage.read_text to be implemented in the futurer^   )r'   r#   r.   r   r   r    r)      r`   zOSSStorage.read_textr#   r+   c              	   c   rT   )ag  Download a file from ``filepath``.

        ``as_local_path`` is decorated by :meth:`contextlib.contextmanager`. It
        can be called with ``with`` statement, and when exists from the
        ``with`` statement, the temporary path will be released.

        Args:
            filepath (str): Download a file from ``filepath``.

        Examples:
            >>> storage = OSSStorage()
            >>> # After existing from the ``with`` clause,
            >>> # the path will be removed
            >>> with storage.get_local_path('http://path/to/file') as path:
            ...     # do something here
        FrU   NrW   r[   r   r   r    rK      r\   zOSSStorage.as_local_pathr*   c                 C   r]   )Nz0OSSStorage.write to be implemented in the futurer^   r,   r   r   r    r      r`   zOSSStorage.writer.   c                 C   r]   )Nz5OSSStorage.write_text to be implemented in the futurer^   r/   r   r   r    r0      r`   zOSSStorage.write_textr%   r1   )r2   r3   r4   r5   rc   r   r)   rL   rM   r6   r   r   r   rK   r7   r   r0   r   r   r   r    ra      s    

&(ra   c                
   @   s   e Zd ZU eeeedZeed< e	dd Z
e	dedefddZe	ddeeef d
edefddZe	dedeeef ddfddZe	ddeded
eddfddZejdedeeeef ddf fddZdS )File)osshttphttpslocal_prefix_to_storagec                 C   s   t | tsJ dt|  d| vrd}n	| d\}}|}|tjv s2J d|  dttj  |tvr>tj|  t|< t| S )Nz uri should be str type, but got z://rh   zUnsupported uri z, valid prefixs: )	
isinstancer6   typesplitrd   ri   listkeys
G_STORAGES)uristorage_typeprefix_r   r   r    _get_storage   s   zFile._get_storagerp   r+   c                 C   s   t | }|| S )r:   )rd   rt   r   )rp   r   r   r   r    r      s   


z	File.readr-   r.   c                 C   s   t | }|| S )r?   )rd   rt   r)   )rp   r.   r   r   r   r    r)     s   

zFile.read_textr*   Nc                 C   s   t |}|| |S )rC   )rd   rt   r   )r*   rp   r   r   r   r    r     s   
z
File.writec                 C   s   t |}|| |S )rH   )rd   rt   r0   )r*   rp   r.   r   r   r   r    r0   *  s   
zFile.write_textc                 c   sB    t | }|| }|V  W d   dS 1 sw   Y  dS rJ   )rd   rt   rK   )rp   r   
local_pathr   r   r    rK   ;  s
   
"zFile.as_local_pathr1   )r2   r3   r4   ra   r   r9   ri   dict__annotations__staticmethodrt   r6   r7   r   r   r   r)   r   r0   rL   rM   r   rK   r   r   r   r    rd      s$   
 
" *rd   )rL   r   r   abcr   r   pathlibr   typingr   r   rO   urllib.parser   r!   r"   r9   r   ra   ro   objectrd   r   r   r   r    <module>   s   K/.