o
    iy0                  
   @   s  U d Z ddlmZ ddlZddlZddlmZ ddlmZ ddl	m
Z
mZmZmZmZ ddlmZ er9ddlmZ eeej Z	 G d	d
 d
eZdedefddZdefddZdaedB ed< defddZ deeef fddZ!d.ddZ"dej#fdeej$B dede%de&e fddZ'd/dede&e fddZ(	 	!d0d"ed#ed$edd%fd&d'Z)d1d"ed$ededB fd(d)Z*d/dede&e fd*d+Z+d/dede&e fd,d-Z,dS )2a  Management of pydicom's data files.


External Data Sources
---------------------

*pydicom* can also search third-party data sources for matching data. To do so
your project should register its entry points in its `setup.py` file. For
example, a project named "mydata" with the interface class ``MyInterface``
should register:

.. codeblock: python

    from setuptools import setup

    setup(
        ...,
        entry_points={
            "pydicom.data.external_sources": "mydata = mydata:MyInterface",
        },
    )

The interface class should have, at a minimum, the following two methods:

* ``get_path(self, name: str, dtype: int) -> str`` - returns the absolute path
  to the first file with a filename `name` or raises a ``ValueError`` if no
  matching file found.
* ``get_paths(self, pattern: str, dtype: int) -> List[str]`` - returns a list
  of absolute paths to filenames matching `pattern`.

Where `name` is the name of the filename to search for, `dtype` is an int
that indicates the type of data to search for and should be one of the
following:

* ``0`` - DICOM dataset
* ``1`` - Character set file
* ``2`` - Palette file
* ``3`` - DICOMDIR file
* ``4`` - JPEG file

And lastly, `pattern` is a str used to filter files against when searching.

For a real-life example of an external data source you can look at the
`pydicom-data <https://github.com/pydicom/pydicom-data>`_ repository.
    )IntEnumN)Path)TYPE_CHECKING)data_path_with_downloadcalculate_file_hashget_cached_filehashget_url_mapget_data_dir)warn_and_log)Datasetc                   @   s$   e Zd ZdZdZdZdZdZdZdS )	DataTypeszConstants for data types.r               N)	__name__
__module____qualname____doc__DATASETCHARSETPALETTEDICOMDIRJPEG r   r   O/mnt/sdb/aimis/docanh/lib/python3.10/site-packages/pydicom/data/data_manager.pyr   G   s    r   fpathreturnc                 C   s"   t | }t|}t|j}||kS )a  Return ``True`` if the SHA256 checksum of the file at ``fpath`` is OK.

    Parameters
    ----------
    fpath : str
        The absolute path to the file to perform the checksum for.

    Returns
    -------
    bool
        ``True`` if the checksum matches those in ``hashes.json``, ``False``
        otherwise.

    Raises
    ------
    pydicom.data.download.NoHashFound
        If the file is missing from ``hashes.json``.
    )r   r   r   name)r   pext_hashref_hashr   r   r   _check_data_hashQ   s   
r"   c                  C   sF   ddl m}  dd | ddD }i }d|v r|d |d< || |S )zReturn a :class:`dict` of external data source interfaces.

    Returns
    -------
    dict
        A dict of ``{'source name': <interface class instance>}``.
    r   )entry_pointsc                 S   s   i | ]	}|j |  qS r   )r   load).0vvr   r   r   
<dictcomp>w       z(get_external_sources.<locals>.<dictcomp>zpydicom.data.external_sources)grouppydicom-data)importlib.metadatar#   update)r#   sourcesoutr   r   r   get_external_sourcesk   s   	
r/   _EXTERNAL_DATA_SOURCESc                   C   s   t du rt a t S )z9Return the available external data sources - loaded once.N)r0   r/   r   r   r   r   external_data_sources   s   r1   c                     s2   t t  } tjtd  fdd| D }|S )zReturn a :class:`dict` of dummy paths to the downloadable test files.

    Returns
    -------
    dict
        A dict of dummy paths to the test files available via download.
    
