
    x'hT                     L   d dl Z d dlZd dlZd dlmZmZmZmZmZm	Z	 d dl
Z
d dlmZ d dlmZ d dlZd dlZd dlmZ d dlmZmZmZmZmZmZmZ 	 d dlZdZ ej@                  d      Z! ejD                         Z#g d	Z$g d
Z%g dZ& G d dejN                        Z( G d d      Z) G d d      Z* G d d      Z+d Z,de-de.fdZ/de-de	e-df   fdZ0de-de	e-df   fdZ1de-dejd                  de-fdZ3de-de4dee-   fdZ5efde-de4dee-   fdZ6de-dee-   fdZ7d:d ejp                  d!e.de-fd"Z9d;d#ee-ee-ef   f   d$e4dejt                  fd%Z;d& Z<d' Z=d( Z>d) Z?d:d*Z@d<d+e.d,ee   fd-ZAd. ZBd/d0d1efd2ZCd3e-d4e-fd5ZDd3e-d4e-fd6ZEde.fd7ZFde	e4df   fd8ZGd9ZHy# e$ r d dlZY Pw xY w)=    N)AnyCallableListDictOptionalUnion)sha256)	parse_qsl)types)is_pil_imageis_dict	is_stringis_byteschunksgenerate_random_tokenpil_image_to_filei   TeleBot)textaudiodocument	animationgamephotostickervideo
video_notevoicecontactlocationvenuediceinvoicesuccessful_paymentconnected_websitepollpassport_dataweb_app_datastorygiveawaygiftunique_gift))new_chat_membersleft_chat_membernew_chat_titlenew_chat_photodelete_chat_photogroup_chat_createdsupergroup_chat_createdchannel_chat_createdmigrate_to_chat_idmigrate_from_chat_idpinned_messageproximity_alert_triggeredvideo_chat_scheduledvideo_chat_startedvideo_chat_endedvideo_chat_participants_invited!message_auto_delete_timer_changedchat_background_setforum_topic_createdforum_topic_closedforum_topic_reopenedforum_topic_editedgeneral_forum_topic_hiddengeneral_forum_topic_unhiddenwrite_access_allowedusers_sharedchat_sharedgiveaway_createdgiveaway_winnersgiveaway_completedboost_addedpaid_message_price_changedchecklist_tasks_donechecklist_tasks_addeddirect_message_price_changedsuggested_post_refundedsuggested_post_infosuggested_post_approvedsuggested_post_approval_failedsuggested_post_declinedsuggested_post_paid)messageedited_messagechannel_postedited_channel_postinline_querychosen_inline_resultcallback_queryshipping_querypre_checkout_queryr%   poll_answermy_chat_memberchat_memberchat_join_requestmessage_reactionmessage_reaction_countremoved_chat_boost
chat_boostbusiness_connectionbusiness_messageedited_business_messagedeleted_business_messagespurchased_paid_mediac                   :    e Zd ZdZdZd
dZd Zd Zd Zd Z	d	 Z
y)WorkerThread
    :meta private:
    r   Nc                 2   |sGdj                  | j                  j                  dz         }| j                  xj                  dz  c_        |st        j                         }t        j
                  j                  | |       || _        d| _        t	        j                         | _
        t	        j                         | _        t	        j                         | _        t	        j                         | _        || _        d | _        d| _        | j#                          y )NzWorkerThread{0}   )nameT)format	__class__countQueue	threadingThread__init__queuedaemonEventreceived_task_event
