
    EqgL                        d Z ddlmZmZmZmZ ddlZddlZddlZddl	m
Z
mZmZ ddlmZmZ ddlmZ ddlmZ ddlZddlZg dZ G d	 d
e          Z G d de          Z G d de          Z ej        e          Z G d d          ZdS )aN  
This module provides the SmsAero class for interacting with the SmsAero API.

The SmsAero class provides methods for sending SMS messages, checking the status of sent messages,
managing contacts, managing groups, managing the blacklist, and more.

Example:
    smsaero = SmsAero(email="user@example.com", api_key="your_api_key")
    smsaero.send_sms(number=1234567890, text="Hello, World!")

This module also provides several exception classes for handling errors that may occur when interacting with the API.

Classes:
    SmsAero: Provides methods for interacting with the SmsAero API.
    SmsAeroException: The base class for all exceptions raised by this module.
    SmsAeroConnectionException: Raised when a connection error occurs.
    SmsAeroNoMoneyException: Raised when there is not enough money on the account to perform an operation.
    )UnionListDictOptionalN)urljoin
quote_plusurlparse)validate_emailEmailNotValidError)Response)
exceptions)SmsAeroSmsAeroExceptionSmsAeroConnectionExceptionSmsAeroNoMoneyExceptionc                       e Zd ZdZdS )r   z"Super class of all SmsAero Errors.N__name__
__module____qualname____doc__     B/var/www/html/env/lib/python3.11/site-packages/smsaero/__init__.pyr   r   -   s        ,,,,r   r   c                       e Zd ZdZdS )r   zA Connection error occurred.Nr   r   r   r   r   r   1   s        &&&&r   r   c                       e Zd ZdZdS )r   zNo money on the account.Nr   r   r   r   r   r   5   s        """"r   r   c                   
   e Zd ZdZg dZdZeddddfded	ed
ededede	e         defdZ
d Zd Zdee         fdZedeeee         f         defd            Zededefd            Zdgdededede	e         def
dZdefdZ	 	 	 dhdede	e         de	e         dedef
d Zd! Zd" Zdefd#Zdefd$Z	 	 	 dideeee         f         d%ed&e	e         d'e	ej                 d(e	e         defd)Zd*edefd+Z	 	 	 dide	eeee         f                  d%e	e         de	e         defd,Zdefd-Z d.e!d/edefd0Z"defd1Z#defd2Z$dgde	e         defd3Z%d4edefd5Z&d6edefd7Z'defd8Z(dgde	e         defd9Z)	 	 	 	 	 	 	 	 	 djdeeee         f         d6e	e         d:e	e         d;e	e         d<e	e         d=e	e         d>e	e         d?e	e         d@e	e         dAe	e         defdBZ*dCedefdDZ+defdEZ,	 	 	 	 	 	 	 	 	 djde	eeee         f                  d6e	e         d:e	e         d;e	e         dFe	e         d<e	e         d=e	e         d>e	e         de	e         defdGZ-deeee         f         defdHZ.dkde	eeee         f                  de	e         defdIZ/dJedefdKZ0deeee         f         defdLZ1dMedefdNZ2deeee         f         defdOZ3	 	 	 	 	 	 	 	 	 	 dld&edPed%ede	eeee         f                  d6e	e         dQe	e         dRe	e         dSe	e         dTe	e         dUe	e         dVe	e         dWe	e         dXe	e         defdYZ4defdZZ5dgde	e         defd[Z6dgd\ede	e         defd]Z7deeee         f         ddfd^Z8edeeee         f         ddfd_            Z9ede	e         ddfd`            Z:	 	 	 dideeee         f         d%ed&e	e         d'e	ej                 d(e	e         ddfdaZ;	 	 	 dide	eeee         f                  d%e	e         de	e         ddfdbZ<	 	 	 	 	 	 	 	 	 	 dld&edPed%ede	eeee         f                  d6e	e         dQe	e         dRe	e         dSe	e         dTe	e         dUe	e         dVe	e         dWe	e         dXe	e         ddfdcZ=	 	 	 	 	 	 	 	 	 djdeeee         f         d6e	e         d:e	e         d;e	e         d<e	e         d=e	e         d>e	e         d?e	e         d@e	e         dAe	e         ddfddZ>	 	 	 	 	 	 	 	 	 djde	eeee         f                  d6e	e         d:e	e         d;e	e         dFe	e         d<e	e         d=e	e         d>e	e         de	e         ddfdeZ?eeddddfded	ed
ededede	e         deddfdf            Z@dS )mr   z
    The SmsAero class provides methods for interacting with the SmsAero API.

    This class provides methods for sending SMS messages, checking the status of sent messages,
    managing contacts, managing groups, managing the blacklist, and more.
    )z@gate.smsaero.ru/v2/z@gate.smsaero.org/v2/z@gate.smsaero.net/v2/zSms Aero   TNFemailapi_key	signaturetimeoutallow_phone_validationurl_gate	test_modec           	      F   || _         || _        || _        || _        t	          j                    | _        | j        j                            ddi           || _	        || _
        d| _        || _        |                     |||||||           |                                  dS )a!  
        Initializes the SmsAero class.

        Parameters:
        email (str): The user's email.
        api_key (str): The user's API key. Should be 32 characters.
        signature (str, optional): The signature for the messages.
        timeout (int, optional): The timeout for the requests.
        allow_phone_validation (bool, optional): Whether to allow phone number validation.
        url_gate (str, optional): The gateway URL. For example, '@local.host/v2/'.
        test_mode (bool, optional): Whether to enable test mode.
        z
User-AgentzSAPythonClient/3.0.0N)_SmsAero__user_SmsAero__akey_SmsAero__gate_SmsAero__signrequestssession_SmsAero__sessheadersupdate_SmsAero__time_SmsAero__pnum_SmsAero__resp_SmsAero__testinit_validatecheck_and_format_user_gate)selfr   r    r!   r"   r#   r$   r%   s           r   __init__zSmsAero.__init__M   s    , &((""L2H#IJJJ,*."	
 	
 	
 	'')))))r   c                    | j         sdS t          | j                   }|j                            d          s|                    d|j        z             }|j                            d          r|                    |j        dz             }n8|j                            d          s|                    |j        dz             }|                                | _         dS )at  
        This method checks and formats the `self.__gate` attribute to ensure it starts with '@' and ends with '/v2/'.
        If `self.__gate` does not start with '@', it prepends '@' to it.
        If `self.__gate` does not end with '/v2/', it appends '/v2/' to it.
        The method does not return any value but modifies the `self.__gate` attribute in-place.
        N@)pathz/v2/z/v2/)r)   r	   r:   
startswith_replaceendswithgeturl)r6   
parsed_urls     r   r5   z"SmsAero.check_and_format_user_gatez   s     { 	Fdk**
))#.. 	I#,,#
2G,HHJ?##E** 	L#,,*/C2G,HHJJ))&11 	L#,,*/F2J,KKJ ''))r   c                     | j         S )z*
        Returns the gateway URL.
        )r)   r6   s    r   get_gatezSmsAero.get_gate   s     {r   returnc                 .    | j         r| j         gn| j        S )z
        Returns a list of gateway URLs for sending requests.
        If a gateway URL was specified during initialization, it returns a list with only that URL.
        Otherwise, it returns a list of all available gateway URLs.
        )r)   	GATE_URLSrB   s    r   get_gate_urlszSmsAero.get_gate_urls   s     !%?}}?r   numberc                 Z    | st          d          t          | t                    rdnd| iS )z
        Takes a number or a list of numbers as input.
        Returns:
        Dict: with the key as 'numbers' if input is a list, or 'number' if input is a single number.
        zNumber cannot be emptynumbersrH   )
ValueError
isinstancelist)rH   s    r   	fill_numszSmsAero.fill_nums   s9      	75666'55C		8VLLr   responsec                    	 |                                  }n"# t          $ r}t          d          |d}~ww xY w|                    d          dk    rt	          |d                   |                    d          dk    rt          |d                   |                    d          s$t          |                    d          pd	          |                    d
          S )a  
        Checks the response from the server.

        If the response contains an error message, it raises an appropriate exception.
        If the response is successful, it returns the data from the response.

        Parameters:
        response (Response): The response from the server.

        Returns:
        Dict: The data from the response if the request was successful.
        zUnexpected format is receivedNresultz
no creditsrejectreasonsuccessmessagezUnknown errordata)jsonrK   r   getr   )rO   contentes      r   check_responsezSmsAero.check_response   s    	KmmooGG 	K 	K 	K"#BCCJ	K ;;x  L00)'(*;<<<;;x  H,,"78#4555{{9%% 	N"7;;y#9#9#L_MMM{{6"""s    
616protoselectorgatepagec                     t          | dt          | j                   d| j         | |          }|r t          |dt	          |                     }|S )a_  
        Builds a URL for the request.

        Parameters:
        proto (str): The protocol for the URL (e.g., 'http' or 'https').
        selector (str): The selector for the URL.
        gate (str): The gateway for the URL.
        page (Optional[int], optional): The page number for the URL.

        Returns:
        str: The built URL.
        z://:z?page=)r   r   r'   r(   int)r6   r\   r]   r^   r_   urls         r   	build_urlzSmsAero.build_url   sf     PP:dk#:#:PPT[P$PPRZ[[ 	5#3D		3344C
