#!/usr/bin/env python # # A library that provides a Python interface to the Telegram Bot API # Copyright (C) 2015-2024 # Leandro Toledo de Souza # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser Public License for more details. # # You should have received a copy of the GNU Lesser Public License # along with this program. If not, see [http://www.gnu.org/licenses/]. """This module contains the classes that represent Telegram MessageOigin.""" import datetime from typing import TYPE_CHECKING, Dict, Final, Optional, Type from telegram import constants from telegram._chat import Chat from telegram._telegramobject import TelegramObject from telegram._user import User from telegram._utils import enum from telegram._utils.datetime import extract_tzinfo_from_defaults, from_timestamp from telegram._utils.types import JSONDict if TYPE_CHECKING: from telegram import Bot class MessageOrigin(TelegramObject): """ Base class for telegram MessageOrigin object, it can be one of: * :class:`MessageOriginUser` * :class:`MessageOriginHiddenUser` * :class:`MessageOriginChat` * :class:`MessageOriginChannel` Objects of this class are comparable in terms of equality. Two objects of this class are considered equal, if their :attr:`type` and :attr:`date` are equal. .. versionadded:: 20.8 Args: type (:obj:`str`): Type of the message origin, can be on of: :attr:`~telegram.MessageOrigin.USER`, :attr:`~telegram.MessageOrigin.HIDDEN_USER`, :attr:`~telegram.MessageOrigin.CHAT`, or :attr:`~telegram.MessageOrigin.CHANNEL`. date (:obj:`datetime.datetime`): Date the message was sent originally. |datetime_localization| Attributes: type (:obj:`str`): Type of the message origin, can be on of: :attr:`~telegram.MessageOrigin.USER`, :attr:`~telegram.MessageOrigin.HIDDEN_USER`, :attr:`~telegram.MessageOrigin.CHAT`, or :attr:`~telegram.MessageOrigin.CHANNEL`. date (:obj:`datetime.datetime`): Date the message was sent originally. |datetime_localization| """ __slots__ = ( "date", "type", ) USER: Final[str] = constants.MessageOriginType.USER """:const:`telegram.constants.MessageOriginType.USER`""" HIDDEN_USER: Final[str] = constants.MessageOriginType.HIDDEN_USER """:const:`telegram.constants.MessageOriginType.HIDDEN_USER`""" CHAT: Final[str] = constants.MessageOriginType.CHAT """:const:`telegram.constants.MessageOriginType.CHAT`""" CHANNEL: Final[str] = constants.MessageOriginType.CHANNEL """:const:`telegram.constants.MessageOriginType.CHANNEL`""" def __init__( self, type: str, # pylint: disable=W0622 date: datetime.datetime, *, api_kwargs: Optional[JSONDict] = None, ): super().__init__(api_kwargs=api_kwargs) # Required by all subclasses self.type: str = enum.get_member(constants.MessageOriginType, type, type) self.date: datetime.datetime = date self._id_attrs = ( self.type, self.date, ) self._freeze() @classmethod def de_json( cls, data: Optional[JSONDict], bot: Optional["Bot"] = None ) -> Optional["MessageOrigin"]: """Converts JSON data to the appropriate :class:`MessageOrigin` object, i.e. takes care of selecting the correct subclass. """ data = cls._parse_data(data) if not data: return None _class_mapping: Dict[str, Type[MessageOrigin]] = { cls.USER: MessageOriginUser, cls.HIDDEN_USER: MessageOriginHiddenUser, cls.CHAT: MessageOriginChat, cls.CHANNEL: MessageOriginChannel, } if cls is MessageOrigin and data.get("type") in _class_mapping: return _class_mapping[data.pop("type")].de_json(data=data, bot=bot) loc_tzinfo = extract_tzinfo_from_defaults(bot) data["date"] = from_timestamp(data.get("date"), tzinfo=loc_tzinfo) if "sender_user" in data: data["sender_user"] = User.de_json(data.get("sender_user"), bot) if "sender_chat" in data: data["sender_chat"] = Chat.de_json(data.get("sender_chat"), bot) if "chat" in data: data["chat"] = Chat.de_json(data.get("chat"), bot) return super().de_json(data=data, bot=bot) class MessageOriginUser(MessageOrigin): """ The message was originally sent by a known user. .. versionadded:: 20.8 Args: date (:obj:`datetime.datetime`): Date the message was sent originally. |datetime_localization| sender_user (:class:`telegram.User`): User that sent the message originally. Attributes: type (:obj:`str`): Type of the message origin. Always :tg-const:`~telegram.MessageOrigin.USER`. date (:obj:`datetime.datetime`): Date the message was sent originally. |datetime_localization| sender_user (:class:`telegram.User`): User that sent the message originally. """ __slots__ = ("sender_user",) def __init__( self, date: datetime.datetime, sender_user: User, *, api_kwargs: Optional[JSONDict] = None, ): super().__init__(type=self.USER, date=date, api_kwargs=api_kwargs) with self._unfrozen(): self.sender_user: User = sender_user class MessageOriginHiddenUser(MessageOrigin): """ The message was originally sent by an unknown user. .. versionadded:: 20.8 Args: date (:obj:`datetime.datetime`): Date the message was sent originally. |datetime_localization| sender_user_name (:obj:`str`): Name of the user that sent the message originally. Attributes: type (:obj:`str`): Type of the message origin. Always :tg-const:`~telegram.MessageOrigin.HIDDEN_USER`. date (:obj:`datetime.datetime`): Date the message was sent originally. |datetime_localization| sender_user_name (:obj:`str`): Name of the user that sent the message originally. """ __slots__ = ("sender_user_name",) def __init__( self, date: datetime.datetime, sender_user_name: str, *, api_kwargs: Optional[JSONDict] = None, ): super().__init__(type=self.HIDDEN_USER, date=date, api_kwargs=api_kwargs) with self._unfrozen(): self.sender_user_name: str = sender_user_name class MessageOriginChat(MessageOrigin): """ The message was originally sent on behalf of a chat to a group chat. .. versionadded:: 20.8 Args: date (:obj:`datetime.datetime`): Date the message was sent originally. |datetime_localization| sender_chat (:class:`telegram.Chat`): Chat that sent the message originally. author_signature (:obj:`str`, optional): For messages originally sent by an anonymous chat administrator, original message author signature Attributes: type (:obj:`str`): Type of the message origin. Always :tg-const:`~telegram.MessageOrigin.CHAT`. date (:obj:`datetime.datetime`): Date the message was sent originally. |datetime_localization| sender_chat (:class:`telegram.Chat`): Chat that sent the message originally. author_signature (:obj:`str`): Optional. For messages originally sent by an anonymous chat administrator, original message author signature """ __slots__ = ( "author_signature", "sender_chat", ) def __init__( self, date: datetime.datetime, sender_chat: Chat, author_signature: Optional[str] = None, *, api_kwargs: Optional[JSONDict] = None, ): super().__init__(type=self.CHAT, date=date, api_kwargs=api_kwargs) with self._unfrozen(): self.sender_chat: Chat = sender_chat self.author_signature: Optional[str] = author_signature class MessageOriginChannel(MessageOrigin): """ The message was originally sent to a channel chat. .. versionadded:: 20.8 Args: date (:obj:`datetime.datetime`): Date the message was sent originally. |datetime_localization| chat (:class:`telegram.Chat`): Channel chat to which the message was originally sent. message_id (:obj:`int`): Unique message identifier inside the chat. author_signature (:obj:`str`, optional): Signature of the original post author. Attributes: type (:obj:`str`): Type of the message origin. Always :tg-const:`~telegram.MessageOrigin.CHANNEL`. date (:obj:`datetime.datetime`): Date the message was sent originally. |datetime_localization| chat (:class:`telegram.Chat`): Channel chat to which the message was originally sent. message_id (:obj:`int`): Unique message identifier inside the chat. author_signature (:obj:`str`): Optional. Signature of the original post author. """ __slots__ = ( "author_signature", "chat", "message_id", ) def __init__( self, date: datetime.datetime, chat: Chat, message_id: int, author_signature: Optional[str] = None, *, api_kwargs: Optional[JSONDict] = None, ): super().__init__(type=self.CHANNEL, date=date, api_kwargs=api_kwargs) with self._unfrozen(): self.chat: Chat = chat self.message_id: int = message_id self.author_signature: Optional[str] = author_signature