L iYdZddlZddlmZddlmZddlmZmZm Z m Z m Z m Z m Z ddlmZmZddlmZddlmZdd lmZmZdd lmZdd lmZmZmZmZmZm Z d Z!d Z"e deZ#de$e#de%e$e#fdZ&de$e#de'de#fdZ(de#de)ee)e$e#e'fffdZ*GddejVZ,GddejZZ.GddeeeefZ/y)z1This module contains the PicklePersistence class.N)deepcopy)Path)AnyCallableOptionalTypeVarUnioncastoverload)BotTelegramObject) FilePathInput)warn)BasePersistencePersistenceInput) ContextTypes)BDCDUDCDCDataConversationDictConversationKeyz/a known bot replaced by PTB's PicklePersistencez2an unknown bot replaced by PTB's PicklePersistence TelegramObj)boundclsreturnc |j}t|j|Dcgc]}t|D]}|c}}Scc}}w)zsGets all subclasses of the specified object, recursively. from https://stackoverflow.com/a/3862957/9706202 )__subclasses__setunion_all_subclasses)r subclassescss e/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/telegram/ext/_picklepersistence.pyr!r!'sG##%J z? Z!TQRAS!TA!!T!!T UU!TsA kwargscJ|j|}|j||S)a This method is used for unpickling. The data, which is in the form a dictionary, is converted back into a class. Works mostly the same as :meth:`TelegramObject.__setstate__`. This function should be kept in place for backwards compatibility even if the pickling logic is changed, since `_custom_reduction` places references to this function into the pickled data. )__new__ __setstate__)rr&objs r%_reconstruct_tor+/s% ++c CV Jcp|jd}t|d|d<t|j|ffS)z This method is used for pickling. The bot attribute is preserved so _BotPickler().persistent_id works as intended. T)include_private api_kwargs) _get_attrsdictr+ __class__)rdatas r%_custom_reductionr4;s> >>$> /Dd<01D S]]D1 11r,cpeZdZdZdededeffd Zdedee ee ee fffdZ de deefd ZxZS) _BotPickler_botbotargsr&c2||_t||i|yNr8super__init__selfr9r:r&r2s r%r?z_BotPickler.__init__J  $)&)r,r*rcDt|tstSt|S)z This method is used for pickling. The bot attribute is preserved so _BotPickler().persistent_id works as intended. ) isinstancer NotImplementedr4rAr*s r%reducer_overridez_BotPickler.reducer_overrideNs#~.! ! %%r,cr||jurtSt|trt ddt Sy)zUsed to 'mark' the Bot, so it can be replaced later. See https://docs.python.org/3/library/pickle.html#pickle.Pickler.persistent_id for more info zHUnknown bot instance found. Will be replaced by `None` during unpickling) stacklevelN)r8_REPLACED_KNOWN_BOTrDr r_REPLACED_UNKNOWN_BOTrFs r% persistent_idz_BotPickler.persistent_idZs9 $)) & & c3  Z ) (r,)__name__ __module__ __qualname__ __slots__r rr?rtuplertyper1rGobjectrstrrM __classcell__r2s@r%r6r6GsgI*C**s* & & xtK0$677 8 &  HSM r,r6cFeZdZdZdededeffd ZdedeefdZ xZ S) _BotUnpicklerr7r9r:r&c2||_t||i|yr<r=r@s r%r?z_BotUnpickler.__init__lrBr,pidrcj|tk(r |jS|tk(rytjd)zSReplaces the bot with the current bot if known, else it is replaced by :obj:`None`.Nz,Found unknown persistent id when unpickling!)rKr8rLpickleUnpicklingError)rAr[s r%persistent_loadz_BotUnpickler.persistent_loadps3 % %99  ' '$$%STTr,) rNrOrPrQr rr?rUrr_rVrWs@r%rYrYis<I*C**s*U3U8C=Ur,rYcHeZdZdZdZe d.dddedeede d e d e f d Z e d/dd dedeede d e d e d ee e eeeffdZ d/dedeede d e d e d ee e eeeff fd Z d0dZdede fdZd0dZdededdfdZdeeeffdZdeeeffdZdefdZdeefdZdedefdZ dede!deeddfdZ"dededdfd Z#d!ededdfd"Z$deddfd#Z%deddfd$Z&d!eddfd%Z'deddfd&Z(ded'eddfd(Z)d!ed)eddfd*Z*d+eddfd,Z+d0d-Z,xZ-S)1PicklePersistenceaqUsing python's builtin :mod:`pickle` for making your bot persistent. Attention: The interface provided by this class is intended to be accessed exclusively by :class:`~telegram.ext.Application`. Calling any of the methods below manually might interfere with the integration of persistence into :class:`~telegram.ext.Application`. Note: This implementation of :class:`BasePersistence` uses the functionality of the pickle module to support serialization of bot instances. Specifically any reference to :attr:`~BasePersistence.bot` will be replaced by a placeholder before pickling and :attr:`~BasePersistence.bot` will be inserted back when loading the data. Examples: :any:`Persistent Conversation Bot ` .. seealso:: :wiki:`Making Your Bot Persistent ` .. versionchanged:: 20.0 * The parameters and attributes ``store_*_data`` were replaced by :attr:`store_data`. * The parameter and attribute ``filename`` were replaced by :attr:`filepath`. * :attr:`filepath` now also accepts :obj:`pathlib.Path` as argument. Args: filepath (:obj:`str` | :obj:`pathlib.Path`): The filepath for storing the pickle files. When :attr:`single_file` is :obj:`False` this will be used as a prefix. store_data (:class:`~telegram.ext.PersistenceInput`, optional): Specifies which kinds of data will be saved by this persistence instance. By default, all available kinds of data will be saved. single_file (:obj:`bool`, optional): When :obj:`False` will store 5 separate files of `filename_user_data`, `filename_bot_data`, `filename_chat_data`, `filename_callback_data` and `filename_conversations`. Default is :obj:`True`. on_flush (:obj:`bool`, optional): When :obj:`True` will only save to file when :meth:`flush` is called and keep data in memory until that happens. When :obj:`False` will store data on any transaction *and* on call to :meth:`flush`. Default is :obj:`False`. context_types (:class:`telegram.ext.ContextTypes`, optional): Pass an instance of :class:`telegram.ext.ContextTypes` to customize the types used in the ``context`` interface. If not passed, the defaults documented in :class:`telegram.ext.ContextTypes` will be used. .. versionadded:: 13.6 update_interval (:obj:`int` | :obj:`float`, optional): The :class:`~telegram.ext.Application` will update the persistence in regular intervals. This parameter specifies the time (in seconds) to wait between two consecutive runs of updating the persistence. Defaults to 60 seconds. .. versionadded:: 20.0 Attributes: filepath (:obj:`str` | :obj:`pathlib.Path`): The filepath for storing the pickle files. When :attr:`single_file` is :obj:`False` this will be used as a prefix. store_data (:class:`~telegram.ext.PersistenceInput`): Specifies which kinds of data will be saved by this persistence instance. single_file (:obj:`bool`): Optional. When :obj:`False` will store 5 separate files of `filename_user_data`, `filename_bot_data`, `filename_chat_data`, `filename_callback_data` and `filename_conversations`. Default is :obj:`True`. on_flush (:obj:`bool`): Optional. When :obj:`True` will only save to file when :meth:`flush` is called and keep data in memory until that happens. When :obj:`False` will store data on any transaction *and* on call to :meth:`flush`. Default is :obj:`False`. context_types (:class:`telegram.ext.ContextTypes`): Container for the types used in the ``context`` interface. .. versionadded:: 13.6 ) bot_data callback_data chat_data context_types conversationsfilepathon_flush single_file user_dataNrAzAPicklePersistence[dict[Any, Any], dict[Any, Any], dict[Any, Any]]rg store_datarirhupdate_intervalcyr<)rArgrkrirhrls r%r?zPicklePersistence.__init__s r,zPicklePersistence[UD, CD, BD]recyr<rn)rArgrkrirhrlres r%r?zPicklePersistence.__init__s r,ct|||t||_||_||_d|_d|_d|_d|_ d|_ td|xs t|_ y)N)rkrlzContextTypes[Any, UD, CD, BD])r>r?rrgrirhrjrdrbrcrfr rre)rArgrkrirhrlrer2s r%r?zPicklePersistence.__init__so JP"8n +6(0 2626&* 04]a<@ +]-Lln= r,rc |jjd5}t|j|j }dddd|_|d|_|jd|jj|_ |jdi|_ |d|_ y#1swYnxYw#t$r>i|_ i|_i|_|jj|_ d|_ Yytj$r+}|jj}t!d|d|d}~wt"$r(}t!d |jj|d}~wwxYw) NrbrjrdrbrcrfFile # does not contain valid pickle data Something went wrong unpickling )rgopenrYr9loadrjrdgetrerbrcrfOSErrorr]r^name TypeError Exception)rAfiler3excfilenames r%_load_singlefilez"PicklePersistence._load_singlefilesL ^##D) D !%o!6D  < < &!#D DNDN ..779DM!%D %% \}}))HeH:-PQRX[ [ ^>t}}?Q?Q>RSTZ] ] ^sBB;%B/A,B;/B84B;;AE-E-&D99 E-#E((E-cb |jd5}t|j|jcdddS#1swYyxYw#t$rYyt j $r}td|jd|d}~wt$r}td|j|d}~wwxYw)Nrrrsrtru) rvrYr9rwryr]r^r{rzr|)rArgr}r~s r% _load_filezPicklePersistence._load_file s Yt$ <$TXXt499; < < < %% aeHMM?2UVW]` ` Y>x}}oNOUX X YsEA $A A A A A B.B.*B B.B))B.cB|j|j|j|j|jd}|j j d5}t|j|tjj|dddy#1swYyxYw)N)rfrjrdrbrcwbprotocol) rfrjrdrbrcrgrvr6r9r]HIGHEST_PROTOCOLdump)rAr3r}s r%_dump_singlefilez"PicklePersistence._dump_singlefiles!// !//  ]]   % U $1H1H I N Nt T U U Us 6BBr3c|jd5}t|j|tjj |dddy#1swYyxYw)Nrr)rvr6r9r]rr)rArgr3r}s r% _dump_filezPicklePersistence._dump_file"sJ ]]4  UD $1H1H I N Nt T U U Us 6AAcK|jrnO|js3|jt|jd}|si}||_n|j t |jSw)zReturns the user_data from the pickle file if it exists or an empty :obj:`dict`. Returns: dict[:obj:`int`, :obj:`dict`]: The restored user data. _user_data)rjrirrrgrrrAr3s r% get_user_datazPicklePersistence.get_user_data&c >> !!??44==/(D#EFD!DN  ! ! #''A2A4cK|jrnO|js3|jt|jd}|si}||_n|j t |jSw)zReturns the chat_data from the pickle file if it exists or an empty :obj:`dict`. Returns: dict[:obj:`int`, :obj:`dict`]: The restored chat data. _chat_data)rdrirrrgrrrs r% get_chat_datazPicklePersistence.get_chat_data7rrcK|jrng|jsK|jt|jd}|s|j j}||_n|j t|jSw)a Returns the bot_data from the pickle file if it exists or an empty object of type :obj:`dict` | :attr:`telegram.ext.ContextTypes.bot_data`. Returns: :obj:`dict` | :attr:`telegram.ext.ContextTypes.bot_data`: The restored bot data. _bot_data)rbrirrrgrerrrs r% get_bot_datazPicklePersistence.get_bot_dataHsr == !!??44==/(C#DED))224 DM  ! ! # &&sB B cK|jrnO|js3|jt|jd}|sd}||_n|j |jyt |jSw)adReturns the callback data from the pickle file if it exists or :obj:`None`. .. versionadded:: 13.6 Returns: tuple[list[tuple[:obj:`str`, :obj:`float`, dict[:obj:`str`, :class:`object`]]], dict[:obj:`str`, :obj:`str`]] | :obj:`None`: The restored metadata or :obj:`None`, if no data was stored. _callback_dataN)rcrirrrgrrrs r%get_callback_dataz#PicklePersistence.get_callback_dataZsw    !!??44==/(H#IJD!%D   ! ! #    %**++sA?BrzcK|jrnQ|js5|jt|jd}|s|ii}||_n|j |jj |ijSw)zReturns the conversations from the pickle file if it exists or an empty dict. Args: name (:obj:`str`): The handlers name. Returns: :obj:`dict`: The restored conversations for the handler. _conversations)rfrirrrgrrxcopy)rArzr3s r%get_conversationsz#PicklePersistence.get_conversationsqs}    !!??44==/(H#IJDbz!%D   ! ! #!!%%dB/4466sB B key new_stateclK|jsi|_|jj|ij||k(ry||j||<|jsP|js3|j t |jd|jy|jyyw)aJWill update the conversations for the given handler and depending on :attr:`on_flush` save the pickle file. Args: name (:obj:`str`): The handler's name. key (:obj:`tuple`): The key the state is changed for. new_state (:class:`object`): The new state for the given key. Nr) rf setdefaultrxrhrirrrgr)rArzrrs r%update_conversationz%PicklePersistence.update_conversations!!!#D     ( (r 2 6 6s ;y H (14 %}}## n%E FHZHZ[%%' sB2B4user_idcFK|ji|_|jj||k(ry||j|<|jsP|js3|j t |j d|jy|jyyw)aWill update the user_data and depending on :attr:`on_flush` save the pickle file. Args: user_id (:obj:`int`): The user the data might have been changed for. data (:obj:`dict`): The :attr:`telegram.ext.Application.user_data` ``[user_id]``. Nr)rjrxrhrirrrgr)rArr3s r%update_user_dataz"PicklePersistence.update_user_data >> !DN >>  g &$ . "&w}}## j%A BDNNS%%' BB!chat_idcFK|ji|_|jj||k(ry||j|<|jsP|js3|j t |j d|jy|jyyw)aWill update the chat_data and depending on :attr:`on_flush` save the pickle file. Args: chat_id (:obj:`int`): The chat the data might have been changed for. data (:obj:`dict`): The :attr:`telegram.ext.Application.chat_data` ``[chat_id]``. Nr)rdrxrhrirrrgr)rArr3s r%update_chat_dataz"PicklePersistence.update_chat_datarrcK|j|k(ry||_|jsP|js3|jt |j d|jy|j yyw)zWill update the bot_data and depending on :attr:`on_flush` save the pickle file. Args: data (:obj:`dict` | :attr:`telegram.ext.ContextTypes.bot_data`): The :attr:`telegram.ext.Application.bot_data`. Nr)rbrhrirrrgrrs r%update_bot_dataz!PicklePersistence.update_bot_datasa ==D  }}## i%@ A4==Q%%' A5A7cK|j|k(ry||_|jsP|js3|jt |j d|jy|j yyw)aWill update the callback_data (if changed) and depending on :attr:`on_flush` save the pickle file. .. versionadded:: 13.6 Args: data (tuple[list[tuple[:obj:`str`, :obj:`float`, dict[:obj:`str`, :class:`object`]]], dict[:obj:`str`, :obj:`str`]]): The relevant data to restore :class:`telegram.ext.CallbackDataCache`. Nr)rcrhrirrrgrrs r%update_callback_dataz&PicklePersistence.update_callback_datasf    % !}}## n%E FHZHZ[%%' rcK|jy|jj|d|jsP|js3|j t |j d|jy|jyyw)zWill delete the specified key from the ``chat_data`` and depending on :attr:`on_flush` save the pickle file. .. versionadded:: 20.0 Args: chat_id (:obj:`int`): The chat id to delete from the persistence. Nr)rdpoprhrirrrgr)rArs r%drop_chat_dataz PicklePersistence.drop_chat_datal >> !  7D)}}## j%A BDNNS%%' BB cK|jy|jj|d|jsP|js3|j t |j d|jy|jyyw)zWill delete the specified key from the ``user_data`` and depending on :attr:`on_flush` save the pickle file. .. versionadded:: 20.0 Args: user_id (:obj:`int`): The user id to delete from the persistence. Nr)rjrrhrirrrgr)rArs r%drop_user_dataz PicklePersistence.drop_user_datarrrjc Kyw)zDoes nothing. .. versionadded:: 13.6 .. seealso:: :meth:`telegram.ext.BasePersistence.refresh_user_data` Nrn)rArrjs r%refresh_user_dataz#PicklePersistence.refresh_user_data rdc Kyw)zDoes nothing. .. versionadded:: 13.6 .. seealso:: :meth:`telegram.ext.BasePersistence.refresh_chat_data` Nrn)rArrds r%refresh_chat_dataz#PicklePersistence.refresh_chat_datarrrbc Kyw)zDoes nothing. .. versionadded:: 13.6 .. seealso:: :meth:`telegram.ext.BasePersistence.refresh_bot_data` Nrn)rArbs r%refresh_bot_dataz"PicklePersistence.refresh_bot_datarrc.K|jrN|js0|js$|js|js |j r|j yy|jr2|jt|jd|j|jr2|jt|jd|j|jr2|jt|jd|j|jr2|jt|jd|j|j r3|jt|jd|j yyw)z/Will save all data in memory to pickle file(s).rrrrrN) rirjrdrbrcrfrrrrg)rAs r%flushzPicklePersistence.flushs#   >>==%%%%%%'&~~ j%A BDNNS~~ j%A BDNNS}} i%@ A4==Q!! n%E FHZHZ[!! n%E FHZHZ["sFF)NTF<)NTFrN)rN).rNrOrP__doc__rQr rrrboolfloatr?rrrrrrrrrrTrr1intrrrrrrUrrrrrrrrrrrrrrrVrWs@r%raraysAF I26 !#  Q  -.        26 !#AE -  -.        S"b"_ =>  26 !#AE  -.        S"b"_ => ,^. Y4 YC Y UU4UvU$U(T#r']("(T#r']("'B'$,'):,.7C74D7(((-(:B6:J( (,(c((($(c((($("(( (w(4(((C(D(&(C(D(& s r d  s r d  r d \r,ra)0rr]rrpathlibrtypingrrrrr r r telegramr r telegram._utils.typesrtelegram._utils.warningsr telegram.extrrtelegram.ext._contexttypesrtelegram.ext._utils.typesrrrrrrrKrLrrSrr!r1r+rRr4Picklerr6 UnpicklerrYrarnr,r%rs&8 JJJ(/):3\\GLm>: Vk*Vs4 3D/EV k* D [  2; 255kARTXAX;Y1Y+Z 2&..D UF$$ U z\B 3z\r,