r   c                 `    | j         st          d          | j                                         S )z
        Retrieves the response from the server.

        Returns:
        Dict: The server's response in JSON format.
        zNo response received)r2   r   rW   rB   s    r   get_responsezSmsAero.get_response   s1     { 	;"#9:::{!!!r   httpsrV   c                    |                                  D ]}	 |                     ||||          }t                              d||           | j                            ||pi | j                  | _        t                              d| j                                                   | 	                    | j                  c S # t          j        $ r d}Y t          j        $ r Y w xY wt          )a#  
        Sends a request to the server.

        Parameters:
        selector (str): The selector for the URL.
        data (Dict[str, Any], optional): The data to be sent in the request. If not specified, no data will be sent.
        page (int, optional): The page number for the URL. If not specified, no page number will be added to the URL.
        proto (str, optional): The protocol for the URL (e.g., 'http' or 'https'). Default is 'https'.

        Returns:
        Dict: The data from the response if the request was successful.
        z"Sending request to %s with data %s)rW   r"   zReceived response: %shttp)rG   rd   loggerdebugr-   postr0   r2   rW   r[   r   SSLErrorr+   RequestExceptionr   )r6   r]   rV   r_   r\   r^   rc   s          r   requestzSmsAero.request   s    & &&(( 	 	DnnUHdDAAA3MMM"k..sT[.YY4dk6F6F6H6HIII**4;77777&   ,    )(s   B(CC'C'&C'c                     d| _         dS )z$
        Enables test mode.
        TNr3   rB   s    r   enable_test_modezSmsAero.enable_test_mode  s     r   c                     d| _         dS )z%
        Disables test mode.
        FNrq   rB   s    r   disable_test_modezSmsAero.disable_test_mode  s     r   c                     | j         S )z~
        Checks if test mode is active.

        Returns:
        bool: True if test mode is active, False otherwise.
        rq   rB   s    r   is_test_mode_activezSmsAero.is_test_mode_active  s     {r   c                 0    |                      d          du S )a(  
        Checks if the user is authorized.

        This method sends a request to the server to check if the user is authorized.
        It does not require any parameters.

        Returns:
        bool: True if the user is authorized or SmsAeroException if the user is not authorized.
        authNro   rB   s    r   is_authorizedzSmsAero.is_authorized  s     ||F##t++r   textsigndate_to_sendcallback_urlc           	      `   |                      |||||           ||p| j        |d} |j        di |                     |           |rH|                    dt	          t          j        |                                                    i           |                     | j	        rdnd|          S )a  
        Sends a message to the specified number or numbers.

        Parameters:
        number (Union[int, List[int]]): The recipient's phone number or a list of phone numbers.
        text (str): The text of the message.
        sign (str, optional): The signature for the message.
        date_to_send (datetime, optional): The date and time when the message should be sent.
        callback_url (str, optional): The URL to which the server will send a request when the message status changes.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "id": 12345,
            "from": "Sms Aero",
            "number": "79031234567",
            "text": "Hello, World!",
            "status": 0,
            "extendStatus": "queue",
            "channel": "FREE SIGN",
            "cost": 5.49,
            "dateCreate": 1719119523,
            "dateSend": 1719119523
        }
        )r{   r|   callbackUrldateSendzsms/testsendzsms/sendr   )