done_eventexception_eventcontinue_eventexception_callbackexception_info_runningstart)selfr   rx   rp   s       D/var/www/flask-api/venv/lib/python3.12/site-packages/telebot/util.pyrw   zWorkerThread.__init__A   s    $++DNN,@,@1,DEDNN  A% KKME!!$T!2
#,??#4 #//+(0'oo/"4"

    c                    | j                   r	 | j                  j                  dd      \  }}}| j                  j	                          | j
                  j	                          | j                  j	                          | j                  j	                          t        j                  d       | j
                  j                           ||i | t        j                  d       | j                  j                          | j                   ry y # t        j                  $ r Y $t        $ r}t        j                  t        |      j                  dz   t!        |j"                        z   dz   t%        j&                         z          || _        | j                  j                          | j*                  r| j+                  | | j(                         | j                  j-                          Y d }~d }~ww xY w)NTg      ?)blocktimeoutzReceived taskzTask completez occurred, args=
)r   rx   getr~   clearr{   r|   r}   loggerdebugsetrt   Empty	Exceptiontype__name__strargs	traceback
format_excr   r   wait)r   taskr   kwargses        r   runzWorkerThread.runV   sn   mm+%)ZZ^^$^%K"dF##))+((..0%%'$$**,_-((,,.d%f%_-##% mm ;;  +T!W--0BBS[PSWWZcZnZnZppq&'#$$((***++D$2E2EF##((**+s   C/D G/!G/)B<G**G/c                 @    | j                   j                  |||f       y N)rx   put)r   r   r   r   s       r   r   zWorkerThread.putn       

dF+,r   c                 P    | j                   j                         r| j                  y r   r}   is_setr   r   s    r   raise_exceptionszWorkerThread.raise_exceptionsq   %    &&(%%% )r   c                 l    | j                   j                          | j                  j                          y r   )r}   r   r~   r   r   s    r   clear_exceptionszWorkerThread.clear_exceptionsu   s&    ""$!r   c                     d| _         y NF)r   r   s    r   stopzWorkerThread.stopy   s	    r   )NNN)r   
__module____qualname____doc__rs   rw   r   r   r   r   r    r   r   rl   rl   ;   s,     E*+0-&"r   rl   c                   6    e Zd ZdZd	dZd Zd Zd Zd Zd Z	y)

ThreadPoolrm   c                    || _         t        j                         | _        t        |      D cg c]"  }t	        | j
                  | j                        $ c}| _        || _        t        j                         | _
        d | _        y c c}w r   )telebotrt   tasksrangerl   on_exceptionworkersnum_threadsru   rz   r}   r   )r   r   r   _s       r   rw   zThreadPool.__init__   sd    [[]
MRS^M_`T%6%6

C`&(0"	 as   'Bc                 @    | j                   j                  |||f       y r   )r   r   )r   funcr   r   s       r   r   zThreadPool.put   r   r   c                     | j                   j                  &| j                   j                  j                  |      }nd}|s!|| _        | j                  j                          |j                  j                          y r   )r   exception_handlerhandler   r}   r   r~   )r   worker_threadexc_infohandleds       r   r   zThreadPool.on_exception   s`    <<))5ll44;;HEGG"*D  $$&$$((*r   c                 P    | j                   j                         r| j                  y r   r   r   s    r   r   zThreadPool.raise_exceptions   r   r   c                 8    | j                   j                          y r   )r}   r   r   s    r   r   zThreadPool.clear_exceptions   s    ""$r   c                     | j                   D ]  }|j                           | j                   D ]*  }|t        j                         k7  s|j	                          , y r   )r   r   ru   current_threadjoin)r   workers     r   closezThreadPool.close   sK    ll 	FKKM	ll 	F1133	r   N   )
r   r   r   r   rw   r   r   r   r   r   r   r   r   r   r   }   s%    #-+&%r   r   c                   "    e Zd ZdZd Zd Zd Zy)	AsyncTaskrm   c                     || _         || _        || _        d| _        t	        j
                  | j                        | _        | j                  j                          y )NF)target)	r   r   r   doneru   rv   _runthreadr   )r   r   r   r   s       r   rw   zAsyncTask.__init__   sD    		&&dii8r   c                     	  | j                   | j                  i | j                  | _        d| _        y # t        $ r}|| _        Y d }~d| _        y d }~ww xY w)NT)r   r   r   resultr   r   )r   r   s     r   r   zAsyncTask._run   sQ    	%$++tyy@DKK@DK 	  	DKK		s   +5 	AAAc                     | j                   s| j                  j                          t        | j                  t
              r| j                  | j                  S r   )r   r   r   
