o
    
j q                  
   @   s   d dl Z d dlZd dlZd dlZd dlZd dlmZ d dlmZm	Z	 d dl
mZmZmZ d dlZd dlZd dlmZ d dlmZmZ d dlmZ dd	d	d	d
ddddd	ZG dd deZdS )    N)Path)copyfilermtree)DictListTuple)tqdm)load_configread_json_with_comments)get_user_data_dirz2https://creativecommons.org/licenses/by-nc-nd/4.0/z&https://www.mozilla.org/en-US/MPL/2.0/z(https://choosealicense.com/licenses/mit/z/https://choosealicense.com/licenses/apache-2.0/z/https://creativecommons.org/licenses/by-sa/4.0/zhttps://coqui.ai/cpml.txt)	zcc by-nc-nd 4.0mplmpl2zmpl 2.0mitz
apache 2.0apache2zcc-by-sa 4.0cpmlc                       s  e Zd ZdZ	 dG fdd	Zdd ZdHd	d
Zdd Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd ZedefddZded efd!d"Zded efd#d$Zd%d& Zedefd'd(Zd)d* Zed+d, Zed-d. Zd/d0 Zd1d2 Zd3d4 Zed ed5eeef fd6d7Zed ed5efd8d9Z d ed:ed5dfd;d<Z!ed=d> Z"ed?d@ Z#edAdB Z$edCdD Z%edEdF Z&  Z'S )IModelManagerNFTc                    sr   t    || _|| _|d u rtd| _ntj|d| _d | _	|d ur+| 
| d S ttjd }| 
| d S )Nttsz../.models.json)super__init__progress_barverboser   output_prefixospathjoinmodels_dictread_models_filer   __file__parent)selfmodels_filer   r   r   r   	__class__ C/home/kuhnn/.local/lib/python3.10/site-packages/TTS/utils/manage.pyr   .   s   
zModelManager.__init__c                 C   s   t || _dS )zfRead .models.json as a dict

        Args:
            file_path (str): path to .models.json.
        N)r
   r   )r   	file_pathr#   r#   r$   r   >   s   zModelManager.read_models_filer   c           	      C   s  | j rtd g }| j| D ]r}| j| | D ]h}| j| | | D ]\}| d| d| d| }tj| j|}| j rjtj|rWtd| d| d| d| d| d ntd| d| d| d| d| 
 || d| d| d|  |d7 }q"qq|S )Nz*
 Name format: type/language/dataset/model-- z: /z [already downloaded]   )	r   printr   r   r   r   r   existsappend)	r   
model_typemodel_count
model_listlangdatasetmodelmodel_full_nameoutput_pathr#   r#   r$   _list_modelsF   s"   *& 
zModelManager._list_modelsc                 C   s   g }d}| | || |S Nr)   )extendr5   )r   r-   models_name_listr.   r#   r#   r$   _list_for_model_typeX   s   z!ModelManager._list_for_model_typec                 C   s.   g }d}| j D ]}| ||}|| q|S r6   )r   r5   r7   )r   r8   r.   r-   r/   r#   r#   r$   list_models^   s   
zModelManager.list_modelsc           	      C   s  g }| d\}}zt|}|dkrtd W dS W n
   td Y dS d}|| jv r_| j| D ],}| j| | D ]"}| j| | | D ]}|| d| d| d|  |d7 }qEq:q1n
td| d dS ||krwtd	| d
 dS ||d   d\}}}}td|  td|  td|  td|  d| j| | | | v rtd| j| | | | d   ntd d| j| | | | v rtd| j| | | | d   dS dS )zPrint the description of the model from .models.json file using model_idx

        Args:
            model_query (str): <model_tye>/<model_idx>
        r(   r   z/> model_query_idx should be a positive integer!Nz'> model_query_idx should be an integer!r)   > model_type  does not exist in the list.z8model query idx exceeds the number of available models [z] > model type : > language supported : > dataset used : > model name : description> description : > description : coming soondefault_vocoder> default_vocoder : )splitintr*   r   r,   )	r   model_querymodel_name_listr-   model_query_idxr.   r0   r1   r2   r#   r#   r$   model_info_by_idxf   sH   
 
&(zModelManager.model_info_by_idxc              
   C   s  | d\}}}}|| jv r|| j| v r|| j| | v r|| j| | | v rtd|  td|  td|  td|  d| j| | | | v retd| j| | | | d   ntd d	| j| | | | v rtd