send_sms_validater*   r/   rN   rb   timemktime	timetuplero   r3   )r6   rH   r{   r|   r}   r~   rV   s          r   send_smszSmsAero.send_sms&  s    F 	vtT<NNN"D,?DKP\]]--dnnV,,--- 	RKKS\5K5K5M5M)N)N%O%OPQQQ||dkINNz4PPPr   sms_idc                 ^    |                      | j        rdnddt          |          i          S )a_  
        Retrieves the status of a specific SMS.

        Parameters:
        sms_id (int): The ID of the SMS.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "id": 12345,
            "from": "Sms Aero",
            "number": "79031234567",
            "text": "Hello, World!",
            "status": 1,
            "extendStatus": "delivery",
            "channel": "FREE SIGN",
            "cost": "5.49",
            "dateCreate": 1719115820,
            "dateSend": 1719115820,
            "dateAnswer": 1719115825
        }
        zsms/teststatusz
sms/statusid)ro   r3   rb   )r6   r   s     r   
sms_statuszSmsAero.sms_statusP  s5    2 ||M,,PTVYZ`VaVaObcccr   c                     |                      |||           i }|r(|                    |                     |                     |r|                    d|i           |                     | j        rdnd||          S )a  
        Retrieves a list of SMS messages.

        Parameters:
        number (Union[int, List[int]], optional): The recipient's phone number or a list of phone numbers.
        text (str, optional): The text of the message.
        page (int, optional): The page number for the URL.

        Returns:
        Dict: The server's response in JSON format.


        Example response:
        {
            "0": {
                "id": 12345,
                "from": "Sms Aero",
                "number": "79031234567",
                "text": "Hello, World!",
                "status": 1,
                "extendStatus": "delivery",
                "channel": "FREE SIGN",
                "cost": "5.49",
                "dateCreate": 1697533302,
                "dateSend": 1697533302,
                "dateAnswer": 1697533306
            },
            "1": {
            ...
            },
            ...
            "links": {
                "self": "/v2/sms/list?page=1",
                "first": "/v2/sms/list?page=1",
                "last": "/v2/sms/list?page=3",
                "next": "/v2/sms/list?page=2"
            },
            "totalCount": "138"
        }
        r{   zsms/testlistzsms/list)sms_list_validater/   rN   ro   r3   )r6   rH   r{   r_   rV   s        r   sms_listzSmsAero.sms_listk  s    \ 	vtT222 	0KKv../// 	(KK'''||dkINNz4QUVVVr   c                 ,    |                      d          S )z
        Retrieves the balance of the user's account.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "balance": 337.03
        }
        balancery   rB   s    r   r   zSmsAero.balance  s     ||I&&&r   amountcard_idc                 h    |                      dt          |          t          |          d          S )az  
        Adds a specified amount to the balance using a specified card.

        Parameters:
        amount (float): The amount to be added to the balance.
        card_id (int): The ID of the card to be used for the transaction.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "sum": 100
        }
        zbalance/add)sumcardId)ro   floatrb   )r6   r   r   s      r   balance_addzSmsAero.balance_add  s-      ||M5==CPWLL+Y+YZZZr   c                 ,    |                      d          S )a*  
        Retrieves the cards associated with the user's account.

        This method sends a request to the server to retrieve the cards associated with the user's account.
        It does not require any parameters.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "0": {
                "id": 12345,
                "number": Visa*****1234
            },
            "1": {
                "id": 12346,
                "number": MasterCard*****4321
            }
        }
        cardsry   rB   s    r   r   zSmsAero.cards  s    , ||G$$$r   c                 ,    |                      d          S )a#  
        Retrieves the tariffs for the user's account.

        This method sends a request to the server to retrieve the tariffs for the user's account.
        It does not require any parameters.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "FREE SIGN": {
                "MEGAFON": "8.99",
                "MTS": "4.99",
                "BEELINE": "5.49",
                "TELE2": "4.79",
                "OTHER": "5.19"
            },
            ...
        }
        tariffsry   rB   s    r   r   zSmsAero.tariffs  s    , ||I&&&r   c                 0    |                      d|          S )a?  
        Retrieves a list of signatures for the user's account.

        This method sends a request to the server to retrieve a list of signatures for the user's account.
        It accepts an optional parameter for pagination.

        Parameters:
        page (int, optional): The page number for the URL.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "totalCount": "1",
            "0": {
                "id": 12345,
                "name": "TestSign",
                "status": 1,
                "extendStatus": "approve",
                "statusOperators": {
                    "1": {
                        "operator": 1,
                        "extendOperator": "MEGAFON",
                        "status": 1,
                        "extendStatus": "approve"
                    },
                    "4": {
                        "operator": 4,
                        "extendOperator": "MTS",
                        "status": 1,
                        "extendStatus": "approve"
                    },
                    "5": {
                        "operator": 5,
                        "extendOperator": "BEELINE",
                        "status": 1,
                        "extendStatus": "approve"
                    },
                    "6": {
                        "operator": 6,
                        "extendOperator": "TELE2",
                        "status": 1,
                        "extendStatus": "approve"
                    }
                }
            }
        }
        z	sign/listr_   ry   r6   r_   s     r   	sign_listzSmsAero.sign_list  s    d ||Kd|333r   namec                 2    |                      dd|i          S )aL  
        Adds a new group to the SmsAero service.

        Parameters:
        name (str): The name of the group to be added.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "id": 12345,
            "name": "TestGroup",
            "count": 0
        }
        z	group/addr   ry   )r6   r   s     r   	group_addzSmsAero.group_add%  s    " ||K&$888r   group_idc                 P    |                      ddt          |          i          du S )z
        Deletes a group from the SmsAero service.

        Parameters:
        group_id (int): The ID of the group to be deleted.

        Returns:
        bool: True if deletion was successful, SmsAeroException if deletion was unsuccessful.
        zgroup/deleter   Nro   rb   )r6   r   s     r   group_deletezSmsAero.group_delete8  s(     ||NT3x==,ABBdJJr   c                 0    |                      d          du S )z
        Deletes all group from the SmsAero service.

        Returns:
        bool: True if deletion was successful, SmsAeroException if deletion was unsuccessful.
        zgroup/delete-allNry   rB   s    r   group_delete_allzSmsAero.group_delete_allD  s     ||.//477r   c                 0    |                      d|          S )a  
        Retrieves a list of groups from the SmsAero service.

        Parameters:
        page (Optional[int], optional): The page number for the URL.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "0": {
                "id": "12345",
                "name": "test_group",
                "countContacts": "0"
            },
            ...,
            "links": {
                "self": "/v2/group/list?page=1",
                "first": "/v2/group/list?page=1",
                "last": "/v2/group/list?page=1"
            },
            "totalCount": "4"
        }
        z
group/listr   ry   r   s     r   
group_listzSmsAero.group_listM  s    4 ||Lt|444r   birthdaysex	last_name
first_namesurnameparam1param2param3c                     |                      |||||||||	|

  
         |                     d||ot          |          |||||||	|
d
          S )a   
        Adds a contact or a list of contacts to the user's account.

        Parameters:
        number (Union[int, List[int]]): The phone number or a list of phone numbers of the contacts.
        group_id (int, optional): The ID of the group to which the contacts belong.
        birthday (str, optional): The birthday of the contact.
        sex (str, optional): The sex of the contact.
        last_name (str, optional): The last name of the contact.
        first_name (str, optional): The first name of the contact.
        surname (str, optional): The surname of the contact.
        param1 (str, optional): The first custom parameter for the contact.
        param2 (str, optional): The second custom parameter for the contact.
        param3 (str, optional): The third custom parameter for the contact.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "id": 12345,
            "number": "79031234567",
            "sex": "male",
            "lname": "Doe",
            "fname": "John",
            "sname": "Smith",
            "param1": "custom1",
            "param2": "custom2",
            "param3": "custom3",
            "operator": 5,
            "extendOperator": "BEELINE"
        }
        zcontact/add)
rH   groupIdr   r   lnamefnamesnamer   r   r   )contact_add_validatero   rb   r6   rH   r   r   r   r   r   r   r   r   r   s              r   contact_addzSmsAero.contact_addi  s    ^ 	!!HhY
GVU[]c	
 	
 	
 || #5H$"#     
 
 	
r   
contact_idc                 P    |                      ddt          |          i          du S )a   
        Deletes a contact from the user's account.

        Parameters:
        contact_id (int): The ID of the contact to be deleted.

        Returns:
        bool: True if deletion was successful, SmsAeroException if deletion was unsuccessful.
        zcontact/deleter   Nr   )r6   r   s     r   contact_deletezSmsAero.contact_delete  s)     ||,tS__.EFF$NNr   c                 0    |                      d          du S )z
        Deletes all contacts from the user's account.

        Returns:
        bool: True if deletion was successful, SmsAeroException if deletion was unsuccessful.
        zcontact/delete-allNry   rB   s    r   contact_delete_allzSmsAero.contact_delete_all  s     ||011T99r   operatorc
                     |                      |||||||||		  	         |                     d||ot          |          ||||||d|	          S )a  
        Retrieves a list of contacts from the user's account.

        Parameters:
        number (Optional[Union[int, List[int]]], optional): The phone number or a list of phone numbers of the contacts.
        group_id (int, optional): The ID of the group to which the contacts belong.
        birthday (str, optional): The birthday of the contact.
        sex (str, optional): The sex of the contact.
        operator (str, optional): The operator of the contact.
        last_name (str, optional): The last name of the contact.
        first_name (str, optional): The first name of the contact.
        surname (str, optional): The surname of the contact.
        page (int, optional): The page number for the URL.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "0": {
                "id": 12345,
                "number": 79031234567,
                "sex": "male",
                "lname": "Doe",
                "fname": "John",
                "sname": "Smith",
                "param1": "",
                "param2": "",
                "param3": "",
                "operator": 5,
                "extendOperator": "BEELINE",
                "groups": [
                    {
                        "id": 12345,
                        "name": "test_group"
                    }
                ],
                "hlrStatus": 1,
                "extendHlrStatus": "available"
            },
            ...,
            "links": {
                "self": "/v2/contact/list?page=1",
                "first": "/v2/contact/list?page=1",
                "last": "/v2/contact/list?page=1"
            },
            "totalCount": "5"
        }
        zcontact/list)rH   r   r   r   r   r   r   r   )contact_list_validatero   rb   
r6   rH   r   r   r   r   r   r   r   r_   s
             r   contact_listzSmsAero.contact_list  sw    | 	""68XsHiYcelnrsss|| #5H$$"# 	 	 
 
 	
r   c                 T    |                      d|                     |                    S )aR  
        Adds a number or a list of numbers to the blacklist.

        Parameters:
        number (Union[int, List[int]]): The number or a list of numbers to be added to the blacklist.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "id": 12345,
            "number": "79031234567",
            "sex": "male",
            "lname": "Doe",
            "fname": "John",
            "sname": "Smith",
            "bday": null,
            "param": null,
            "param2": null,
            "param3": null
        }
        zblacklist/addro   rN   r6   rH   s     r   blacklist_addzSmsAero.blacklist_add  s$    0 ||OT^^F-C-CDDDr   c                 ^    |                      d|r|                     |          nd|          S )a  
        Retrieves a list of numbers from the blacklist.

        Parameters:
        number (Optional[Union[int, List[int]]], optional): The number or a list of numbers to be retrieved.
        page (Optional[int], optional): The page number for the URL.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "0": {
                "id": "12345",
                "number": "79031234567",
                "sex": "male",
                "lname": "Doe",
                "fname": "John",
                "sname": "Smith",
                "bday": null,
                "param": null,
                "param2": null,
                "param3": null
            },
            "links": {
                "self": "/v2/blacklist/list?page=1",
                "first": "/v2/blacklist/list?page=1",
                "last": "/v2/blacklist/list?page=1"
            },
            "totalCount": "1"
        }
        zblacklist/listNr   )r6   rH   r_   s      r   blacklist_listzSmsAero.blacklist_list(  s4    B ||,.XdnnV.D.D.DTXZ^___r   blacklist_idc                 P    |                      ddt          |          i          du S )a  
        Deletes a number from the blacklist.

        Parameters:
        blacklist_id (int): The ID of the number to be deleted from the blacklist.

        Returns:
        bool: True if deletion was successful, SmsAeroException if deletion was unsuccessful.
        zblacklist/deleter   Nr   )r6   r   s     r   blacklist_deletezSmsAero.blacklist_deleteK  s+     ||.s<7H7H0IJJdRRr   c                 T    |                      d|                     |                    S )a  
        Checks the Home Location Register (HLR) for a number or a list of numbers.

        Parameters:
        number (Union[int, List[int]]): The number or a list of numbers to be checked.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "id": 12345,
            "number": "79031234567",
            "hlrStatus": 4,
            "extendHlrStatus": "in work"
        }
        z	hlr/checkr   r   s     r   	hlr_checkzSmsAero.hlr_checkW  s$    $ ||K)?)?@@@r   hlr_idc                 L    |                      ddt          |          i          S )a}  
        Retrieves the status of a specific HLR check.

        Parameters:
        hlr_id (int): The ID of the HLR check.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "id": 12345,
            "number": "79031234567",
            "hlrStatus": 1,
            "extendHlrStatus": "available"
        }
        z
hlr/statusr   r   )r6   r   s     r   
hlr_statuszSmsAero.hlr_statusk  s#    $ ||L4V*=>>>r   c                 T    |                      d|                     |                    S )a  
        Retrieves the operator of a number or a list of numbers.

        Parameters:
        number (Union[int, List[int]]): The number or a list of numbers.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "number": "79031234567",
            "operator": 5,
            "extendOperator": "BEELINE"
        }
        znumber/operatorr   r   s     r   number_operatorzSmsAero.number_operator  s%    " ||-t~~f/E/EFFFr   channelimage_sourcetext_buttonlink_button	date_sendsign_smschannel_smstext_sms	price_smsc                 <   |                      |||||||||	|
|||           |ot          |          |ot          |          |ot          |          |||||	|
|||d}|r(|                    |                     |                     |                     d|          S )a7  
        Sends a Viber message.

        Parameters:
        sign (str): The signature of the message.
        channel (str): The channel of the message.
        text (str): The text of the message.
        number (Union[int, List[int]], optional): The phone number or a list of phone numbers to send the message to.
        group_id (int, optional): The ID of the group to send the message to.
        image_source (str, optional): The source of the image in the message.
        text_button (str, optional): The text of the button in the message.
        link_button (str, optional): The link of the button in the message.
        date_send (str, optional): The date to send the message.
        sign_sms (str, optional): The signature of the SMS fallback.
        channel_sms (str, optional): The channel of the SMS fallback.
        text_sms (str, optional): The text of the SMS fallback.
        price_sms (int, optional): The price of the SMS fallback.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "id": 12345,
            "number": "79031234567",
            "count": 1,
            "sign": "Viber",
            "channel": "OFFICIAL",
            "text": "Hello, World!",
            "cost": 2.25,
            "status": 1,
            "extendStatus": "moderation",
            "dateCreate": 1511153253,
            "dateSend": 1511153253,
            "countSend": 0,
            "countDelivered": 0,
            "countWrite": 0,
            "countUndelivered": 0,
            "countError": 0
        }
        )r   r|   r   r{   imageSource
textButton
linkButtonr   signSms
channelSmstextSmspriceSmsz
viber/send)viber_send_validaterb   strr/   rN   ro   )r6   r|   r   r{   rH   r   r   r   r   r   r   r   r   r   rV   s                  r   
viber_sendzSmsAero.viber_send  s    t 	  	
 	
 	
"  1CMM&SYY/3w<<'%%!%!
 
  	0KKv..///||L$///r   c                 ,    |                      d          S )a  
        Retrieves a list of Viber signs.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            "0": {
                "id": 12345,
                "name": "GOOD SIGN",
                "status": 1,
                "extendStatus": "active",
                "statusOperators": {
                    "1": {
                        "operator": 1,
                        "extendOperator": "MEGAFON",
                        "status": 0,
                        "extendStatus": "moderation"
                    },
                    ....
                }
            },
            ...
        }
        zviber/sign/listry   rB   s    r   viber_sign_listzSmsAero.viber_sign_list  s    6 ||-...r   c                 Z    |                      |           |                     d|          S )a  
        Retrieves a list of Viber messages.

        Parameters:
        page (int, optional): The page number for the URL.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            0: {
                "id": 1,
                "number": "79031234567",
                "count": 1,
                "sign": "Viber",
                "channel": "OFFICIAL",
                "text": "Hello, World!",
                "cost": 2.25,
                "status": 1,
                "extendStatus": "moderation",
                "dateCreate": 1511153253,
                "dateSend": 1511153253,
                "countSend": 0,
                "countDelivered": 0,
                "countWrite": 0,
                "countUndelivered": 0,
                "countError": 0
            },
            ...
            "links": {
                "self": "/v2/viber/list?page=1",
                "next": "/v2/viber/list?page=2",
                "last": "/v2/viber/list?page=3"
            }
        z
viber/listr   )page_validatero   r   s     r   
viber_listzSmsAero.viber_list  s/    J 	4   ||Lt|444r   
sending_idc                 z    |                      |           |                     ddt          |          i|          S )a  
        Retrieves the statistics for a specific Viber message.

        Parameters:
        sending_id (int): The ID of the Viber message.

        Returns:
        Dict: The server's response in JSON format.

        Example response:
        {
            0: {
                "number": "79031234567",
                "status": 0,
                "extendStatus": "send",
                "dateSend": 1511153341
            },
            1: {
                "number": "79031234568",
                "status": 2,
                "extendStatus": "write",
                "dateSend": 1511153341
            },
            "links": {
                "self": "/v2/viber/statistic?sendingId=1&page=1"
            }
        }
        zviber/statistic	sendingIdr   )r   ro   rb   )r6   r   r_   s      r   viber_statisticszSmsAero.viber_statistics3  s=    : 	4   ||-S__/MTX|YYYr   c                 &   t          |t          t          f          st          d          t          |t                    r8dt	          t          |                    cxk    rdk    sn t          d          t          |t                    r(t          d |D                       rt          d          t          |t                    r(t          d |D                       rt          d          | j        r| 	                    |           d	S d	S )
a>  
        Validates the phone number or a list of phone numbers.

        If number is of type int or a list of ints and if it is within the valid length range (7 to 15).
        If number is not of type int or a list of ints, or is not within the valid length range, it raises exception.

        Parameters:
        number (Union[int, List[int]]): The phone number or a list of phone numbers to validate.

        Raises:
        TypeError: If the number is not of type int or a list of ints.
        ValueError: If the number is not within the valid length range.
        z/number must be an integer or a list of integers   r   z)Length of number must be between 7 and 15c              3   l   K   | ]/}d t          t          |                    cxk    odk    nc  V  0dS )r   r   N)lenr   .0nums     r   	<genexpr>z+SmsAero.phone_validation.<locals>.<genexpr>e  sM      +]+]sc#c((mm1I1I1I1Ir1I1I1I1I,J+]+]+]+]+]+]r   z:Length of each number in the list must be between 7 and 15c              3   B   K   | ]}t          |t                     V  d S N)rL   rb   r   s     r   r   z+SmsAero.phone_validation.<locals>.<genexpr>g  s/      +W+W
30D0D,D+W+W+W+W+W+Wr   z/Type of each number in the list must be integerN)
rL   rb   rM   	TypeErrorr   r   rK   anyr1   phonenumbers_validater   s     r   phone_validationzSmsAero.phone_validationS  s,    &3+.. 	OMNNNfc"" 	J1CKK0@0@+F+F+F+FB+F+F+F+FHIIIfd## 	[+]+]V\+]+]+](](] 	[YZZZfd## 	P+W+WPV+W+W+W(W(W 	PNOOO ; 	/&&v.....	/ 	/r   c                    t          | t                    r|| D ]w}	 t          j        dt	          |          z   d          }t          j        |          st          d          L# t          j        j        $ r}t          d          |d}~ww xY wdS 	 t          j        dt	          |           z   d          }t          j        |          st          d          dS # t          j        j        $ r}t          d          |d}~ww xY w)a1  
        Validates the phone number or a list of phone numbers using the phonenumbers library.

        This function checks if the number is of type int or a list of ints and if it is a valid phone number.
        If number is not a valid number, it raises an appropriate exception.

        Parameters:
        number (Union[int, List[int]]): The phone number or a list of phone numbers to validate.

        Raises:
        TypeError: If the number is not of type int or a list of ints.
        ValueError: If the number is not a valid phone number.
        +Nz4Each number in the list must be a valid phone numberz5Each number in the list must be a valid phone number!z#Number must be a valid phone numberz$Number must be a valid phone number!)	rL   rM   phonenumbersparser   is_valid_numberrK   phonenumberutilNumberParseException)rH   r   parsed_numberrZ   s       r   r   zSmsAero.phonenumbers_validaten  sF    fd## 	P e ee$0$6sSXX~t$L$LM'7FF a()_```a#3H e e e$%\]]cddee eP , 23V3Dd K K#3MBB L$%JKKKL L/D P P P !GHHaOPs1   AA$$B8BBAC D1DDc                     | 9t          | t                    st          d          | dk    rt          d          dS dS )a  
        Validates the page parameter.

        This function checks if the page is of type int and if it is greater than 0.
        If the page is not of type int or is less than or equal to 0, it raises an appropriate exception.

        Parameters:
        page (Optional[int]): The page number to validate.

        Raises:
        ValueError: If any of the parameters are invalid.
        TypeError: If any of the parameters have an incorrect type.
        Nzpage must be an integerr   zpage must be greater than 0)rL   rb   r   rK   r   s    r   r   zSmsAero.page_validate  sR     dC(( ; 9:::qyy !>???	  yr   c                 >   t          |t                    st          d          dt          |          cxk    rdk    sn t	          d          |$t          |t                    st          d          |)t          |t
          j                  st          d          |$t          |t                    st          d          |?t          |          }t          |j        |j	        |j
        g          st	          d	          |                     |           dS )
