Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 29 additions & 3 deletions telegram/ext/basepersistence.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class BasePersistence(object):

All relevant methods must be overwritten. This means:

* If :attr:`store_bot_data` is ``True`` you must overwrite :meth:`get_bot_data` and
:meth:`update_bot_data`.
* If :attr:`store_chat_data` is ``True`` you must overwrite :meth:`get_chat_data` and
:meth:`update_chat_data`.
* If :attr:`store_user_data` is ``True`` you must overwrite :meth:`get_user_data` and
Expand All @@ -38,17 +40,22 @@ class BasePersistence(object):
persistence class.
store_chat_data (:obj:`bool`): Optional. Whether chat_data should be saved by this
persistence class.
store_bot_data (:obj:`bool`): Optional. Whether bot_data should be saved by this
persistence class.

Args:
store_user_data (:obj:`bool`, optional): Whether user_data should be saved by this
persistence class. Default is ``True``.
store_chat_data (:obj:`bool`, optional): Whether chat_data should be saved by this
persistence class. Default is ``True`` .
store_bot_data (:obj:`bool`, optional): Whether bot_data should be saved by this
persistence class. Default is ``True`` .
"""

def __init__(self, store_user_data=True, store_chat_data=True):
def __init__(self, store_user_data=True, store_chat_data=True, store_bot_data=True):
self.store_user_data = store_user_data
self.store_chat_data = store_chat_data
self.store_bot_data = store_bot_data

def get_user_data(self):
""""Will be called by :class:`telegram.ext.Dispatcher` upon creation with a
Expand All @@ -70,6 +77,16 @@ def get_chat_data(self):
"""
raise NotImplementedError

def get_bot_data(self):
""""Will be called by :class:`telegram.ext.Dispatcher` upon creation with a
persistence object. It should return the bot_data if stored, or an empty
``defaultdict(dict)``.

Returns:
:obj:`defaultdict`: The restored bot data.
"""
raise NotImplementedError

def get_conversations(self, name):
""""Will be called by :class:`telegram.ext.Dispatcher` when a
:class:`telegram.ext.ConversationHandler` is added if
Expand Down Expand Up @@ -101,7 +118,7 @@ def update_user_data(self, user_id, data):

Args:
user_id (:obj:`int`): The user the data might have been changed for.
data (:obj:`dict`): The :attr:`telegram.ext.dispatcher.user_data`[user_id].
data (:obj:`dict`): The :attr:`telegram.ext.dispatcher.user_data` [user_id].
"""
raise NotImplementedError

Expand All @@ -111,7 +128,16 @@ def update_chat_data(self, chat_id, data):

Args:
chat_id (:obj:`int`): The chat the data might have been changed for.
data (:obj:`dict`): The :attr:`telegram.ext.dispatcher.chat_data`[user_id].
data (:obj:`dict`): The :attr:`telegram.ext.dispatcher.chat_data` [chat_id].
"""
raise NotImplementedError

def update_bot_data(self, data):
"""Will be called by the :class:`telegram.ext.Dispatcher` after a handler has
handled an update.

Args:
data (:obj:`dict`): The :attr:`telegram.ext.dispatcher.bot_data` .
"""
raise NotImplementedError

Expand Down
20 changes: 14 additions & 6 deletions telegram/ext/callbackqueryhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,16 @@ class CallbackQueryHandler(Handler):
the callback function.
pass_chat_data (:obj:`bool`): Optional. Determines whether ``chat_data`` will be passed to
the callback function.
pass_bot_data (:obj:`bool`): Optional. Determines wether ``bot_data`` will be passed to
the callback function.

Note:
:attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a ``dict`` you
can use to keep any data in will be sent to the :attr:`callback` function. Related to
either the user or the chat that the update was sent in. For each update from the same user
or in the same chat, it will be the same ``dict``.
:attr:`pass_user_data`, :attr:`pass_chat_data` and :attr:`pass_bot_data` determine whether
a ``dict`` you can use to keep any data in will be sent to the :attr:`callback` function.
:attr:`pass_user_data` and :attr:`pass_chat_data` are related to either the user or the
chat that the update was sent in. For each update from the same user or in the same chat,
it will be the same ``dict``. :attr:`bot_data` is available independent of updates and will
always be the same ``dict``.

Args:
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
Expand All @@ -79,6 +83,8 @@ class CallbackQueryHandler(Handler):
``user_data`` will be passed to the callback function. Default is ``False``.
pass_chat_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
``chat_data`` will be passed to the callback function. Default is ``False``.
pass_bot_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
``bot_data`` will be passed to the callback function. Default is ``False``.

