L i~GdZddlZddlZddlmZddlmZmZm Z m Z m Z ddl m Z  ddlmZdZddlZdd lmZmZmZmZmZdd lmZdd lmZdd lmZerdd lm Z GddeZ!GddZ"GddZ#y#e$rdZYUwxYw)z1This module contains the CallbackDataCache class.N)MutableMapping) TYPE_CHECKINGAnyOptionalUnioncast)uuid4)LRUCacheTF) CallbackQueryInlineKeyboardButtonInlineKeyboardMarkupMessageUser)to_float_timestamp) TelegramError)CDCData)ExtBotcZeZdZdZdZddeeddffd Zdee eeeffdZ xZ S) InvalidCallbackDataa2 Raised when the received callback data has been tampered with or deleted from cache. Examples: :any:`Arbitrary Callback Data Bot ` .. seealso:: :wiki:`Arbitrary callback_data ` .. versionadded:: 13.6 Args: callback_data (:obj:`int`, optional): The button data of which the callback data could not be found. Attributes: callback_data (:obj:`int`): Optional. The button data of which the callback data could not be found.  callback_dataNrreturnc2t|d||_y)Nz\The object belonging to this callback_data was deleted or the callback_data was manipulated.)super__init__r)selfr __class__s e/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/telegram/ext/_callbackdatacache.pyrzInvalidCallbackData.__init__Ds   -:c4|j|jffS)zDefines how to serialize the exception for pickle. See :py:meth:`object.__reduce__` for more info. Returns: :obj:`tuple` )rrrs r __reduce__zInvalidCallbackData.__reduce__Ks~~ 2 2444rN) __name__ __module__ __qualname____doc__ __slots__rstrrtupletyper" __classcell__)rs@rrr.sE&#I:hsm:t:5E$hsm(<"<=5rrc jeZdZdZ d dedeedeeeeffdZ d dZ de eeeeefffd Z y) _KeyboardData) access_time button_data keyboard_uuidNr1r/r0cb||_|xsi|_|xstj|_yr#)r1r0timer/)rr1r/r0s rrz_KeyboardData.__init__Xs, +&,"&5$))+rrc6tj|_y)z.Updates the access time with the current time.N)r3r/r!s rupdate_access_timez _KeyboardData.update_access_timebs99;rcH|j|j|jfS)zsGives a tuple representation consisting of the keyboard uuid, the access time and the button data. r1r/r0r!s rto_tuplez_KeyboardData.to_tuplefs#!!4#3#3T5E5EEEr)NNrN) r$r%r&r(r)rfloatdictobjectrr5r*r8rrr.r.Usj?I (,37 66e_6d3;/0 6'F%UDf,= =>Frr.ceZdZdZdZ d!dddedeefdZded dfd Z e d efd Z e d efd Z d e d e fdZededed efdZded eeeefedefffdZeded eeeffdZded dfdZded eefdZded dfdZded dfdZded dfdZ d"deee e!jDfd dfdZ#d#dZ$ d"de%deee e!jDfd dfd Z&y)$CallbackDataCacheaA custom cache for storing the callback data of a :class:`telegram.ext.ExtBot`. Internally, it keeps two mappings with fixed maximum size: * One for mapping the data received in callback queries to the cached objects * One for mapping the IDs of received callback queries to the cached objects The second mapping allows to manually drop data that has been cached for keyboards of messages sent via inline mode. If necessary, will drop the least recently used items. Important: If you want to use this class, you must install PTB with the optional requirement ``callback-data``, i.e. .. code-block:: bash pip install "python-telegram-bot[callback-data]" Examples: :any:`Arbitrary Callback Data Bot ` .. seealso:: :wiki:`Architecture Overview `, :wiki:`Arbitrary callback_data ` .. versionadded:: 13.6 .. versionchanged:: 20.0 To use this class, PTB must be installed via ``pip install "python-telegram-bot[callback-data]"``. Args: bot (:class:`telegram.ext.ExtBot`): The bot this cache is for. maxsize (:obj:`int`, optional): Maximum number of items in each of the internal mappings. Defaults to ``1024``. persistent_data (tuple[list[tuple[:obj:`str`, :obj:`float`, dict[:obj:`str`, :class:`object`]]], dict[:obj:`str`, :obj:`str`]], optional): Data to initialize the cache with, as returned by :meth:`telegram.ext.BasePersistence.get_callback_data`. Attributes: bot (:class:`telegram.ext.ExtBot`): The bot this cache is for. )_callback_queries_keyboard_data_maxsizebotNrCz ExtBot[Any]maxsizepersistent_datacts td||_||_t ||_t ||_|r|j|yy)NziTo use `CallbackDataCache`, PTB must be installed via `pip install "python-telegram-bot[callback-data]"`.)rD)CACHE_TOOLS_AVAILABLE RuntimeErrorrCrBr rAr@load_persistence_data)rrCrDrEs rrzCallbackDataCache.__init__sZ %9  !$$ BJSZB[;CG;T   & & 7 rrc|\}}|jD]\}}||j|<|D]!\}}}t||||j|<#y)aLoads data into the cache. Warning: This method is not intended to be called by users directly. .. versionadded:: 20.0 Args: persistent_data (tuple[list[tuple[:obj:`str`, :obj:`float`, dict[:obj:`str`, :class:`object`]]], dict[:obj:`str`, :obj:`str`]], optional): Data to load, as returned by :meth:`telegram.ext.BasePersistence.get_callback_data`. r7N)itemsr@r.rA) rrE keyboard_datacallback_querieskeyvalueuuidr/datas rrIz'CallbackDataCache.load_persistence_datasm+:' '*002 0JC*/D " "3 ' 0'4  #D+t(5" )D   % rc|jS)z:obj:`int`: The maximum size of the cache. .. versionchanged:: 20.0 This property is now read-only. )rBr!s rrDzCallbackDataCache.maxsizes}}rc|jjDcgc]}|jc}t|jj fScc}w)ztuple[list[tuple[:obj:`str`, :obj:`float`, dict[:obj:`str`, :class:`object`]]], dict[:obj:`str`, :obj:`str`]]: The data that needs to be persisted to allow caching callback data across bot reboots. )rAvaluesr8r;r@rK)rrQs rpersistence_dataz"CallbackDataCache.persistence_datasN-1,?,?,F,F,HID I4  " " ( ( *L   IsA reply_markupcrtj}t|}|jDcgc]O}|Dcgc]A}|jr1t |j |j|j|n|Cc}Q}}}|js|S||j|<t|Scc}wcc}}w)aRegisters the reply markup to the cache. If any of the buttons have :attr:`~telegram.InlineKeyboardButton.callback_data`, stores that data and builds a new keyboard with the correspondingly replaced buttons. Otherwise, does nothing and returns the original reply markup. Args: reply_markup (:class:`telegram.InlineKeyboardMarkup`): The keyboard. Returns: :class:`telegram.InlineKeyboardMarkup`: The keyboard to be passed to Telegram. r) r hexr.inline_keyboardrr text_CallbackDataCache__put_buttonr0rAr )rrVr1rLcolumnbtnbuttonss rprocess_keyboardz"CallbackDataCache.process_keyboards %m4 "'66 " (( )&*&7&78I8I=&Y     "(( -:M*#G,,+  s B3AB. >B3.B3rrLchtj}||j|<|j|S)zStores the data for a single button in :attr:`keyboard_data`. Returns the string that should be passed instead of the callback_data, which is ``keyboard_uuid + button_uuids``. )r rXr0r1)rrLrPs r __put_buttonzCallbackDataCache.__put_buttons5 w{{*7 !!$'--.tf55rc|j|\}} |j|}|j|}|j||fS#t$rdt |fcYSwxYwr#) extract_uuidsrAr0r5KeyErrorr)rrkeyboardbuttonrLr0s r#__get_keyboard_uuid_and_button_dataz5CallbackDataCache.__get_keyboard_uuid_and_button_datas{ --m<& <!//9M'33F;K  , , .$$ <,];; ; )MK^1_(3  4 4rcallback_queryc$d}|jrm|j}|j|\}}|j5||_ddd|s+t|ts||j |j <d}t|jtro|j|j|jj|jjfD]$}t|ts|j|&yy#1swYxYw)aMReplaces the data in the callback query and the attached messages keyboard with the cached objects, if necessary. If the data could not be found, :class:`telegram.ext.InvalidCallbackData` will be inserted. If :attr:`telegram.CallbackQuery.data` or :attr:`telegram.CallbackQuery.message` is present, this also saves the callback queries ID in order to be able to resolve it to the stored data. Note: Also considers inserts data into the buttons of :attr:`telegram.Message.reply_to_message` and :attr:`telegram.Message.pinned_message` if necessary. Warning: *In place*, i.e. the passed :class:`telegram.CallbackQuery` will be changed! Args: callback_query (:class:`telegram.CallbackQuery`): The callback query. FNT) rQrq _unfrozenrsrr@idrjrrlpinned_messagereply_to_message)rrxmappedrQr1r0 maybe_messages rprocess_callback_queryz(CallbackDataCache.process_callback_queryms(   !&&D*.)Q)QRV)W &M;))+ 2&1# 2*[:M"N#9#9 :&&55&&77" : mW5**=9  : 7 2 2s DDc |jj|j}|j|y#t$r}t d|d}~wwxYw)aDeletes the data for the specified callback query. Note: Will *not* raise exceptions in case the callback data is not found in the cache. *Will* raise :exc:`KeyError` in case the callback query can not be found in the cache. Args: callback_query (:class:`telegram.CallbackQuery`): The callback query. Raises: KeyError: If the callback query can not be found in the cache z%CallbackQuery was not found in cache.N)r@popr{!_CallbackDataCache__drop_keyboardrd)rrxr1excs r drop_datazCallbackDataCache.drop_datasR M 2266~7H7HIM   / MBC L Ms69 A AAr1ctjt5|jj |dddy#1swYyxYwr#) contextlibsuppressrdrAr)rr1s r__drop_keyboardz!CallbackDataCache.__drop_keyboards9   * 3    # #M 2 3 3 3s ?A time_cutoffc>|j|j|y)aClears the stored callback data. Args: time_cutoff (:obj:`float` | :obj:`datetime.datetime`, optional): Pass a UNIX timestamp or a :obj:`datetime.datetime` to clear only entries which are older. |tz-naive-dtms| )rN)_CallbackDataCache__clearrA)rrs rclear_callback_dataz%CallbackDataCache.clear_callback_datas T((k Brc:|j|jy)z%Clears the stored callback query IDs.N)rr@r!s rclear_callback_queriesz(CallbackDataCache.clear_callback_queriess T++,rmappingc|s|jyt|tjrDt ||j j r |j j jnd}n|}|jDcgc]\}}|j|ks|}}}|D]}|j|ycc}}w)N)tzinfo) clearrsdtmdatetimerrCdefaultsrrKr/r)rrreffective_cutoffrNrQto_drops r__clearzCallbackDataCache.__clears MMO  k3<< 01@Q@QDHH$5$5$<$? C  C- \`%4rs&8 *<<"#  ]]7(-#$5-$5NFF0ii]"!"sA::BB