test_filesc                    s   i | ]
}t j ||qS r   )ospathjoinr%   filenametest_files_rootr   r   r'      s    z0online_test_file_dummy_paths.<locals>.<dictcomp>)listr   keysr3   r4   r5   	DATA_ROOT)	filenamesdummy_path_mapr   r8   r   online_test_file_dummy_paths   s   
r?   c               	      sx   t    fddtt  D } g }| D ]}zt|j W q ty-   ||j Y qw |r:tdd	| dS )z/Download missing test files to the local cache.c                    s   i | ]} | |qS r   r   )r%   fnamecacher   r   r'          z$fetch_data_files.<locals>.<dictcomp>z3An error occurred downloading the following files: z, N)
r	   r:   r   r;   r   r   	ExceptionappendRuntimeErrorr5   )pathserrorr   r   rA   r   fetch_data_files   s   rI   **/*basepatterndtypec              	      s   t | } dd | |D }t  D ]\}}|||}|dkr(dd |D }|| qt  t 	 t
j| |} fdd|D }g }	d}
|D ]}z|	t
t| W qM tyf   d}
Y qMw ||	7 }|
rqtd |S )	a  Return all matching file paths from the available data sources.

    First searches the local *pydicom* data store, then any locally available
    external sources, and finally the files available in the
    pydicom/pydicom-data repository.

    .. versionchanged: 2.1

        Added the `dtype` keyword parameter, modified to search locally
        available external data sources and the pydicom/pydicom-data repository

    Parameters
    ----------
    base : str or os.PathLike
        Base directory to recursively search.
    pattern : str, optional
        The pattern to pass to :meth:`~pathlib.Path.glob`, default
        (``'**/*'``).
    dtype : int, optional
        The type of data to search for when using an external source, one of:

        * ``0`` - DICOM dataset
        * ``1`` - Character set file
        * ``2`` - Palette file
        * ``3`` - DICOMDIR file
        * ``4`` - JPEG file

    Returns
    -------
    list of str
        A list of absolute paths to matching files.
    c                 S   s   g | ]}t |qS r   r3   fspathr%   mr   r   r   
<listcomp>   rC   zget_files.<locals>.<listcomp>r*   c                 S   s   g | ]}t |r|qS r   )r"   )r%   r   r   r   r   rR      s    c                    s   g | ]	}t  | qS r   rN   )r%   
dummy_pathdummy_online_file_path_mapr   r   rR      r(   FTzYOne or more download failures occurred, the list of matching file paths may be incomplete)r   globr1   items	get_pathsextendr?   fnmatchfilterr;   r3   r4   r5   rE   rO   r   rD   r
   )rK   rL   rM   fileslibsourcefpathsdummy_online_file_path_filtereddownload_namesreal_online_file_pathsdownload_errorr7   r   rT   r   	get_files   s8   #