isinstancer   BaseExceptionr   s    r   r   zAsyncTask.wait   s;    yyKKdkk=1++;;r   N)r   r   r   r   rw   r   r   r   r   r   r   r      s    r   r   c                       e Zd ZdZddZd Zy)CustomRequestResponserm   c                 .    || _         || _        || _        y r   )status_coder   reason)r   	json_textr   r   s       r   rw   zCustomRequestResponse.__init__   s    &	r   c                 @    t        j                  | j                        S r   )jsonloadsr   r   s    r   r   zCustomRequestResponse.json   s    zz$))$$r   N)    )r   r   r   r   rw   r   r   r   r   r   r      s    
%r   r   c                      d } | S )rm   c                       fd}|S )Nc                  "    t        g| i |S r   )r   )r   r   fns     r   wrapperz-async_dec.<locals>.decorator.<locals>.wrapper   s    R1$1&11r   r   )r   r   s   ` r   	decoratorzasync_dec.<locals>.decorator   s    	2 r   r   )r   s    r   	async_decr      s    
 r   r   returnc                 *    | y| j                  d      S )z
    Checks if `text` is a command. Telegram chat commands start with the '/' character.
    
    :param text: Text to check.
    :type text: :obj:`str`

    :return: True if `text` is a command, else False.
    :rtype: :obj:`bool`
    F/)
startswithr   s    r   
is_commandr      s     |E??3r   c                 r    | yt        |       r(| j                         d   j                  d      d   dd S dS )av  
    Extracts the command from `text` (minus the '/') if `text` is a command (see is_command).
    If `text` is not a command, this function returns None.

    .. code-block:: python3
        :caption: Examples:
        
        extract_command('/help'): 'help'
        extract_command('/help@BotName'): 'help'
        extract_command('/search black eyed peas'): 'search'
        extract_command('Good day to you'): None

    :param text: String to extract the command from
    :type text: :obj:`str`

    :return: the command if `text` is a command (according to is_command), else None.
    :rtype: :obj:`str` or :obj:`None`
    Nr   @ro   )r   splitr   s    r   extract_commandr      s>    & |D0:40@4::<?  %a(,JdJr   c                     t        j                  dt         j                        }|j                  |       }t	        |       r|j                  d      S dS )a  
    Returns the argument after the command.
    
    .. code-block:: python3
        :caption: Examples:

        extract_arguments("/get name"): 'name'
        extract_arguments("/get"): ''
        extract_arguments("/get@botName name"): 'name'
    
    :param text: String to extract the arguments from a command
    :type text: :obj:`str`

    :return: the arguments if `text` is a command (according to is_command), else None.
    :rtype: :obj:`str` or :obj:`None`
    z/\w*(@\w*)*\s*([\s\S]*)r   N)recompile
IGNORECASEmatchr   group)r   regexpr   s      r   extract_argumentsr     sA    " ZZ2BMMBF\\$F(.6<<?8D8r   r   c                    d}d}| j                         }t        |      }d}|D ]Q  }|dz  dk7  rB||j                  k(  r|}n ||j                  z
  |j                  k(  r|} n|dk\  r|dz  }n|dz  }|dz  }S ||| j	                         S )a  
    Returns the content of the entity.
    
    :param text: The text of the message the entity belongs to
    :type text: :obj:`str`
    
    :param e: The entity to extract
    :type e: :obj:`MessageEntity`
    
    :return: The content of the entity
    :rtype: :obj:`str`
    r            r   ro   )encodelenoffsetlengthdecode)r   r   r   r   encoded_textendibytes           r   extract_entityr    s     FE;;=L