| j| | | | d	   dS dS td| d| d| d| d	 dS td| d| d| d dS td| d| d dS td| d dS )zPrint the description of the model from .models.json file using model_full_name

        Args:
            model_query_name (str): Format is <model_type>/<language>/<dataset>/<model_name>
        r(   r=   r>   r?   r@   rA   rB   rC   rD   rE   z> model z does not exist for .z
> dataset z> lang r;   r<   N)rF   r   r*   )r   model_query_namer-   r0   r1   r2   r#   r#   r$   model_info_by_full_name   s.   
& z$ModelManager.model_info_by_full_namec                 C   
   |  dS )zlPrint all `TTS` models and return a list of model names

        Format is `language/dataset/model`
        
tts_modelsr9   r   r#   r#   r$   list_tts_models      
zModelManager.list_tts_modelsc                 C   rO   )ztPrint all the `vocoder` models and return a list of model names

        Format is `language/dataset/model`
        vocoder_modelsrQ   rR   r#   r#   r$   list_vocoder_models   rT   z ModelManager.list_vocoder_modelsc                 C   rO   )z{Print all the voice conversion models and return a list of model names

        Format is `language/dataset/model`
        voice_conversion_modelsrQ   rR   r#   r#   r$   list_vc_models   rT   zModelManager.list_vc_modelsc                 C   s>   t d | jD ]}| j| D ]}t d| d| d qqdS )z!Print all the available languagesz Name format: type/language >: r(   r'   Nr*   r   )r   r-   r0   r#   r#   r$   
list_langs   s   
zModelManager.list_langsc              
   C   sV   t d | jD ]!}| j| D ]}| j| | D ]}t d| d| d|  qqqdS )zPrint all the datasetsz# Name format: type/language/datasetrY   r(   NrZ   )r   r-   r0   r1   r#   r#   r$   list_datasets   s   
zModelManager.list_datasets
model_itemc                 C   sr   d| v r3| d   dkr3td| d   | d  tv r-tdt| d    d dS td dS td dS )	zqPrint the license of a model

        Args:
            model_item (dict): model item in the models.json
        license z > Model's license - z	 > Check z for more info.z7 > Check https://opensource.org/licenses for more info.z5 > Model's license - No license information availableN)stripr*   lowerLICENSE_URLSr]   r#   r#   r$   print_model_license   s    z ModelManager.print_model_licenser4   c                 C   >   t |d tr| |d || j d S | |d || j d S )Ngithub_rls_url
isinstancelist_download_model_filesr   _download_zip_filer   r]   r4   r#   r#   r$   _download_github_model      z#ModelManager._download_github_modelc                 C   re   )Nhf_urlrg   rl   r#   r#   r$   _download_hf_model   rn   zModelManager._download_hf_modelc                 C   s>   d}| d\}}}}tj|| d}| ||| j d S )N'https://coqui.gateway.scarf.sh/fairseq/r(   z.tar.gz)rF   r   r   r   _download_tar_filer   )r   
model_namer4   
URI_PREFIX_r0   model_download_urir#   r#   r$   download_fairseq_model   s   z#ModelManager.download_fairseq_modelc                 C   sh   d | d< d| v r| d | d< | S d| v r| d | d< | S d| d v r(d| d< | S d| d v r2d| d< | S )	N	model_urlrf   ro   fairseqrs   rq   xttsz$https://coqui.gateway.scarf.sh/xtts/r#   rc   r#   r#   r$   set_model_url   s   zModelManager.set_model_urlc                 C   s:  d|v rd}| dd }ddd ddd}||d< nad	|v rct| dd
krcd}t||r7| dd }nd}d}d}d}|}d dddd| dd| dd| dd| dd| dgd}n| d\}}}}| j| | | | }||d< | d| d| d| }	d|v r|d nd }
| |}||	||
fS )Nry   rP   r(   r)   zCC BY-NC 4.0zthis model is released by Meta under Fairseq repo. Visit https://github.com/facebookresearch/fairseq/tree/main/examples/mms for more info.)r-   r^   rD   authorrA   rs   rz      zv\d+\.\d+\.\d+ru   mainmultilingualzmulti-datasetCPMLzinfo@coqui.aiTz0https://coqui.gateway.scarf.sh/hf-coqui/XTTS-v2/z
/model.pthz/config.jsonz/vocab.jsonz	/hash.md5z/speakers_xtts.pth)rD   r^   contacttos_requiredro   r-   r&   
model_hash)rF   lenresearchr   r{   )r   rs   r-   r0   r]   version_regexmodel_versionr1   r2   r3   md5hashr#   r#   r$   _set_model_item  sJ   