aU  
        Validates the parameters for the send_sms method.

        Parameters:
        number (Union[int, List[int]]): The recipient's phone number or a list of phone numbers.
        text (str): The text of the message.
        sign (str, optional): The signature of the message.
        date_to_send (datetime, optional): The date to send the message.
        callback_url (str, optional): The callback URL for the message status.

        Raises:
        TypeError: If any of the parameters have an incorrect type.
        ValueError: If any of the parameters have an incorrect value.
        text must be a string     z(Length of text must be between 2 and 640Nzsign must be a stringz&date_to_send must be a datetime objectzcallback_url must be a stringz callback_url must be a valid URL)rL   r   r   r   rK   datetimer	   allschemenetlocr:   r   )r6   rH   r{   r|   r}   r~   r@   s          r   r   zSmsAero.send_sms_validate  s$   , $$$ 	53444CII$$$$$$$$GHHHJtS$9$93444#J|XEV,W,W#DEEE#J|S,I,I#;<<<#!,//J
):+<joNOO E !CDDDf%%%%%r   c                     |r|                      |           |$t          |t                    st          d          |                     |           dS )a  
        Validates the parameters for the sms_list method.

        Parameters:
        number (Union[int, List[int]], optional): The recipient's phone number or a list of phone numbers.
        text (str, optional): The text of the message.
        page (int, optional): The page number for the URL.

        Raises:
        TypeError: If any of the parameters have an incorrect type.
        ValueError: If any of the parameters have an incorrect value.
        Nr	  )r   rL   r   r   r   )r6   rH   r{   r_   s       r   r   zSmsAero.sms_list_validate  s^    $  	*!!&)))JtS$9$934444     r   c                 t   t          |t                    st          d          dt          |          cxk    rdk    sn t	          d          |$t          |t                    st          d          |+dt          |          cxk    rdk    sn t	          d          |$t          |t                    st          d	          |$t          |t
                    st          d
          |$t          |t                    st          d          |$t          |t                    st          d          |$t          |t                    st          d          |	$t          |	t                    st          d          |
