o
    vZh)3                     @   s   d dl Z 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mZ d dl	m
Z
mZmZ d dlmZmZmZ ddgZeeZee  G dd dZG d	d dZG d
d deZdS )    N)_fallback_deprecated_lang	tts_langs)	Tokenizerpre_processorstokenizer_cases)_clean_tokens	_minimize_translate_urlgTTS	gTTSErrorc                   @   s   e Zd ZdZdZdZdS )SpeedznRead Speed

    The Google TTS Translate API supports two speeds:
        Slow: True
        Normal: None
    TN)__name__
__module____qualname____doc__SLOWNORMAL r   r   7/var/www/auris/lib/python3.10/site-packages/gtts/tts.pyr      s    r   c                
   @   s   e Zd ZdZdZddddZdZdd	d
dejej	ej
ejgeejejejejgjdf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S )r
   ac
  gTTS -- Google Text-to-Speech.

    An interface to Google Translate's Text-to-Speech API.

    Args:
        text (string): The text to be read.
        tld (string): Top-level domain for the Google Translate host,
            i.e `https://translate.google.<tld>`. Different Google domains
            can produce different localized 'accents' for a given
            language. This is also useful when ``google.com`` might be blocked
            within a network but a local or different Google host
            (e.g. ``google.com.hk``) is not. Default is ``com``.
        lang (string, optional): The language (IETF language tag) to
            read the text in. Default is ``en``.
        slow (bool, optional): Reads text more slowly. Defaults to ``False``.
        lang_check (bool, optional): Strictly enforce an existing ``lang``,
            to catch a language error early. If set to ``True``,
            a ``ValueError`` is raised if ``lang`` doesn't exist.
            Setting ``lang_check`` to ``False`` skips Web requests
            (to validate language) and therefore speeds up instantiation.
            Default is ``True``.
        pre_processor_funcs (list): A list of zero or more functions that are
            called to transform (pre-process) text before tokenizing. Those
            functions must take a string and return a string. Defaults to::

                [
                    pre_processors.tone_marks,
                    pre_processors.end_of_line,
                    pre_processors.abbreviations,
                    pre_processors.word_sub
                ]

        tokenizer_func (callable): A function that takes in a string and
            returns a list of string (tokens). Defaults to::

                Tokenizer([
                    tokenizer_cases.tone_marks,
                    tokenizer_cases.period_comma,
                    tokenizer_cases.colon,
                    tokenizer_cases.other_punctuation
                ]).run

        timeout (float or tuple, optional): Seconds to wait for the server to
            send data before giving up, as a float, or a ``(connect timeout,
            read timeout)`` tuple. ``None`` will wait forever (default).

    See Also:
        :doc:`Pre-processing and tokenizing <tokenizer>`

    Raises:
        AssertionError: When ``text`` is ``None`` or empty; when there's nothing
            left to speak after pre-processing, tokenizing and cleaning.
        ValueError: When ``lang_check`` is ``True`` and ``lang`` is not supported.
        RuntimeError: When ``lang_check`` is ``True`` but there's an error loading
            the languages dictionary.

    d   zhttp://translate.google.com/znMozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36z/application/x-www-form-urlencoded;charset=utf-8)ZRefererz
User-AgentzContent-TypejQ1olccomenFTNc	              
   C   s   t t  D ]\}	}
|	dkrqtd|	|
 q|sJ d|| _|| _|| _|| _| jret	|| _zt
 }| j|vrAtd| W n" tyd } ztjt|dd tt| W Y d }~nd }~ww |rltj| _ntj| _|| _|| _|| _d S )Nselfz%s: %szNo text to speakzLanguage not supported: %sT)exc_info)dictlocalsitemslogdebugtexttld
lang_checklangr   r   
ValueErrorRuntimeErrorstrwarningr   r   speedr   pre_processor_funcstokenizer_functimeout)r   r    r!   r#   Zslowr"   r)   r*   r+   kvZlangser   r   r   __init__f   s6   



zgTTS.__init__c                 C   s   |  }| jD ]}td| ||}qt|| jkr t|gS td| j | |}t|}g }|D ]}|t|d| j7 }q4dd |D }|S )Nzpre-processing: %sztokenizing: %s c                 S   s   g | ]}|r|qS r   r   ).0tr   r   r   
<listcomp>   s    z"gTTS._tokenize.<locals>.<listcomp>)	stripr)   r   r   lenGOOGLE_TTS_MAX_CHARSr   r*   r   )r   r    pptokensZ
min_tokensr2   r   r   r   	_tokenize   s   



zgTTS._tokenizec                 C   s   t | jdd}| | j}tdt| tdt| |s#J dg }t|D ]!\}}| 	|}td|| t
jd||| jd}||  q)|S )	zCreated the TTS API the request(s) without sending them.

        Returns:
            list: ``requests.PreparedRequests_``. <https://2.python-requests.org/en/master/api/#requests.PreparedRequest>`_``.
        z(_/TranslateWebserverUi/data/batchexecute)r!   pathztext_parts: %sztext_parts: %izNo text to send to TTS APIzdata-%i: %sPOST)methodurldataheaders)r	   r!   r9   r    r   r   r&   r5   	enumerate_package_rpcrequestsRequestGOOGLE_TTS_HEADERSappendprepare)r   Ztranslate_urlZ