l
C	A 4KD !!(("ahh.t|!!	Q c"))++r   chars_per_stringc                 `    t        dt        |       |      D cg c]
  }| |||z     c}S c c}w )a  
    Splits one string into multiple strings, with a maximum amount of `chars_per_string` characters per string.
    This is very useful for splitting one giant message into multiples.

    :param text: The text to split
    :type text: :obj:`str`

    :param chars_per_string: The number of characters per line the text is split into.
    :type chars_per_string: :obj:`int`

    :return: The splitted text as a list of strings.
    :rtype: :obj:`list` of :obj:`str`
    r   )r   r   )r   r  r  s      r   split_stringr
  =  s3     383t9FV2WXQD1''(XXXs   +c                 $   dt         dt         ffd}|t        kD  rt        }g }	 t        |       |k  r|j                  |        |S | d| dv r	 |d      ndv r	 |d      ndv r |d      |j                         | t              d } l)aT  
    Splits one string into multiple strings, with a maximum amount of `chars_per_string` characters per string.
    This is very useful for splitting one giant message into multiples.
    If `chars_per_string` > 4096: `chars_per_string` = 4096.
    Splits by '\n', '. ' or ' ' in exactly this priority.

    :param text: The text to split
    :type text: :obj:`str`

    :param chars_per_string: The number of maximum characters per part the text is split to.
    :type chars_per_string: :obj:`int`

    :return: The splitted text as a list of strings.
    :rtype: :obj:`list` of :obj:`str`
    substrr   c                 P    | j                  j                  |       d d       | z   S )N)r   r   )r  parts    r   _text_before_lastz&smart_split.<locals>._text_before_last_  s'    {{4::f-cr23f<<r   Nr   z.  )r   MAX_MESSAGE_LENGTHr   append)r   r  r  partsr  s       @r   smart_splitr  N  s    "=# =# = ,,AS.>E
t9''LLL%%&4<$T*DT\$T*DD[$S)DTCIJ r   c                 l    dddd}| y|j                         D ]  \  }}| j                  ||      }  | S )z
    Replaces the following chars in `text` ('&' with '&amp;', '<' with '&lt;' and '>' with '&gt;').

    :param text: the text to escape
    :return: the escaped text
    z&amp;z&lt;z&gt;)&<>N)itemsreplace)r   charsoldnews       r   escaper  w  sF     V4E|KKM &S||C%&Kr   user
include_idc                     t        | j                        }d| j                   d| d|rd| j                   dz   S dz   S )a  
    Returns an HTML user link. This is useful for reports.
    Attention: Don't forget to set parse_mode to 'HTML'!


    .. code-block:: python3
        :caption: Example:

        bot.send_message(your_user_id, user_link(message.from_user) + ' started the bot!', parse_mode='HTML')

    .. note::
        You can use formatting.* for all other formatting options(bold, italic, links, and etc.)
        This method is kept for backward compatibility, and it is recommended to use formatting.* for
        more options.

    :param user: the user (not the user_id)
    :type user: :obj:`telebot.types.User`

    :param include_id: include the user_id
    :type include_id: :obj:`bool`

    :return: HTML user link
    :rtype: :obj:`str`
    z<a href='tg://user?id=z'>z</a>z (<pre>z</pre>)r   )r  
first_nameid)r   r!  rp   s      r   	user_linkr%    sU    2 $//"D$TWWIRvT:-7	)A B=?A Br   values	row_widthc           	          t        j                  |      }| j                         D cg c]  \  }}t        j                  dd|i| }}} |j                  |  |S c c}}w )aK  
    Returns a reply markup from a dict in this format: {'text': kwargs}
    This is useful to avoid always typing 'btn1 = InlineKeyboardButton(...)' 'btn2 = InlineKeyboardButton(...)' 
    
    Example:

    .. code-block:: python3
        :caption: Using quick_markup:

        from telebot.util import quick_markup

        markup = quick_markup({
            'Twitter': {'url': 'https://twitter.com'},
            'Facebook': {'url': 'https://facebook.com'},
            'Back': {'callback_data': 'whatever'}
        }, row_width=2)
        # returns an InlineKeyboardMarkup with two buttons in a row, one leading to Twitter, the other to facebook
        # and a back button below

        # kwargs can be: 
        {
            'url': None, 
            'callback_data': None, 
            'switch_inline_query': None,
            'switch_inline_query_current_chat': None,
            'callback_game': None,
            'pay': None,
            'login_url': None,
            'web_app': None
        }
    
    :param values: a dict containing all buttons to create in this format: {text: kwargs} {str:}
    :type values: :obj:`dict`

    :param row_width: number of :class:`telebot.types.InlineKeyboardButton` objects on each row
    :type row_width: :obj:`int`

    :return: InlineKeyboardMarkup
    :rtype: :obj:`types.InlineKeyboardMarkup`
    )r'  r   r   )r   InlineKeyboardMarkupr  InlineKeyboardButtonadd)r&  r'  markupr   r   buttonss         r   quick_markupr.    sk    R '')<F #LLND& 	""777G  FJJMs   !Ac                 D    | j                          | j                          yrm   N)_setchangedr   s    r   or_setr3    s     	IIKLLNr   c                 D    | j                          | j                          yr0  )_clearr2  r   s    r   or_clearr6    s     	KKMLLNr   c                      t         d      s j                   _        t         d      s j                   _        | _         fd _         fd _        y)rm   r1  r5  c                      t               S r   )r3  r   s   r   <lambda>zorify.<locals>.<lambda>  s    F1I r   c                      t               S r   )r6  r9  s   r   r:  zorify.<locals>.<lambda>  s    hqk r   N)hasattrr   r1  r   r5  r2  )r   changed_callbacks   ` r   orifyr>    sD     1f1h77 AIAE!AGr   c                       t        j                          fd}fd} D ]  }t        ||        j                  _        |_         |        S )rm   c                      D  cg c]  } | j                          }} t        |      rj                          y j                          y c c} w r   )r   anyr   r   )evboolseventsor_events     r   r2  zOrEvent.<locals>.changed  s;    '-...u:LLNNN	 /s   Ac                  l     j                         s# j                  d        j                         s"y y )N   )r   _wait)rE  s   r   	busy_waitzOrEvent.<locals>.busy_wait  s%    //#NN1 //#r   )ru   rz   r>  r   rH  )rD  r2  rI  r   rE  s   `   @r   OrEventrJ    sR      H
  a]]HNHMIOr   c                 v    |st        t        |       s |       }t        t        | |       t        t        |       S )rm   )r<  thread_localsetattrgetattr)keyconstruct_valueresetvalues       r   