rd   c                 C   .   t td }t|| tjd}dd |D }|S )aH  Return a list of absolute paths to palettes with filenames matching
    `pattern`.

    Parameters
    ----------
    pattern : str, optional
        The pattern to pass to :meth:`~pathlib.Path.glob`, default
        (``'**/*'``).

    Returns
    -------
    list of str
        A list of absolute paths to matching files.
    palettesrK   rL   rM   c                 S      g | ]	}| d s|qS z.pyendswithr6   r   r   r   rR         z%get_palette_files.<locals>.<listcomp>)r   r<   rd   r   r   rL   	data_pathr\   r   r   r   get_palette_files     ro   FTr   readdownloadzstr | Dataset | Nonec                 C   sP   t j| rtd|  dt| |d}|r&|dur&ddlm} ||ddS |S )	a  Return an absolute path to the first matching dataset with filename
    `name` that is found in a local or external pydicom datastore.

    First searches the local *pydicom* data store, then any locally available
    external sources, and finally the files available in the
    pydicom/pydicom-data repository.

    .. versionchanged:: 2.1

        Modified to search locally available external data sources and the
        pydicom/pydicom-data repository

    .. versionchanged:: 2.2

        Added the `read` keyword parameter.

    .. versionchanged:: 2.3

        Added the `download` keyword parameter.

    Parameters
    ----------
    name : str
        The full file name (without path)
    read : bool, optional
        If ``True`` then use :func:`~pydicom.filereader.dcmread` to read the
        file and return the corresponding
        :class:`~pydicom.dataset.FileDataset`. Default ``False``.
    download : bool, optional
        If ``True`` (default) download the file if missed locally.

    Returns
    -------
    str, pydicom.dataset.Dataset or None
        The absolute path of the file if found, the dataset itself if `read` is
        ``True``, or ``None`` if the file is not found.

    Raises
    ______
    ValueError
        If `name` is an absolute path.
    z'get_testdata_file' does not support absolute paths, as it only works with internal pydicom test data - did you mean 'dcmread("z")'?)r   rr   Nr   )dcmreadT)force)r3   r4   isabs
ValueError_get_testdata_filepydicom.filereaderrs   )r   rq   rr   r4   rs   r   r   r   get_testdata_file  s   /ry   c              	   C   s   t td }dd || D }|rt|d S t  D ]/\}}z
|j| tj	d}W n t
y7   d }Y nw |dkrG|rFt|rF|  S q|rM|  S q|rwt  D ]!}|| kr\qUz
tt|W   S  tyv   td|   Y qUw d S )Nr2   c                 S   s   g | ]}|qS r   r   rP   r   r   r   rR   \  s    z&_get_testdata_file.<locals>.<listcomp>r   )rM   r*   z9A download failure occurred while attempting to retrieve )r   r<   rglobr3   rO   r1   rW   get_pathr   r   rv   r"   r   r;   r   rD   r
   )r   rr   rn   matchesr]   r^   r   r7   r   r   r   rw   Y  s>   rw   c                 C   sB   t j| r
tdttd }t|| tjd}dd |D }|S )a  Return a list of absolute paths to datasets with filenames matching
    `pattern`.

    Parameters
    ----------
    pattern : str, optional
        The pattern to pass to :meth:`~pathlib.Path.glob`, default
        (``'**/*'``).

    Returns
    -------
    list of str
        A list of absolute paths to matching files.

    Raises
    ______
    ValueError
        If `pattern` matches an absolute path.
    zg'get_testdata_files' does not support absolute paths, as it only works with internal pydicom test data.r2   rg   c                 S   rh   ri   rj   r6   r   r   r   rR     rl   z&get_testdata_files.<locals>.<listcomp>)	r3   r4   ru   rv   r   r<   rd   r   r   rm   r   r   r   get_testdata_files  s   r}   c                 C   re   )aK  Return a list of absolute paths to charsets with filenames matching
    `pattern`.

    Parameters
    ----------
    pattern : str, optional
        The pattern to pass to :meth:`~pathlib.Path.glob`, default
        (``'**/*'``).

    Returns
    ----------
    list of str
        A list of absolute paths to matching files.
    charset_filesrg   c                 S   rh   ri   rj   r6   r   r   r   rR     rl   z%get_charset_files.<locals>.<listcomp>)r   r<   rd   r   r   rm   r   r   r   get_charset_files  rp   r   )r   N)rJ   )FT)T)-r   enumr   rZ   r3   pathlibr   typingr   pydicom.data.downloadr   r   r   r   r	   pydicom.miscr
   pydicomr   rO   __file__parentresolver<   r   strboolr"   dictr/   r0   __annotations__r1   r?   rI   r   PathLikeintr:   rd   ro   ry   rw   r}   r   r   r   r   r   <module>   sX   .


P
=&!