$t          |
t                    st          d          |$t          |t                    st          d          |$t          |t                    st          d          |$t          |t
                    st          d          ||                     |           dS dS )a~  
        Validates the parameters for the viber_send method.

        Parameters:
        number (Union[int, List[int]]): The recipient's phone number or a list of phone numbers.
        text (str): The text of the message.
        sign (str, optional): The signature of the message.
        channel (str, optional): The channel of the message.
        group_id (int, optional): The ID of the group to send the message to.
        image_source (str, optional): The source of the image in the message.
        text_button (str, optional): The text of the button in the message.
        link_button (str, optional): The link of the button in the message.
        date_send (str, optional): The date to send the message.
        sign_sms (str, optional): The signature of the SMS fallback.
        channel_sms (str, optional): The channel of the SMS fallback.
        text_sms (str, optional): The text of the SMS fallback.
        price_sms (int, optional): The price of the SMS fallback.

        Raises:
        TypeError: If any of the parameters have an incorrect type.
        ValueError: If any of the parameters have an incorrect value.
        zText must be a string.r
  r  z1Text length must be between 2 and 640 characters.NzSign must be a string.@   z0Sign length must be between 2 and 64 characters.zChannel must be a string.Group ID must be an integer.zImage source must be a string.zText button must be a string.zLink button must be a string.zDate send must be a string.zSign SMS must be a string.zChannel SMS must be a string.zText SMS must be a string.zPrice SMS must be an integer.)rL   r   r   r   rK   rb   r   )r6   r|   r   r{   rH   r   r   r   r   r   r   r   r   r   s                 r   r   zSmsAero.viber_send_validate  sG   L $$$ 	64555CII$$$$$$$$PQQQJtS$9$94555AT$8$8$8$8b$8$8$8$8OPPPz'3'?'?7888
8S(A(A:;;;#J|S,I,I#<===":k3+G+G";<<<":k3+G+G";<<< Is)C)C 9:::
8S(A(A8999":k3+G+G";<<<
8S(A(A8999 Is)C)C ;<<<!!&))))) r   c                    ||                      |           |$t          |t                    st          d          |$t          |t                    st          d          |$t          |t                    st          d          |$t          |t                    st          d          |$t          |t                    st          d          |$t          |t                    st          d          |$t          |t                    st          d          |	$t          |	t                    st          d	          |
$t          |
t                    st          d
          dS dS )a  
        Validates the parameters for the contact_add method.

        Parameters:
        number (Union[int, List[int]]): The phone number or a list of phone numbers of the contacts.
        group_id (int, optional): The ID of the group to which the contacts belong.
        birthday (str, optional): The birthday of the contact.
        sex (str, optional): The sex of the contact.
        last_name (str, optional): The last name of the contact.
        first_name (str, optional): The first name of the contact.
        surname (str, optional): The surname of the contact.
        param1 (str, optional): The first custom parameter for the contact.
        param2 (str, optional): The second custom parameter for the contact.
        param3 (str, optional): The third custom parameter for the contact.

        Raises:
        TypeError: If any of the parameters have an incorrect type.
        ValueError: If any of the parameters have an incorrect value.
        Nr  Birthday must be a string.Sex must be a string.Last name must be a string.First name must be a string.Surname must be a string.zParam1 must be a string.zParam2 must be a string.zParam3 must be a string.)r   rL   rb   r   r   r   s              r   r   zSmsAero.contact_add_validate&  so   @ !!&)))