per_threadrS    s1     GL#.!c5)<%%r   warnalternativec                       fd}|S )a  
    Use this decorator to mark functions as deprecated.
    When the function is used, an info (or warning if `warn` is True) is logged.

    :meta private:
    
    :param warn: If True a warning is logged else an info
    :type warn: :obj:`bool`

    :param alternative: The new function to use instead
    :type alternative: :obj:`Callable`

    :param deprecation_text: Custom deprecation text
    :type deprecation_text: :obj:`str`

    :return: The decorated function
    c                       fd}|S )Nc                      dj                    d}r|dj                    dz  }r|dz   z  }st        j                  |       nt        j                  |        | i |S )N`z` is deprecated.z Use `z	` insteadr  )r   r   infowarning)r   r   rZ  rU  deprecation_textfunctionrT  s      r   r   z.deprecated.<locals>.decorator.<locals>.wrapper-  st    x(())9:D&!5!5 6i@@...D!t$T,V,,r   r   )r]  r   rU  r\  rT  s   ` r   r   zdeprecated.<locals>.decorator,  s    
	- r   r   )rT  rU  r\  r   s   ``` r   
deprecatedr^    s    & r   c                     |j                   rC	 |j                         }t        j                  j	                  |      }| j                  |g       yy# t        $ r}t        |       Y d}~yd}~ww xY w)a(  
    A webhook endpoint for Google Cloud Functions FaaS.
    
    :param bot: The bot instance
    :type bot: :obj:`telebot.TeleBot` or :obj:`telebot.async_telebot.AsyncTeleBot`

    :param request: The request object
    :type request: :obj:`flask.Request`

    :return: The response object
    r   N)zBot FAILi  zBot ON)is_jsonget_jsonr   Updatede_jsonprocess_new_updatesr   print)botrequestrequest_jsonupdater   s        r   webhook_google_functionsrj  ?  sf     	#"++-L\\)),7F##VH-
 	  	#!H"	#s   AA 	A/A**A/   )number_retriesr]  c                    ddl m} ddlm} t	        |dz
        D ]  }	  | |i |c S   | |i |S # |$ r3}|j
                  dk(  r ||j                  d   d          n Y d}~Jd}~ww xY w)	a  
    Use this function inside loops in order to avoid getting TooManyRequests error.
    Example:
    
    .. code-block:: python3
    
        from telebot.util import antiflood
        for chat_id in chat_id_list:
        msg = antiflood(bot.send_message, chat_id, text)
        
    :param function: The function to call
    :type function: :obj:`Callable`

    :param number_retries: Number of retries to send
    :type function: :obj:int

    :param args: The arguments to pass to the function
    :type args: :obj:`tuple`

    :param kwargs: The keyword arguments to pass to the function
    :type kwargs: :obj:`dict`

    :return: None
    r   )ApiTelegramException)sleepro   i  
