o
    8wiE                  
   @   s$  d dl mZ d dlZd dlmZ d dlmZmZmZm	Z	m
Z
mZmZmZ d dlZd dlmZmZ ddlmZmZ ddlmZ d dlZG d	d
 d
eZG dd dZdee fddZdee fddZdeee
e
f ef deee
e
f ef dededef
ddZe Ze D ]Ze e qdS )    )EnumN)Path)DictListSetOptionalTextTupleTypeUnion)PreprocessorsProtocol   )create_protocolget_init)Databasec                   @   s   e Zd ZdZdZdZdS )LoadingModer   r      N)__name__
__module____qualname__OVERRIDEKEEPERROR r   r   W/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/pyannote/database/registry.pyr   ,   s    r   c                   @   s   e Zd ZdZdddZejfdeee	f defdd	Z
eje fd
eee	f dedee	 fddZdefddZ	ddee defddZdd Zdejfded
eee	f defddZdd ZdS )RegistryzDatabase and experimental protocols registry

    Usage
    -----
    >>> from pyannote.database import registry
    >>> registry.load_database("/path/to/first/database.yml")
    >>> registry.load_database("/path/to/second/database.yml")
    returnNc                 C   s   t  | _t  | _t  | _d S N)dictconfigssources	databases)selfr   r   r   __init__q   s   !zRegistry.__init__pathmodec                 C   s   | j ||t d |   dS )a  Load YAML configuration file into the registry

        Parameters
        ----------
        path : str or Path
            Path to YAML configuration file.
        mode : LoadingMode, optional
            Controls how to handle conflicts in protocol names.
            Defaults to overriding the existing protocol.

        Usage
        -----
        >>> from pyannote.database import registry
        >>> registry.load_database("/path/to/database.yml")
        r&   loadingN)_load_database_helperset_reload_meta_protocols)r#   r%   r&   r   r   r   load_database   s   zRegistry.load_databasedatabase_ymlr(   c                 C   s  t |  }||v rdS || t|d}tj|tjd}W d   n1 s+w   Y  |dt	 }t
|t	s?|g}|D ]}t |}| sP|j| }| j|||d qA|dt }|dd}	|	durn|	|d< | D ]\}
}| j|
|||d qr|d	t }| D ]/\}
}t
|t	s|g}t	 }|D ]}t |}| s|j| }|t| q|| jt|
< q|| j|< dS )
aB  Helper function for recursive loading

        Parameters
        ----------
        database_yml : Union[Text, Path]
            Path to the database.yml
        mode : LoadingMode, optional
            Controls how to handle conflicts in protocol names.
            Defaults to overriding the existing protocol.
        Nr)LoaderRequirementsr'   	ProtocolsXr&   	Databases)r   
expanduserresolveaddopenyamlload
SafeLoaderpoplist
isinstanceis_absoluteparentr)   getr   items_load_protocolsappendstrr!   r    )r#   r-   r&   r(   fconfigrequirementsrequirement_yaml	protocolsxdb_name
db_entriesr"   value	path_listpr%   r   r   r   r)      sB   




zRegistry._load_database_helperc                 K   sX   z| j | }W n ty$   |dkrd}t|d}|j|d}t|w |di |S )zGet database by name

        Parameters
        ----------
        database_name : str
            Database name.

        Returns
        -------
        database : Database
            Database instance
        r2   zCould not find any meta-protocol. Please refer to pyannote.database documentation to learn how to define them: https://github.com/pyannote/pyannote-databasezCould not find any protocol for "{name}" database. Please refer to pyannote.database documentation to learn how to define them: https://github.com/pyannote/pyannote-database)nameNr   )r"   KeyErrorformat
ValueError)r#   database_namekwargsdatabasemsgr   r   r   get_database
  s   zRegistry.get_databasepreprocessorsc                 C   s4   | d\}}}| |}|j|||d}||_|S )a]  Get protocol by full name

        Parameters
        ----------
        name : str
            Protocol full name (e.g. "Etape.SpeakerDiarization.TV")
        preprocessors : dict or (key, preprocessor) iterable
            When provided, each protocol item (dictionary) are preprocessed, such
            that item[key] = preprocessor(item). In case 'preprocessor' is not
            callable, it should be a string containing placeholder for item keys
            (e.g. {'audio': '/path/to/{uri}.wav'})

        Returns
        -------
        protocol : Protocol
            Protocol instance
        .)rZ   )splitrY   get_protocolrQ   )r#   rQ   rZ   rU   	task_nameprotocol_namerW   protocolr   r   r   r]   -  s   