8S(A(A:;;;
8S(A(A8999?:c3#7#7?3444 Is)C)C 9:::!*Z*E*E!:;;;z'3'?'?7888j&=&=6777j&=&=6777j&=&=6777 r   c
                 r   |r|                      |           |$t          |t                    st          d          |$t          |t                    st          d          |$t          |t                    st          d          |$t          |t                    st          d          |$t          |t                    st          d          |$t          |t                    st          d          |$t          |t                    st          d          |                     |	           dS )	ai  
        Validates the parameters for the contact_list method.

        Parameters:
        number (Union[int, List[int]], optional): The phone number or a list of phone numbers of the contacts.
        group_id (int, optional): The ID of the group to which the contacts belong.
        birthday (str, optional): The birthday of the contact.
        sex (str, optional): The sex of the contact.
        operator (str, optional): The operator of the contact.
        last_name (str, optional): The last name of the contact.
        first_name (str, optional): The first name of the contact.
        surname (str, optional): The surname of the contact.
        page (int, optional): The page number for the URL.

        Raises:
        TypeError: If any of the parameters have an incorrect type.
        ValueError: If any of the parameters have an incorrect value.
        Nr  r  r  zOperator must be a string.r  r  r  )r   rL   rb   r   r   r   r   s
             r   r   zSmsAero.contact_list_validate[  s4   <  	*!!&)))