parametersretry_afterN)telebot.apihelperrn  timero  r   
error_coderesult_json)r]  rl  r   r   rn  ro  r   exs           r   	antifloodrw  X  s    2 7>A%& 	)	T,V,,	) ((( $ 	}}#bnn\2=AB C	s   2A*)A%%A*tokenraw_init_datac                     t        | |      }|syi }t        |      D ]   \  }}	 t        j                  |      }|||<   " |S # t        j                  $ r |||<   Y ?w xY w)z
    Parses web app data.

    :param token: The bot token
    :type token: :obj:`str`

    :param raw_init_data: The raw init data
    :type raw_init_data: :obj:`str`

    :return: The parsed init data
    F)validate_web_app_datar
   r   r   JSONDecodeError)rx  ry  is_validr   rO  rR  s         r   parse_web_app_datar~    sx     %UM:HF.  
U	 JJu%E  F3K  M	 ## 	 F3K	 s   AAAc                    	 t        t        |            }d|vry|j                  d      }dj	                  d t        |j                               D              }t        j                  d| j                         t              }t        j                  |j                         |j                         t              j                         |k(  S # t        $ r Y yw xY w)z
    Validates web app data.

    :param token: The bot token
    :type token: :obj:`str`

    :param raw_init_data: The raw init data
    :type raw_init_data: :obj:`str`

    :return: The parsed init data
    Fhashr   c              3   0   K   | ]  \  }}| d |   yw)=Nr   ).0rO  rR  s      r   	<genexpr>z(validate_web_app_data.<locals>.<genexpr>  s     !azsESE5'"2!as   s
   WebAppData)rO  msg	digestmod)dictr
   
ValueErrorpopr   sortedr  hmacr  r   r	   digest	hexdigest)rx  ry  parsed_datainit_data_hashdata_check_string
secret_keys         r   r{  r{    s    9]34 [  __V,N		!aVKL]L]L_E`!aam6RJ88J%%'):)A)A)CVLVVX\jjj  s   C 	CCc                     t        d | D              rt        d      d| vrt        d      t        | j                  d            dk7  rt        d      y)Nc              3   <   K   | ]  }|j                           y wr   )isspace)r  chars     r   r  z!validate_token.<locals>.<genexpr>  s     
,d4<<>
,s   zToken must not contain spaces:zToken must contain a colonr   z7Token must contain exactly 2 parts separated by a colonT)rA  r  r   r   rx  s    r   validate_tokenr    sU    

,e
,,899
%566
5;;s!RSSr   c                 r    	 t        |        t        | j                  d      d         S # t        $ r Y y w xY w)Nr  r   )r  r  intr   r  s    r   extract_bot_idr    s>    u u{{3"##  s   * 	66)"content_type_mediacontent_type_serviceupdate_typesrl   r   r   r   r^  r   r   r   r   r   r   r   r   r   r   r
  r  r  r%  r.  rw  r~  r{  r3  r6  r>  rJ  rS  rj  r  r  )Fr   )TNN)Ir   ru   r   typingr   r   r   r   r   r   r  hashlibr	   urllib.parser
   rx   rt   loggingr   r   telebot.service_utilsr   r   r   r   r   r   r   ujsonr   ImportErrorr  	getLoggerr   localrL  r  r  r  rv   rl   r   r   r   r   r   boolr   r   r   MessageEntityr  r  r
  r  r  Userr%  r)  r.  r3  r6  r>  rJ  rS  r^  rj  rw  r~  r{  r  r  __all__r   r   r   <module>r     s   	   = =   "    ~ ~ ~  			9	%y   ?9## ?D' 'T <% % S  T  K# K%T	"2 K.9C 9E#t)$4 9* ,  ,!4!4  ,  ,DYs Yc Yd3i Y" 4F & c & S & $s) & R # BEJJ BD BS B</c4S>12 /s /5KeKe /f
"4&"T "x/A "L2 9: %) %)Pc # 6k kS k4
T 
$U39- $m  s   F 	F#"F#