o
    i                     @   sv   d 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	 ddl
Z
ddlmZ ddlmZ d	Zd
ZG dd dZdS )zDRM module is used to handle DRM operations with clock skew correction.
Currently the only DRM operation is generating the Sec-MS-GEC token value
used in all API requests to Microsoft Edge's online text-to-speech service.    N)datetime)timezone)DictOptional   )TRUSTED_CLIENT_TOKEN)SkewAdjustmentErrorl    !l
 g    eAc                   @   s   e Zd ZU dZdZeed< ededdfddZedefd	d
Z	ede
dee fddZedejddfddZede
fddZede
fddZedee
e
f dee
e
f fddZdS )DRMzD
    Class to handle DRM operations with clock skew correction.
    g        clock_skew_secondsskew_secondsreturnNc                 C   s   t  j| 7  _dS )aW  
        Adjust the clock skew in seconds in case the system clock is off.

        This method updates the `clock_skew_seconds` attribute of the DRM class
        to the specified number of seconds.

        Args:
            skew_seconds (float): The number of seconds to adjust the clock skew to.

        Returns:
            None
        N)r	   r
   )r    r   F/home/kim/smarthome/.venv/lib/python3.10/site-packages/edge_tts/drm.pyadj_clock_skew_seconds   s   zDRM.adj_clock_skew_secondsc                   C   s   t tj tj S )z
        Gets the current timestamp in Unix format with clock skew correction.

        Returns:
            float: The current timestamp in Unix format with clock skew correction.
        )dtnowtzutc	timestampr	   r
   r   r   r   r   get_unix_timestamp+   s   zDRM.get_unix_timestampdatec                 C   s2   zt | djtjd W S  ty   Y dS w )aN  
        Parses an RFC 2616 date string into a Unix timestamp.

        This function parses an RFC 2616 date string into a Unix timestamp.

        Args:
            date (str): RFC 2616 date string to parse.

        Returns:
            Optional[float]: Unix timestamp of the parsed date string, or None if parsing failed.
        z%a, %d %b %Y %H:%M:%S %Z)tzinfoN)r   strptimereplacer   r   r   
ValueError)r   r   r   r   parse_rfc2616_date5   s   
zDRM.parse_rfc2616_dateec                 C   s   | j du r
td| | j dd}|du st|tstd| t|}|du s-t|ts5td| | t }t	||  dS )aS  
        Handle a client response error.

        This method adjusts the clock skew based on the server date in the response headers
        and raises a SkewAdjustmentError if the server date is missing or invalid.

        Args:
            e (Exception): The client response error to handle.

        Returns:
            None
        NzNo server date in headers.DatezFailed to parse server date: )
headersr   get
isinstancestrr	   r   floatr   r   )r   Zserver_dateZserver_date_parsedZclient_dater   r   r   handle_client_response_errorK   s   



z DRM.handle_client_response_errorc                  C   sN   t  } | t7 } | | d 8 } | td 9 } | dt }t|d 	 S )a  
        Generates the Sec-MS-GEC token value.

        This function generates a token value based on the current time in Windows file time format
        adjusted for clock skew, and rounded down to the nearest 5 minutes. The token is then hashed
        using SHA256 and returned as an uppercased hex digest.

        Returns:
            str: The generated Sec-MS-GEC token value.

        See Also:
            https://github.com/rany2/edge-tts/issues/290#issuecomment-2464956570
        i,  d   z.0fascii)
r	   r   	WIN_EPOCHS_TO_NSr   hashlibsha256encode	hexdigestupper)ZticksZstr_to_hashr   r   r   generate_sec_ms_gecf   s   zDRM.generate_sec_ms_gecc                   C   s   t d S )za
        Generates a random MUID.

        Returns:
            str: The generated MUID.
           )secretsZ	token_hexr,   r   r   r   r   generate_muid   s   zDRM.generate_muidr   c                 C   s,   |   }d|vs
J dt  d|d< |S )z
        Returns a copy of the given headers with the MUID header added.

        Args:
            headers (dict): The original headers.

        Returns:
            dict: The headers with the MUID header added.
        Cookiezmuid=;)copyr	   r0   )r   Zcombined_headersr   r   r   headers_with_muid   s   zDRM.headers_with_muid)__name__
__module____qualname____doc__r
   r"   __annotations__staticmethodr   r   r!   r   r   aiohttpZClientResponseErrorr#   r-   r0   r   r4   r   r   r   r   r	      s"   
 	!	(r	   )r8   r(   r/   r   r   r   r   typingr   r   r;   	constantsr   
exceptionsr   r&   r'   r	   r   r   r   r   <module>   s    