8S(A(A:;;;
8S(A(A8999?:c3#7#7?3444
8S(A(A8999 Is)C)C 9:::!*Z*E*E!:;;;z'3'?'?78884     r   c                    	 t          |            n/# t          $ r"}t          t          |                    |d}~ww xY wt	          |t                    st          d          dt          |          cxk    rdk    sn t          d          t	          |t                    st          d          t          |          dk     rt          d          t	          |t                    st          d	          |dk    rt          d
          t	          |t                    st          d          |$t	          |t                    st          d          t	          |t                    st          d          dS )ae  
        Validates the parameters for the __init__ method of the `SmsAero` class.

        Parameters:
        email (str): A string representing the user's email.
        @api_key (str): A string representing the API key for the SmsAero service. Should be 32 characters.
        signature (str): A string representing the signature for the SmsAero service.
        timeout (int): An integer representing the timeout for requests to the SmsAero service.
        allow_phone_validation (bool): A boolean indicating whether phone number validation is allowed.
        url_gate (str): A string representing the URL gate for the SmsAero service.
        test_mode (bool): A boolean indicating whether test mode is active.

        Raises:
        ValueError: If any of the parameters are invalid.
        TypeError: If any of the parameters have an incorrect type.
        NzAPI key must be a string.       z4API key length must be between 20 and 32 characters.zSignature must be a string.r
  z/Signature length must be at least 2 characters.zTimeout must be an integer.z#Timeout must be a positive integer.z)Allow phone validation must be a boolean.zURL gate must be a string.zTest mode must be a boolean.)	r
   r   rK   r   rL   r   r   rb   bool)r   r    r!   r"   r#   r$   r%   rZ   s           r   r4   zSmsAero.init_validate  s   4	,5!!!!! 	, 	, 	,SVV$$!+	,'3'' 	97888S\\''''R''''STTT)S)) 	;9:::y>>ANOOO'3'' 	;9:::a<<BCCC0$77 	IGHHH
8S(A(A8999)T** 	<:;;;	< 	<s    
>9>r   )NNrg   )NNN)	NNNNNNNNN)NN)
NNNNNNNNNN)Ar   r   r   r   rF   	SIGNATUREr   rb   r  r   r7   r5   rC   r   rG   staticmethodr   r   rN   r   r[   rd   rf   ro   rr   rt   rv   rz   r  r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r4   r   r   r   r   r   <   sE          I I #'+"&+* +*+* +* 	+*
 +* !%+* 3-+* +* +* +* +*Z* * *,  @tCy @ @ @ @ M%T#Y/ MD M M M \M # #d # # # \#6 s c  HSM ]`    $	"d 	" 	" 	" 	"  $"!) !)!) tn!) sm	!)
 !) 