zModelManager._set_model_itemc                 C   s|   t j| d}td td td td}| dkr<t|ddd	}|d
 W d   dS 1 s5w   Y  dS dS )z-Ask the user to agree to the terms of servicetos_agreed.txtz" > You must confirm the following:zK | > "I have purchased a commercial license from Coqui: licensing@coqui.ai"z` | > "Otherwise, I agree to the terms of the non-commercial CPML: https://coqui.ai/cpml" - [y/n]z | | > ywutf-8encodingz?I have read, understood and agreed to the Terms and Conditions.NTF)r   r   r   r*   inputra   openwrite)model_full_pathtos_pathanswerfr#   r#   r$   ask_tos5  s   
zModelManager.ask_tosc                 C   sF   d| v r!| d r!t j|d}t j|st jddkrdS dS dS )z4Check if the user has agreed to the terms of servicer   r   COQUI_TOS_AGREED1TF)r   r   r   r+   environget)r]   r   r   r#   r#   r$   
tos_agreedC  s   zModelManager.tos_agreedc              
   C   s   t j|dd | ||s| |st | tdtd|  z"d|v r.| || nd|v r9| || n
d|v rC| 	|| W n t
jy^ } ztd|  t| |d }~ww | j|d	 d S )
NT)exist_okz> [!] You must agree to the terms of service to use this model.z > Downloading model to ry   rf   ro   z( > Failed to download the model file to rc   )r   makedirsr   r   rmdir	Exceptionr*   rw   rm   rp   requestsRequestExceptionr   rd   )r   rs   r]   r4   er#   r#   r$   create_dir_and_download_modelM  s*   

z*ModelManager.create_dir_and_download_modelc           	      C   s   t j| |d ddd}t|}W d    n1 sw   Y  d }|d D ]
}d|v r2|} nq(t j|ddd}t|}W d    n1 sKw   Y  ||ksetd| d | ||| d S d S )	Nr)   rr   r   ro   config.json > zG is already downloaded however it has been changed. Redownloading it...)fsspecr   _find_filesjsonloadr*   r   )	r   rs   r]   r4   r   config_local
remote_urlurlconfig_remoter#   r#   r$   check_if_configs_are_equalc  s    z'ModelManager.check_if_configs_are_equalc                 C   sb  |  |\}}}}tj| j|}tj|r|durltj|d}tj|r]t|dd&}| |ksEt	d| d | 
||| nt	d| d W d   n1 sWw   Y  nt	d| d | 
||| d|v rz	| ||| W n   Y nt	d| d n| 
||| |}	d}
|d	vrd
|vrd|vr| |\}	}
| ||
 |	|
|fS )a  Download model files given the full model name.
        Model name is in the format
            'type/language/dataset/model'
            e.g. 'tts_model/en/ljspeech/tacotron'

        Every model must have the following files:
            - *.pth : pytorch model checkpoint file.
            - config.json : model config file.
            - scale_stats.npy (if exist): scale values for preprocessing.

        Args:
            model_name (str): model name as explained above.
        Nzhash.md5r   )moder   z* has been updated, clearing model cache...z is already downloaded.rz   )ztortoise-v2barkry   )r   r   r   r   r   r+   isfiler   readr*   r   r   r   _update_paths)r   rs   r]   r3   r2   md5sumr4   md5sum_filer   output_model_pathoutput_config_pathr#   r#   r$   download_models  s:   
zModelManager.download_modelreturnc                 C   sn   d}d}t | D ]}|dv rt j| |}q	|dkr"t j| |}q	|du r+td|du r3td||fS )zFind the model and config files in the output path

        Args:
            output_path (str): path to the model files

        Returns:
            Tuple[str, str]: path to the model file and config file
        N)zmodel_file.pthzmodel_file.pth.tarz	model.pthr   z, [!] Model file not found in the output pathz- [!] Config file not found in the output path)r   listdirr   r   
ValueError)r4   
model_fileconfig_file	file_namer#   r#   r$   r     s   
zModelManager._find_filesc                 C   s.   d}t | D ]}|dv rt j| |}q|S )zFind the speaker encoder file in the output path

        Args:
            output_path (str): path to the model files

        Returns:
            str: path to the speaker encoder file
        N)zmodel_se.pthzmodel_se.pth.tar)r   r   r   r   )r4   speaker_encoder_filer   r#   r#   r$   _find_speaker_encoder  s   
z"ModelManager._find_speaker_encoderconfig_pathc           
      C   s  t j|d}t j|d}t j|d}t j|d}t j|d}t j|d}| |}	| d|| | d|| | d|| | d	|| | d	|| | d