"""

Expand All @@ -90,13 +96,15 @@ def __init__(self,
pass_groups=False,
pass_groupdict=False,
pass_user_data=False,
pass_chat_data=False):
pass_chat_data=False,
pass_bot_data=False):
super(CallbackQueryHandler, self).__init__(
callback,
pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue,
pass_user_data=pass_user_data,
pass_chat_data=pass_chat_data)
pass_chat_data=pass_chat_data,
pass_bot_data=pass_bot_data)

if isinstance(pattern, string_types):
pattern = re.compile(pattern)
Expand Down
20 changes: 14 additions & 6 deletions telegram/ext/choseninlineresulthandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,16 @@ class ChosenInlineResultHandler(Handler):
the callback function.
pass_chat_data (:obj:`bool`): Optional. Determines whether ``chat_data`` will be passed to
the callback function.
pass_bot_data (:obj:`bool`): Optional. Determines wether ``bot_data`` will be passed to
the callback function.

Note:
:attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a ``dict`` you
can use to keep any data in will be sent to the :attr:`callback` function. Related to
either the user or the chat that the update was sent in. For each update from the same user
or in the same chat, it will be the same ``dict``.
:attr:`pass_user_data`, :attr:`pass_chat_data` and :attr:`pass_bot_data` determine whether
a ``dict`` you can use to keep any data in will be sent to the :attr:`callback` function.
:attr:`pass_user_data` and :attr:`pass_chat_data` are related to either the user or the
chat that the update was sent in. For each update from the same user or in the same chat,
it will be the same ``dict``. :attr:`bot_data` is available independent of updates and will
always be the same ``dict``.

Args:
callback (:obj:`callable`): A function that takes ``bot, update`` as positional arguments.
Expand All @@ -59,6 +63,8 @@ class ChosenInlineResultHandler(Handler):
``user_data`` will be passed to the callback function. Default is ``False``.
pass_chat_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
``chat_data`` will be passed to the callback function. Default is ``False``.
pass_bot_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
``bot_data`` will be passed to the callback function. Default is ``False``.

"""

Expand All @@ -67,13 +73,15 @@ def __init__(self,
pass_update_queue=False,
pass_job_queue=False,
pass_user_data=False,
pass_chat_data=False):
pass_chat_data=False,
pass_bot_data=False):
super(ChosenInlineResultHandler, self).__init__(
callback,
pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue,
pass_user_data=pass_user_data,
pass_chat_data=pass_chat_data)
pass_chat_data=pass_chat_data,
pass_bot_data=pass_bot_data)

def check_update(self, update):
"""Determines whether an update should be passed to this handlers :attr:`callback`.
Expand Down
19 changes: 14 additions & 5 deletions telegram/ext/commandhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,16 @@ class CommandHandler(Handler):
the callback function.
pass_chat_data (:obj:`bool`): Optional. Determines whether ``chat_data`` will be passed to
the callback function.
pass_bot_data (:obj:`bool`): Optional. Determines wether ``bot_data`` will be passed to
the callback function.

Note:
:attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a ``dict`` you
can use to keep any data in will be sent to the :attr:`callback` function. Related to
either the user or the chat that the update was sent in. For each update from the same user
:attr:`pass_user_data`, :attr:`pass_chat_data` and :attr:`pass_bot_data` determine whether
a ``dict`` you can use to keep any data in will be sent to the :attr:`callback` function.
:attr:`pass_user_data` and :attr:`pass_chat_data` are related to either the user or the
chat that the update was sent in. For each update from the same user or in the same chat,
it will be the same ``dict``. :attr:`bot_data` is available independent of updates and will
always be the same ``dict``.nt in. For each update from the same user
or in the same chat, it will be the same ``dict``.

Args:
Expand Down Expand Up @@ -84,6 +89,8 @@ class CommandHandler(Handler):
``user_data`` will be passed to the callback function. Default is ``False``.
pass_chat_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
``chat_data`` will be passed to the callback function. Default is ``False``.
pass_bot_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
``bot_data`` will be passed to the callback function. Default is ``False``.

"""

Expand All @@ -96,13 +103,15 @@ def __init__(self,
pass_update_queue=False,
pass_job_queue=False,
pass_user_data=False,
pass_chat_data=False):
pass_chat_data=False,
pass_bot_data=False):
super(CommandHandler, self).__init__(
callback,
pass_update_queue=pass_update_queue,
pass_job_queue=pass_job_queue,
pass_user_data=pass_user_data,
pass_chat_data=pass_chat_data)
pass_chat_data=pass_chat_data,
pass_bot_data=pass_bot_data)