!) !) !) !)F    T    
,t 
, 
, 
, 
,  #48&*(Q (Qc49n%(Q (Q sm	(Q
 x01(Q sm(Q 
(Q (Q (Q (QTd d d d d d: 37""	4W 4WsDI~./4W sm4W sm	4W
 
4W 4W 4W 4Wl' ' ' ' '[% [# [$ [ [ [ [$%t % % % %0' ' ' ' '024 24hsm 24t 24 24 24 24h9c 9d 9 9 9 9&
KS 
KT 
K 
K 
K 
K8$ 8 8 8 85 5x} 5 5 5 5 5> #'"&!#'$(!% $ $ $@
 @
c49n%@
 3-@
 3-	@

 c]@
 C=@
 SM@
 #@
 @
 @
 @
 
@
 @
 @
 @
D
O 
O 
O 
O 
O 
O:D : : : : 37"&"&!"&#'$(!%"L
 L
sDI~./L
 3-L
 3-	L

 c]L
 3-L
 C=L
 SML
 #L
 smL
 
L
 L
 L
 L
\EE#tCy.$9 Ed E E E E4!` !`XeCcN.C%D !`S[\_S` !`lp !` !` !` !`F
SS 
ST 
S 
S 
S 
SAc49n 5 A$ A A A A(? ? ? ? ? ?(GeCcN&; G G G G G0 37"&&*%)%)#'"&%)"&#'Z0 Z0Z0 Z0 	Z0
 sDI~./Z0 3-Z0 smZ0 c]Z0 c]Z0 C=Z0 3-Z0 c]Z0 3-Z0 C=Z0 
Z0 Z0 Z0 Z0x/ / / / /:&5 &5x} &5 &5 &5 &5 &5PZ Z3 Zhsm Zt Z Z Z Z@/uS$s)^'< / / / / /6 PeCcN&; P P P P \P< @HSM @d @ @ @ \@0 #48&*%& %&c49n%%& %& sm	%&
 x01%& sm%& 
%& %& %& %&R 37""	! !sDI~./! sm! sm	!
 
! ! ! !: 37"&&*%)%)#'"&%)"&#'C* C*C* C* 	C*
 sDI~./C* 3-C* smC* c]C* c]C* C=C* 3-C* c]C* 3-C* C=C* 
C* C* C* C*P #'"&!#'$(!% $ $ $38 38c49n%38 3-38 3-	38
 c]38 C=38 SM38 #38 38 38 38 
38 38 38 38n 37"&"&!"&#'$(!%".! .!sDI~./.! 3-.! 3-	.!
 c].! 3-.! C=.! SM.! #.! sm.! 
.! .! .! .!`  #'+"&.< .<.<.< .< 	.<
 !%.< 3-.< .< 
.< .< .< \.< .< .<r   r   )r   typingr   r   r   r   r  loggingr   urllib.parser   r   r	   email_validatorr
   r   requests.modelsr   r+   r   r  __all__	Exceptionr   r   r   	getLoggerr   rj   r   r   r   r   <module>r)     s   & / . . . . . . . . . . .    6 6 6 6 6 6 6 6 6 6 ? > > > > > > > $ $ $ $ $ $             - - - - -y - - -' ' ' ' '!1 ' ' '# # # # #. # # # 
	8	$	$~< ~< ~< ~< ~< ~< ~< ~< ~< ~<r   