text_partsprepared_requestsidxpartr>   rr   r   r   _prepare_requests   s&   
zgTTS._prepare_requestsc                 C   sP   || j | jdg}tj|dd}| j|d dggg}tj|dd}dtj|S )Nnull),:)
separatorsZgenericz	f.req={}&)	r#   r(   jsondumpsGOOGLE_TTS_RPCformaturllibparsequote)r   r    Z	parameterZescaped_parameterZrpcZespaced_rpcr   r   r   rA      s
   zgTTS._package_rpcc                 C   s   dd |   D S )zGet TTS API request bodies(s) that would be sent to the TTS API.

        Returns:
            list: A list of TTS API request bodies to make.
        c                 S   s   g | ]}|j qS r   )body)r1   prr   r   r   r3      s    z#gTTS.get_bodies.<locals>.<listcomp>)rK   )r   r   r   r   
get_bodies   s   zgTTS.get_bodiesc                 c   s   zt jjt jjjj W n   Y |  }t|D ]\}}zAt  }|j	|dt
j | jd}W d   n1 s<w   Y  td||jj td||jj td||j |  W n4 t jjy{ } ztt| t| |dd}~w t jjy } ztt| t| dd}~ww |jd	d
D ](}|d}d|v rtd|}	|	r|	dd}
t|
V  qt| |dqtd| qdS )zDo the TTS API request(s) and stream bytes

        Raises:
            :class:`gTTSError`: When there's an error with the API request.

        F)requestverifyproxiesr+   Nzheaders-%i: %sz
url-%i: %szstatus-%i: %s)ttsresponse)r]   i   )
chunk_sizezutf-8r   zjQ1olc","\[\\"(.*)\\"]   asciizpart-%i created) rB   packagesurllib3disable_warnings
exceptionsInsecureRequestWarningrK   r@   SessionsendrT   rZ   
getproxiesr+   r   r   r?   r=   status_coderaise_for_status	HTTPErrorr&   r   RequestException
iter_linesdecoderesearchgroupencodebase64	b64decode)r   rG   rH   rX   srJ   r.   lineZdecoded_lineZaudio_searchas_bytesr   r   r   stream   sT   	

	

	zgTTS.streamc              
   C   sb   zt |  D ]\}}|| td|| qW dS  ttfy0 } ztdt| d}~ww )aQ  Do the TTS API request(s) and write bytes to a file-like object.

        Args:
            fp (file object): Any file-like object to write the ``mp3`` to.

        Raises:
            :class:`gTTSError`: When there's an error with the API request.
            TypeError: When ``fp`` is not a file-like object that takes bytes.

        zpart-%i written to %sz<'fp' is not a file-like object or it does not take bytes: %sN)r@   ry   writer   r   AttributeError	TypeErrorr&   )r   fprH   decodedr.   r   r   r   write_to_fp/  s   

zgTTS.write_to_fpc                 C   sR   t t|d}| | |  td| W d   dS 1 s"w   Y  dS )zDo the TTS API request and write result to file.

        Args:
            savefile (string): The path and file name to save the ``mp3`` to.

        Raises:
            :class:`gTTSError`: When there's an error with the API request.

        wbzSaved to %sN)openr&   r   flushr   r   )r   Zsavefilefr   r   r   saveD  s
   

"z	gTTS.save)r   r   r   r   r6   rD   rR   r   Z
tone_marksend_of_lineZabbreviationsZword_subr   r   Zperiod_commacolonZother_punctuationrunr/   r9   rK   rA   rY   ry   r   r   r   r   r   r   r
   !   sD    :
A#8c                       s,   e Zd ZdZd fdd	ZdddZ  ZS )r   zAException that uses context to present a meaningful error messageNc                    sb   | dd | _| dd | _|r|| _n| jd ur#| | j| j| _nd | _tt| | j d S )Nr]   r^   )popr]   rspmsg	infer_msgsuperr   r/   )r   r   kwargs	__class__r   r   r/   W  s   
zgTTSError.__init__c                 C   s   d}|du rd}|j dkrt|j d}d|}n7|j}|j}d||}|dkr,d	}n$|d
kr<|j dkr<d|j }n|dkrJ|jsJd| jj }n|dkrPd}d||S )zyAttempt to guess what went wrong by using known
        information (e.g. http response) and observed behaviour

        UnknownNzFailed to connectr   )r!   zHost '{}' is not reachablez{:d} ({}) from TTS APIi  z!Bad token or upstream API changesi  zUnsupported tld '{}'   z6No audio stream in response. Unsupported language '%s'i  z$Upstream API error. Try again later.z{}. Probable cause: {})r!   r	   rS   rj   reasonr"   r]   r#   )r   r]   r   causeZpremisehoststatusr   r   r   r   r   b  s,   

zgTTSError.infer_msg)N)r   r   r   r   r/   r   __classcell__r   r   r   r   r   T  s    )rt   rP   loggingrp   rT   rB   Z	gtts.langr   r   Zgtts.tokenizerr   r   r   Z
gtts.utilsr   r   r	   __all__	getLoggerr   r   
addHandlerNullHandlerr   r
   	Exceptionr   r   r   r   r   <module>   s"   
  5