zRegistry.get_protocolc                 c   sP    | j D ]!}| |}| D ]}||D ]}| d| d| V  qqqd S )Nr[   )r"   rY   	get_tasksget_protocols)r#   rU   rW   r^   r_   r   r   r   __iter__K  s   

zRegistry.__iter__rM   c                 C   s   t |}t }| D ]$\}}| D ]\}}	t |}t||||	|}
|
du r(q|
|||f< qq|| jv rC| j| j}t||||| dd | D }t|tft	||d| j|< dS )a  Load all protocols from this database into the registry.

        Parameters
        ----------
        db_name : _type_
            Name of the database
        db_entries : dict
            Dict of all entries under this database (this should be tasks)
        database_yml : Union[Text, Path], optional
            Path to the database.yml file. Not required for X protocols, by default None
        Nc                 S   s   g | ]\\}}}|||fqS r   r   ).0taskp_namep_typer   r   r   
<listcomp>}  s    z,Registry._load_protocols.<locals>.<listcomp>)r$   
_protocols)
rE   r   rB   r   r"   ri   _merge_protocols_inplacetyper   r   )r#   rL   rM   r-   r&   rJ   r^   task_entriesr`   protocol_entriesCustomProtocolold_protocolsprotocol_listr   r   r   rC   R  s2   


zRegistry._load_protocolsc                 C   sT   | j dd | j D ]\}}|dt }d|v r'| jd|d |tjd qdS )z>Reloads all meta protocols from all database.yml files loaded.r2   Nr1   r3   )	r"   r<   r    rB   rA   r   rC   r   r   )r#   db_ymlrG   r"   r   r   r   r+     s   zRegistry._reload_meta_protocols)r   Nr   )r   r   r   __doc__r$   r   r   r   r   r   r,   r   r*   r   r)   r   rY   r   r   r   r]   rc   r   rC   r+   r   r   r   r   r   g   sH    
	;



I$


4r   r   c                  C   sD   t jdd} g }| dD ]}t| }| r|| q|S )zParse PYANNOTE_DATABASE_CONFIG environment variable

    PYANNOTE_DATABASE_CONFIG may contain multiple paths separation by ";".

    Returns
    -------
    paths : list of Path
        List of all YAML database file defined in PYANNOTE_DATABASE_CONF
    PYANNOTE_DATABASE_CONFIG ;)osenvironrA   r\   r   r5   is_filerD   )contentpathsr%   r   r   r   _env_config_paths  s   
r{   c                  C   sN   g } t d }| r| | t  d }| r | | | t 7 } | S )a  Get paths to default YAML configuration files

    * $HOME/.pyannote/database.yml
    * $CWD/database.yml
    * PYANNOTE_DATABASE_CONFIG environment variable

    Returns
    -------
    paths : list of Path
        List of existing default YAML configuration files
    z~/.pyannote/database.ymlzdatabase.yml)r   r5   rx   rD   cwdr{   )rz   home_db_yml
cwd_db_ymlr   r   r   _find_default_ymls  s   


r   new_protocolsro   r&   rL   r-   c           
      C   s   |  D ]R\}}|| v rR|\}}| d| d| }	|tjkr*td|	 d| d|tjkr<td|	 d| d q|tjkrQtd|	 d	| d || |< q|| |< qd
S )a  Merge new and old protocols inplace into the passed new_protocol.

    Warning, merging order might be counterintuitive : "KEEP" strategy keeps element from the OLD protocol
    and MODIFIES the new protocol.

    TODO: make it intuitive :)

    Parameters
    ----------
    new_protocols : Dict[Tuple[Text, Text], Type]
        New protocol dict
        Maps (task,protocol) tuples to custom protocol classes
    old_protocols : Dict[Tuple[Text, Text], Type]
        Old protocols dict
        Maps (task,protocol) tuples to custom protocol classes.
    mode : LoadingMode
        How to handle override
    db_name : _type_
        Name of the database (for logging/warning purposes)
    database_yml : str
        Path of the database.yml file (for logging/warning purposes)
    r[   zCannot load z protocol from 'z' as it already exists.zReplacing existing z! protocol by the one defined in 'z'.z	Skipping z protocol defined in 'N)rB   r   r   RuntimeErrorr   warningswarnr   )
r   ro   r&   rL   r-   p_idold_pt_namerf   realnamer   r   r   rj     s*   



rj   )!enumr   rv   pathlibr   typingr   r   r   r   r   r	   r
   r   r   #pyannote.database.protocol.protocolr   r   customr   r   rW   r   r9   r   r   r{   r   rE   rj   registryymlr,   r   r   r   r   <module>   s<   (;  0
?