|| | d
|| | d|| | d|| | d|	| | d|	| | d|| | d|| dS )zUpdate paths for certain files in config.json after download.

        Args:
            output_path (str): local path the model is downloaded to.
            config_path (str): local config.json path.
        zscale_stats.npyzspeakers.jsonzspeakers.pthzspeaker_ids.jsonzspeaker_ids.pthzconfig_se.jsonzaudio.stats_pathd_vector_filezmodel_args.d_vector_filespeakers_filezmodel_args.speakers_filespeaker_encoder_model_pathz%model_args.speaker_encoder_model_pathspeaker_encoder_config_pathz&model_args.speaker_encoder_config_pathN)r   r   r   r   _update_path)
r   r4   r   output_stats_pathoutput_d_vector_file_pathoutput_d_vector_file_pth_pathoutput_speaker_ids_file_path output_speaker_ids_file_pth_pathr   r   r#   r#   r$   r     s(   
zModelManager._update_pathsc                 C   s   |rct j|ret|}| d}t|dkrE|}|dd D ]}||v r*|| }q dS t||d  tr>|g||d < n|||d < n| |vrKdS t||  trX|g|| < n||| < || dS dS dS )zSUpdate the path in the model config.json for the current environment after downloadrL   r)   Nr~   )	r   r   r+   r	   rF   r   rh   ri   	save_json)
field_namenew_pathr   configfield_namessub_conffdr#   r#   r$   r     s&   

zModelManager._update_pathc                 C   s  t j| dd}znt|jdd}d}|rt|dddt_tj	|| 
dd	 }t|d
}||D ]}|r@tjt| || q4W d   n1 sPw   Y  t|}	|	| W d   n1 sjw   Y  t| W n tjy   td|   tjw |	 D ]#}
tj	||
}tj|rtj	|tj|
}||krt|| q|	 D ]}
tjtj	||
rttj	||
 qdS )Download the github releasesTstreamcontent-lengthr      iBtotalunit
unit_scaler(   r~   wbNz > Error: Bad zip file - )r   r   rG   headersr   r   tqdm_progressr   r   r   rF   r   iter_contentupdater   r   zipfileZipFile
extractallremove
BadZipFiler*   namelistr   basenamer   isdirr   )file_urloutput_folderr   r   total_size_in_bytes
block_sizetemp_zip_namefiledatazr%   src_pathdst_pathr#   r#   r$   rk     sD   
zModelManager._download_zip_filec                 C   s  t j| dd}zrt|jdd}d}|rt|dddt_tj	|| 
dd	 }t|d
}||D ]}|r@tjt| || q4W d   n1 sPw   Y  t|}	|	| |	 }
W d   n1 snw   Y  t| W n tjy   td|   tjw ttj	||
d D ] }tj	||
d |}tj	|tj|}||krt|| qttj	||
d  dS )r   Tr   r   r   r   r   r   r(   r~   r   Nz > Error: Bad tar file - )r   r   rG   r   r   r   r   r   r   r   rF   r   r   r   r   r   tarfiler   getnamesr   	ReadErrorr*   r   r   r   r   )r   r   r   r   r   r   temp_tar_namer   r   t	tar_namesr%   r   r   r#   r#   r$   rr   2  s<   


zModelManager._download_tar_filec              	   C   s   | D ]X}t j|dd}|dd }tj||}t|jdd}d}t|d)}	|r4t	|d	dd
t
_||D ]}
|rEt
jt|
 |	|
 q9W d   n1 sUw   Y  qdS )r   Tr   r(   r~   r   r   r   r   r   r   N)r   r   rF   r   r   r   rG   r   r   r   r   r   r   r   r   r   )	file_urlsr   r   r   r   bease_filenamer   r   r   r   r   r#   r#   r$   rj   S  s"   z"ModelManager._download_model_filesc                 C   sH   ||   v r"| | d ur"t|tsdS t|tr"t| | dkr"dS dS )NTr   F)keysrh   strr   )my_dictkeyr#   r#   r$   _check_dict_keyf  s   
zModelManager._check_dict_key)NNFT)r   )(__name__
__module____qualname__r   r   r   r5   r9   r:   rK   rN   rS   rV   rX   r[   r\   staticmethodr   rd   r  rm   rp   rw   r{   r   r   r   r   r   r   r   r   r   r   r   rk   rr   rj   r  __classcell__r#   r#   r!   r$   r      sZ    
)"1

	5$

"
 
r   )r   r   r   r   r   pathlibr   shutilr   r   typingr   r   r   r   r   r   
TTS.configr	   r
   TTS.utils.generic_utilsr   rb   objectr   r#   r#   r#   r$   <module>   s0    