if isinstance(command, string_types):
self.command = [command.lower()]
Expand Down
68 changes: 65 additions & 3 deletions telegram/ext/dictpersistence.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,36 +29,56 @@


class DictPersistence(BasePersistence):
"""Using python's dicts and json for making you bot persistent.
"""Using python's dicts and json for making your bot persistent.

Attributes:
store_user_data (:obj:`bool`): Whether user_data should be saved by this
persistence class.
store_chat_data (:obj:`bool`): Whether chat_data should be saved by this
persistence class.
store_bot_data (:obj:`bool`): Optional. Whether bot_data should be saved by this
persistence class.

Args:
store_user_data (:obj:`bool`, optional): Whether user_data should be saved by this
persistence class. Default is ``True``.
store_chat_data (:obj:`bool`, optional): Whether user_data should be saved by this
persistence class. Default is ``True``.
store_bot_data (:obj:`bool`, optional): Whether bot_data should be saved by this
persistence class. Default is ``True`` .
user_data_json (:obj:`str`, optional): Json string that will be used to reconstruct
user_data on creating this persistence. Default is ``""``.
chat_data_json (:obj:`str`, optional): Json string that will be used to reconstruct
chat_data on creating this persistence. Default is ``""``.
bot_data_json (:obj:`str`, optional): Json string that will be used to reconstruct
bot_data on creating this persistence. Default is ``""``.
conversations_json (:obj:`str`, optional): Json string that will be used to reconstruct
conversation on creating this persistence. Default is ``""``.

Note:
When using :class:DictPersistence:, use strings as keys for ``user_data``, ``chat_data``
and ``bot_data``. Other objects used as keys will be serialized as string and not be
cerrectly restored when calling ``json.loads``.
"""

def __init__(self, store_user_data=True, store_chat_data=True, user_data_json='',
chat_data_json='', conversations_json=''):
def __init__(self,
store_user_data=True,
store_chat_data=True,
store_bot_data=True,
user_data_json='',
chat_data_json='',
bot_data_json='',
conversations_json=''):
self.store_user_data = store_user_data
self.store_chat_data = store_chat_data
self.store_bot_data = store_bot_data
self._user_data = None
self._chat_data = None
self._bot_data = None
self._conversations = None
self._user_data_json = None
self._chat_data_json = None
self._bot_data_json = None
self._conversations_json = None
if user_data_json:
try:
Expand All @@ -72,6 +92,12 @@ def __init__(self, store_user_data=True, store_chat_data=True, user_data_json=''
self._chat_data_json = chat_data_json
except (ValueError, AttributeError):
raise TypeError("Unable to deserialize chat_data_json. Not valid JSON")
if bot_data_json:
try:
self._bot_data = json.loads(bot_data_json)
self._bot_data_json = bot_data_json
except (ValueError, AttributeError):
raise TypeError("Unable to deserialize bot_data_json. Not valid JSON")

if conversations_json:
try:
Expand Down Expand Up @@ -106,6 +132,19 @@ def chat_data_json(self):
else:
return json.dumps(self.chat_data)

@property
def bot_data(self):
""":obj:`dict`: The bot_data as a dict"""
return self._bot_data

@property
def bot_data_json(self):
""":obj:`str`: The bot_data serialized as a JSON-string."""
if self._bot_data_json:
return self._bot_data_json
else:
return json.dumps(self.bot_data)

@property
def conversations(self):
""":obj:`dict`: The conversations as a dict"""
Expand Down Expand Up @@ -143,6 +182,18 @@ def get_chat_data(self):
self._chat_data = defaultdict(dict)
return self.chat_data.copy()

def get_bot_data(self):
"""Returns the bot_data created from the ``bot_data_json`` or an empty defaultdict.

Returns:
:obj:`defaultdict`: The restored user data.
"""
if self.bot_data:
pass
else:
self._bot_data = {}
return self.bot_data.copy()

def get_conversations(self, name):
"""Returns the conversations created from the ``conversations_json`` or an empty
defaultdict.
Expand Down Expand Up @@ -192,3 +243,14 @@ def update_chat_data(self, chat_id, data):
return
self._chat_data[chat_id] = data
self._chat_data_json = None

def update_bot_data(self, data):
"""Will update the bot_data (if changed).

Args:
data (:obj:`dict`): The :attr:`telegram.ext.dispatcher.bot_data`.
"""
if self._bot_data == data:
return
self._bot_data = data.copy()
self._bot_data_json = None
Loading