diff --git a/lib/telegram/__init__.py b/lib/telegram/__init__.py deleted file mode 100644 index b3dffe97..00000000 --- a/lib/telegram/__init__.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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/]. - -"""A library that provides a Python interface to the Telegram Bot API""" - -__author__ = 'leandrotoledodesouza@gmail.com' -__version__ = '2.8.7' - -from .base import TelegramObject -from .user import User -from .groupchat import GroupChat -from .photosize import PhotoSize -from .audio import Audio -from .voice import Voice -from .document import Document -from .sticker import Sticker -from .video import Video -from .contact import Contact -from .location import Location -from .chataction import ChatAction -from .userprofilephotos import UserProfilePhotos -from .replymarkup import ReplyMarkup -from .replykeyboardmarkup import ReplyKeyboardMarkup -from .replykeyboardhide import ReplyKeyboardHide -from .forcereply import ForceReply -from .error import TelegramError -from .inputfile import InputFile -from .file import File -from .nullhandler import NullHandler -from .emoji import Emoji -from .parsemode import ParseMode -from .message import Message -from .update import Update -from .bot import Bot - -__all__ = ['Bot', 'Emoji', 'TelegramError', 'InputFile', 'ReplyMarkup', - 'ForceReply', 'ReplyKeyboardHide', 'ReplyKeyboardMarkup', - 'UserProfilePhotos', 'ChatAction', 'Location', 'Contact', - 'Video', 'Sticker', 'Document', 'File', 'Audio', 'PhotoSize', - 'GroupChat', 'Update', 'ParseMode', 'Message', 'User', - 'TelegramObject', 'NullHandler', 'Voice'] diff --git a/lib/telegram/audio.py b/lib/telegram/audio.py deleted file mode 100644 index c7a669d3..00000000 --- a/lib/telegram/audio.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram Audio""" - -from telegram import TelegramObject - - -class Audio(TelegramObject): - """This object represents a Telegram Audio. - - Attributes: - file_id (str): - duration (int): - performer (str): - title (str): - mime_type (str): - file_size (int): - - Args: - file_id (str): - duration (int): - **kwargs: Arbitrary keyword arguments. - - Keyword Args: - performer (Optional[str]): - title (Optional[str]): - mime_type (Optional[str]): - file_size (Optional[int]): - """ - - def __init__(self, - file_id, - duration, - **kwargs): - # Required - self.file_id = str(file_id) - self.duration = int(duration) - # Optionals - self.performer = kwargs.get('performer', '') - self.title = kwargs.get('title', '') - self.mime_type = str(kwargs.get('mime_type', '')) - self.file_size = int(kwargs.get('file_size', 0)) - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.Audio: - """ - if not data: - return None - - return Audio(**data) diff --git a/lib/telegram/base.py b/lib/telegram/base.py deleted file mode 100644 index ac0deac0..00000000 --- a/lib/telegram/base.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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/]. - -"""Base class for Telegram Objects""" - -import json -from abc import ABCMeta - - -class TelegramObject(object): - """Base class for most telegram objects""" - - __metaclass__ = ABCMeta - - def __str__(self): - return str(self.to_dict()) - - def __getitem__(self, item): - return self.__dict__[item] - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.TelegramObject: - """ - raise NotImplementedError - - def to_json(self): - """ - Returns: - str: - """ - return json.dumps(self.to_dict()) - - def to_dict(self): - """ - Returns: - dict: - """ - data = dict() - - for key, value in self.__dict__.items(): - if value: - if hasattr(value, 'to_dict'): - data[key] = value.to_dict() - else: - data[key] = value - - return data diff --git a/lib/telegram/bot.py b/lib/telegram/bot.py deleted file mode 100644 index 3805335b..00000000 --- a/lib/telegram/bot.py +++ /dev/null @@ -1,741 +0,0 @@ -#!/usr/bin/env python -# pylint: disable=E0611,E0213,E1102,C0103,E1101,W0613,R0913,R0904 -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram Bot""" - -import functools -import logging - -from telegram import (User, Message, Update, UserProfilePhotos, File, - TelegramError, ReplyMarkup, TelegramObject, NullHandler) -from telegram.utils import request - -H = NullHandler() -logging.getLogger(__name__).addHandler(H) - - -class Bot(TelegramObject): - - """This object represents a Telegram Bot. - - Attributes: - id (int): - first_name (str): - last_name (str): - username (str): - name (str): - - Args: - token (str): - **kwargs: Arbitrary keyword arguments. - - Keyword Args: - base_url (Optional[str]): - """ - - def __init__(self, - token, - base_url=None): - self.token = token - - if base_url is None: - self.base_url = 'https://api.telegram.org/bot%s' % self.token - else: - self.base_url = base_url + self.token - - self.base_file_url = 'https://api.telegram.org/file/bot%s' % self.token - - self.bot = None - - self.logger = logging.getLogger(__name__) - - def info(func): - """ - Returns: - """ - @functools.wraps(func) - def decorator(self, *args, **kwargs): - """ - decorator - """ - if not self.bot: - self.getMe() - - result = func(self, *args, **kwargs) - return result - return decorator - - @property - @info - def id(self): - """int: """ - return self.bot.id - - @property - @info - def first_name(self): - """str: """ - return self.bot.first_name - - @property - @info - def last_name(self): - """str: """ - return self.bot.last_name - - @property - @info - def username(self): - """str: """ - return self.bot.username - - @property - def name(self): - """str: """ - return '@%s' % self.username - - def log(func): - """ - Returns: - A telegram.Message instance representing the message posted. - """ - logger = logging.getLogger(func.__module__) - - @functools.wraps(func) - def decorator(self, *args, **kwargs): - """ - decorator - """ - logger.debug('Entering: %s', func.__name__) - result = func(self, *args, **kwargs) - logger.debug(result) - logger.debug('Exiting: %s', func.__name__) - return result - return decorator - - def message(func): - """ - Returns: - A telegram.Message instance representing the message posted. - """ - @functools.wraps(func) - def decorator(self, *args, **kwargs): - """ - decorator - """ - url, data = func(self, *args, **kwargs) - - if not data.get('chat_id'): - raise TelegramError('Invalid chat_id') - - if kwargs.get('reply_to_message_id'): - reply_to_message_id = kwargs.get('reply_to_message_id') - data['reply_to_message_id'] = reply_to_message_id - - if kwargs.get('reply_markup'): - reply_markup = kwargs.get('reply_markup') - if isinstance(reply_markup, ReplyMarkup): - data['reply_markup'] = reply_markup.to_json() - else: - data['reply_markup'] = reply_markup - - result = request.post(url, data) - - if result is True: - return result - - return Message.de_json(result) - return decorator - - @log - def getMe(self): - """A simple method for testing your bot's auth token. - - Returns: - A telegram.User instance representing that bot if the - credentials are valid, None otherwise. - """ - url = '%s/getMe' % self.base_url - - result = request.get(url) - - self.bot = User.de_json(result) - - return self.bot - - @log - @message - def sendMessage(self, - chat_id, - text, - parse_mode=None, - disable_web_page_preview=None, - **kwargs): - """Use this method to send text messages. - - Args: - chat_id: - Unique identifier for the message recipient - telegram.User or - telegram.GroupChat id. - parse_mode: - Send Markdown, if you want Telegram apps to show bold, italic and - inline URLs in your bot's message. For the moment, only Telegram - for Android supports this. [Optional] - text: - Text of the message to be sent. - disable_web_page_preview: - Disables link previews for links in this message. [Optional] - reply_to_message_id: - If the message is a reply, ID of the original message. [Optional] - reply_markup: - Additional interface options. A JSON-serialized object for a custom - reply keyboard, instructions to hide keyboard or to force a reply - from the user. [Optional] - - Returns: - A telegram.Message instance representing the message posted. - """ - - url = '%s/sendMessage' % self.base_url - - data = {'chat_id': chat_id, - 'text': text} - - if parse_mode: - data['parse_mode'] = parse_mode - if disable_web_page_preview: - data['disable_web_page_preview'] = disable_web_page_preview - - return url, data - - @log - @message - def forwardMessage(self, - chat_id, - from_chat_id, - message_id): - """Use this method to forward messages of any kind. - - Args: - chat_id: - Unique identifier for the message recipient - User or GroupChat id. - from_chat_id: - Unique identifier for the chat where the original message was sent - - User or GroupChat id. - message_id: - Unique message identifier. - - Returns: - A telegram.Message instance representing the message forwarded. - """ - - url = '%s/forwardMessage' % self.base_url - - data = {} - if chat_id: - data['chat_id'] = chat_id - if from_chat_id: - data['from_chat_id'] = from_chat_id - if message_id: - data['message_id'] = message_id - - return url, data - - @log - @message - def sendPhoto(self, - chat_id, - photo, - caption=None, - **kwargs): - """Use this method to send photos. - - Args: - chat_id: - Unique identifier for the message recipient - User or GroupChat id. - photo: - Photo to send. You can either pass a file_id as String to resend a - photo that is already on the Telegram servers, or upload a new - photo using multipart/form-data. - caption: - Photo caption (may also be used when resending photos by file_id). - [Optional] - reply_to_message_id: - If the message is a reply, ID of the original message. [Optional] - reply_markup: - Additional interface options. A JSON-serialized object for a custom - reply keyboard, instructions to hide keyboard or to force a reply - from the user. [Optional] - - Returns: - A telegram.Message instance representing the message posted. - """ - - url = '%s/sendPhoto' % self.base_url - - data = {'chat_id': chat_id, - 'photo': photo} - - if caption: - data['caption'] = caption - - return url, data - - @log - @message - def sendAudio(self, - chat_id, - audio, - duration=None, - performer=None, - title=None, - **kwargs): - """Use this method to send audio files, if you want Telegram clients to - display them in the music player. Your audio must be in an .mp3 format. - On success, the sent Message is returned. Bots can currently send audio - files of up to 50 MB in size, this limit may be changed in the future. - - For backward compatibility, when both fields title and description are - empty and mime-type of the sent file is not "audio/mpeg", file is sent - as playable voice message. In this case, your audio must be in an .ogg - file encoded with OPUS. This will be removed in the future. You need to - use sendVoice method instead. - - Args: - chat_id: - Unique identifier for the message recipient - User or GroupChat id. - audio: - Audio file to send. You can either pass a file_id as String to - resend an audio that is already on the Telegram servers, or upload - a new audio file using multipart/form-data. - duration: - Duration of sent audio in seconds. [Optional] - performer: - Performer of sent audio. [Optional] - title: - Title of sent audio. [Optional] - reply_to_message_id: - If the message is a reply, ID of the original message. [Optional] - reply_markup: - Additional interface options. A JSON-serialized object for a - custom reply keyboard, instructions to hide keyboard or to force a - reply from the user. [Optional] - - Returns: - A telegram.Message instance representing the message posted. - """ - - url = '%s/sendAudio' % self.base_url - - data = {'chat_id': chat_id, - 'audio': audio} - - if duration: - data['duration'] = duration - if performer: - data['performer'] = performer - if title: - data['title'] = title - - return url, data - - @log - @message - def sendDocument(self, - chat_id, - document, - filename=None, - **kwargs): - """Use this method to send general files. - - Args: - chat_id: - Unique identifier for the message recipient - User or GroupChat id. - document: - File to send. You can either pass a file_id as String to resend a - file that is already on the Telegram servers, or upload a new file - using multipart/form-data. - filename: - File name that shows in telegram message (it is usefull when you - send file generated by temp module, for example). [Optional] - reply_to_message_id: - If the message is a reply, ID of the original message. [Optional] - reply_markup: - Additional interface options. A JSON-serialized object for a - custom reply keyboard, instructions to hide keyboard or to force a - reply from the user. [Optional] - - Returns: - A telegram.Message instance representing the message posted. - """ - - url = '%s/sendDocument' % self.base_url - - data = {'chat_id': chat_id, - 'document': document} - - if filename: - data['filename'] = filename - - return url, data - - @log - @message - def sendSticker(self, - chat_id, - sticker, - **kwargs): - """Use this method to send .webp stickers. - - Args: - chat_id: - Unique identifier for the message recipient - User or GroupChat id. - sticker: - Sticker to send. You can either pass a file_id as String to resend - a sticker that is already on the Telegram servers, or upload a new - sticker using multipart/form-data. - reply_to_message_id: - If the message is a reply, ID of the original message. [Optional] - reply_markup: - Additional interface options. A JSON-serialized object for a - custom reply keyboard, instructions to hide keyboard or to force a - reply from the user. [Optional] - - Returns: - A telegram.Message instance representing the message posted. - """ - - url = '%s/sendSticker' % self.base_url - - data = {'chat_id': chat_id, - 'sticker': sticker} - - return url, data - - @log - @message - def sendVideo(self, - chat_id, - video, - duration=None, - caption=None, - **kwargs): - """Use this method to send video files, Telegram clients support mp4 - videos (other formats may be sent as telegram.Document). - - Args: - chat_id: - Unique identifier for the message recipient - User or GroupChat id. - video: - Video to send. You can either pass a file_id as String to resend a - video that is already on the Telegram servers, or upload a new - video file using multipart/form-data. - duration: - Duration of sent video in seconds. [Optional] - caption: - Video caption (may also be used when resending videos by file_id). - [Optional] - reply_to_message_id: - If the message is a reply, ID of the original message. [Optional] - reply_markup: - Additional interface options. A JSON-serialized object for a - custom reply keyboard, instructions to hide keyboard or to force a - reply from the user. [Optional] - - Returns: - A telegram.Message instance representing the message posted. - """ - - url = '%s/sendVideo' % self.base_url - - data = {'chat_id': chat_id, - 'video': video} - - if duration: - data['duration'] = duration - if caption: - data['caption'] = caption - - return url, data - - @log - @message - def sendVoice(self, - chat_id, - voice, - duration=None, - **kwargs): - """Use this method to send audio files, if you want Telegram clients to - display the file as a playable voice message. For this to work, your - audio must be in an .ogg file encoded with OPUS (other formats may be - sent as Audio or Document). On success, the sent Message is returned. - Bots can currently send audio files of up to 50 MB in size, this limit - may be changed in the future. - - Args: - chat_id: - Unique identifier for the message recipient - User or GroupChat id. - voice: - Audio file to send. You can either pass a file_id as String to - resend an audio that is already on the Telegram servers, or upload - a new audio file using multipart/form-data. - duration: - Duration of sent audio in seconds. [Optional] - reply_to_message_id: - If the message is a reply, ID of the original message. [Optional] - reply_markup: - Additional interface options. A JSON-serialized object for a - custom reply keyboard, instructions to hide keyboard or to force a - reply from the user. [Optional] - - Returns: - A telegram.Message instance representing the message posted. - """ - - url = '%s/sendVoice' % self.base_url - - data = {'chat_id': chat_id, - 'voice': voice} - - if duration: - data['duration'] = duration - - return url, data - - @log - @message - def sendLocation(self, - chat_id, - latitude, - longitude, - **kwargs): - """Use this method to send point on the map. - - Args: - chat_id: - Unique identifier for the message recipient - User or GroupChat id. - latitude: - Latitude of location. - longitude: - Longitude of location. - reply_to_message_id: - If the message is a reply, ID of the original message. [Optional] - reply_markup: - Additional interface options. A JSON-serialized object for a - custom reply keyboard, instructions to hide keyboard or to force a - reply from the user. [Optional] - - Returns: - A telegram.Message instance representing the message posted. - """ - - url = '%s/sendLocation' % self.base_url - - data = {'chat_id': chat_id, - 'latitude': latitude, - 'longitude': longitude} - - return url, data - - @log - @message - def sendChatAction(self, - chat_id, - action): - """Use this method when you need to tell the user that something is - happening on the bot's side. The status is set for 5 seconds or less - (when a message arrives from your bot, Telegram clients clear its - typing status). - - Args: - chat_id: - Unique identifier for the message recipient - User or GroupChat id. - action: - Type of action to broadcast. Choose one, depending on what the user - is about to receive: - - ChatAction.TYPING for text messages, - - ChatAction.UPLOAD_PHOTO for photos, - - ChatAction.UPLOAD_VIDEO for videos, - - ChatAction.UPLOAD_AUDIO for audio files, - - ChatAction.UPLOAD_DOCUMENT for general files, - - ChatAction.FIND_LOCATION for location data. - """ - - url = '%s/sendChatAction' % self.base_url - - data = {'chat_id': chat_id, - 'action': action} - - return url, data - - @log - def getUserProfilePhotos(self, - user_id, - offset=None, - limit=100): - """Use this method to get a list of profile pictures for a user. - - Args: - user_id: - Unique identifier of the target user. - offset: - Sequential number of the first photo to be returned. By default, - all photos are returned. [Optional] - limit: - Limits the number of photos to be retrieved. Values between 1-100 - are accepted. Defaults to 100. [Optional] - - Returns: - Returns a telegram.UserProfilePhotos object. - """ - - url = '%s/getUserProfilePhotos' % self.base_url - - data = {'user_id': user_id} - - if offset: - data['offset'] = offset - if limit: - data['limit'] = limit - - result = request.post(url, data) - - return UserProfilePhotos.de_json(result) - - @log - def getFile(self, - file_id): - """Use this method to get basic info about a file and prepare it for - downloading. For the moment, bots can download files of up to 20MB in - size. - - Args: - file_id: - File identifier to get info about. - - Returns: - Returns a telegram.File object - """ - - url = '%s/getFile' % self.base_url - - data = {'file_id': file_id} - - result = request.post(url, data) - - if result.get('file_path'): - result['file_path'] = '%s/%s' % (self.base_file_url, - result['file_path']) - - return File.de_json(result) - - @log - def getUpdates(self, - offset=None, - limit=100, - timeout=0): - """Use this method to receive incoming updates using long polling. - - Args: - offset: - Identifier of the first update to be returned. Must be greater by - one than the highest among the identifiers of previously received - updates. By default, updates starting with the earliest unconfirmed - update are returned. An update is considered confirmed as soon as - getUpdates is called with an offset higher than its update_id. - limit: - Limits the number of updates to be retrieved. Values between 1-100 - are accepted. Defaults to 100. - timeout: - Timeout in seconds for long polling. Defaults to 0, i.e. usual - short polling. - - Returns: - A list of telegram.Update objects are returned. - """ - - url = '%s/getUpdates' % self.base_url - - data = {} - if offset: - data['offset'] = offset - if limit: - data['limit'] = limit - if timeout: - data['timeout'] = timeout - - result = request.post(url, data) - - if result: - self.logger.info( - 'Getting updates: %s', [u['update_id'] for u in result]) - else: - self.logger.info('No new updates found.') - - return [Update.de_json(x) for x in result] - - @log - def setWebhook(self, - webhook_url=None, - certificate=None): - """Use this method to specify a url and receive incoming updates via an - outgoing webhook. Whenever there is an update for the bot, we will send - an HTTPS POST request to the specified url, containing a - JSON-serialized Update. In case of an unsuccessful request, we will - give up after a reasonable amount of attempts. - - Args: - url: - HTTPS url to send updates to. - Use an empty string to remove webhook integration - - Returns: - True if successful else TelegramError was raised - """ - url = '%s/setWebhook' % self.base_url - - data = {} - if webhook_url: - data['url'] = webhook_url - if certificate: - data['certificate'] = certificate - - result = request.post(url, data) - - return result - - @staticmethod - def de_json(data): - pass - - def to_dict(self): - """ - Returns: - dict: - """ - data = {'id': self.id, - 'username': self.username, - 'first_name': self.username} - if self.last_name: - data['last_name'] = self.last_name - return data - - def __reduce__(self): - return (self.__class__, (self.token, - self.base_url.replace(self.token, ''))) diff --git a/lib/telegram/chataction.py b/lib/telegram/chataction.py deleted file mode 100644 index fce7e418..00000000 --- a/lib/telegram/chataction.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python -# pylint: disable=R0903 -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram ChatAction""" - - -class ChatAction(object): - """This object represents a Telegram ChatAction.""" - - TYPING = 'typing' - UPLOAD_PHOTO = 'upload_photo' - RECORD_VIDEO = 'record_video' - UPLOAD_VIDEO = 'upload_video' - RECORD_AUDIO = 'record_audio' - UPLOAD_AUDIO = 'upload_audio' - UPLOAD_DOCUMENT = 'upload_document' - FIND_LOCATION = 'find_location' diff --git a/lib/telegram/contact.py b/lib/telegram/contact.py deleted file mode 100644 index 3b9e2b10..00000000 --- a/lib/telegram/contact.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram Contact""" - -from telegram import TelegramObject - - -class Contact(TelegramObject): - """This object represents a Telegram Contact. - - Attributes: - phone_number (str): - first_name (str): - last_name (str): - user_id (int): - - Args: - phone_number (str): - first_name (str): - **kwargs: Arbitrary keyword arguments. - - Keyword Args: - last_name (Optional[str]): - user_id (Optional[int]): - """ - - def __init__(self, - phone_number, - first_name, - **kwargs): - # Required - self.phone_number = str(phone_number) - self.first_name = first_name - # Optionals - self.last_name = kwargs.get('last_name', '') - self.user_id = int(kwargs.get('user_id', 0)) - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.Contact: - """ - if not data: - return None - - return Contact(**data) diff --git a/lib/telegram/document.py b/lib/telegram/document.py deleted file mode 100644 index d492774d..00000000 --- a/lib/telegram/document.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram Document""" - -from telegram import PhotoSize, TelegramObject - - -class Document(TelegramObject): - """This object represents a Telegram Document. - - Attributes: - file_id (str): - thumb (:class:`telegram.PhotoSize`): - file_name (str): - mime_type (str): - file_size (int): - - Args: - file_id (str): - **kwargs: Arbitrary keyword arguments. - - Keyword Args: - thumb (Optional[:class:`telegram.PhotoSize`]): - file_name (Optional[str]): - mime_type (Optional[str]): - file_size (Optional[int]): - """ - - def __init__(self, - file_id, - **kwargs): - # Required - self.file_id = str(file_id) - # Optionals - self.thumb = kwargs.get('thumb') - self.file_name = kwargs.get('file_name', '') - self.mime_type = str(kwargs.get('mime_type', '')) - self.file_size = int(kwargs.get('file_size', 0)) - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.Document: - """ - if not data: - return None - - data['thumb'] = PhotoSize.de_json(data.get('thumb')) - - return Document(**data) diff --git a/lib/telegram/emoji.py b/lib/telegram/emoji.py deleted file mode 100644 index ee10651a..00000000 --- a/lib/telegram/emoji.py +++ /dev/null @@ -1,878 +0,0 @@ -#!/usr/bin/env python -# flake8: noqa -# pylint: disable=C0103,C0301,R0903 -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents an Emoji""" - - -class Emoji(object): - """This object represents an Emoji.""" - - GRINNING_FACE_WITH_SMILING_EYES = b'\xF0\x9F\x98\x81' - FACE_WITH_TEARS_OF_JOY = b'\xF0\x9F\x98\x82' - SMILING_FACE_WITH_OPEN_MOUTH = b'\xF0\x9F\x98\x83' - SMILING_FACE_WITH_OPEN_MOUTH_AND_SMILING_EYES = b'\xF0\x9F\x98\x84' - SMILING_FACE_WITH_OPEN_MOUTH_AND_COLD_SWEAT = b'\xF0\x9F\x98\x85' - SMILING_FACE_WITH_OPEN_MOUTH_AND_TIGHTLY_CLOSED_EYES = b'\xF0\x9F\x98\x86' - WINKING_FACE = b'\xF0\x9F\x98\x89' - SMILING_FACE_WITH_SMILING_EYES = b'\xF0\x9F\x98\x8A' - FACE_SAVOURING_DELICIOUS_FOOD = b'\xF0\x9F\x98\x8B' - RELIEVED_FACE = b'\xF0\x9F\x98\x8C' - SMILING_FACE_WITH_HEART_SHAPED_EYES = b'\xF0\x9F\x98\x8D' - SMIRKING_FACE = b'\xF0\x9F\x98\x8F' - UNAMUSED_FACE = b'\xF0\x9F\x98\x92' - FACE_WITH_COLD_SWEAT = b'\xF0\x9F\x98\x93' - PENSIVE_FACE = b'\xF0\x9F\x98\x94' - CONFOUNDED_FACE = b'\xF0\x9F\x98\x96' - FACE_THROWING_A_KISS = b'\xF0\x9F\x98\x98' - KISSING_FACE_WITH_CLOSED_EYES = b'\xF0\x9F\x98\x9A' - FACE_WITH_STUCK_OUT_TONGUE_AND_WINKING_EYE = b'\xF0\x9F\x98\x9C' - FACE_WITH_STUCK_OUT_TONGUE_AND_TIGHTLY_CLOSED_EYES = b'\xF0\x9F\x98\x9D' - DISAPPOINTED_FACE = b'\xF0\x9F\x98\x9E' - ANGRY_FACE = b'\xF0\x9F\x98\xA0' - POUTING_FACE = b'\xF0\x9F\x98\xA1' - CRYING_FACE = b'\xF0\x9F\x98\xA2' - PERSEVERING_FACE = b'\xF0\x9F\x98\xA3' - FACE_WITH_LOOK_OF_TRIUMPH = b'\xF0\x9F\x98\xA4' - DISAPPOINTED_BUT_RELIEVED_FACE = b'\xF0\x9F\x98\xA5' - FEARFUL_FACE = b'\xF0\x9F\x98\xA8' - WEARY_FACE = b'\xF0\x9F\x98\xA9' - SLEEPY_FACE = b'\xF0\x9F\x98\xAA' - TIRED_FACE = b'\xF0\x9F\x98\xAB' - LOUDLY_CRYING_FACE = b'\xF0\x9F\x98\xAD' - FACE_WITH_OPEN_MOUTH_AND_COLD_SWEAT = b'\xF0\x9F\x98\xB0' - FACE_SCREAMING_IN_FEAR = b'\xF0\x9F\x98\xB1' - ASTONISHED_FACE = b'\xF0\x9F\x98\xB2' - FLUSHED_FACE = b'\xF0\x9F\x98\xB3' - DIZZY_FACE = b'\xF0\x9F\x98\xB5' - FACE_WITH_MEDICAL_MASK = b'\xF0\x9F\x98\xB7' - GRINNING_CAT_FACE_WITH_SMILING_EYES = b'\xF0\x9F\x98\xB8' - CAT_FACE_WITH_TEARS_OF_JOY = b'\xF0\x9F\x98\xB9' - SMILING_CAT_FACE_WITH_OPEN_MOUTH = b'\xF0\x9F\x98\xBA' - SMILING_CAT_FACE_WITH_HEART_SHAPED_EYES = b'\xF0\x9F\x98\xBB' - CAT_FACE_WITH_WRY_SMILE = b'\xF0\x9F\x98\xBC' - KISSING_CAT_FACE_WITH_CLOSED_EYES = b'\xF0\x9F\x98\xBD' - POUTING_CAT_FACE = b'\xF0\x9F\x98\xBE' - CRYING_CAT_FACE = b'\xF0\x9F\x98\xBF' - WEARY_CAT_FACE = b'\xF0\x9F\x99\x80' - FACE_WITH_NO_GOOD_GESTURE = b'\xF0\x9F\x99\x85' - FACE_WITH_OK_GESTURE = b'\xF0\x9F\x99\x86' - PERSON_BOWING_DEEPLY = b'\xF0\x9F\x99\x87' - SEE_NO_EVIL_MONKEY = b'\xF0\x9F\x99\x88' - HEAR_NO_EVIL_MONKEY = b'\xF0\x9F\x99\x89' - SPEAK_NO_EVIL_MONKEY = b'\xF0\x9F\x99\x8A' - HAPPY_PERSON_RAISING_ONE_HAND = b'\xF0\x9F\x99\x8B' - PERSON_RAISING_BOTH_HANDS_IN_CELEBRATION = b'\xF0\x9F\x99\x8C' - PERSON_FROWNING = b'\xF0\x9F\x99\x8D' - PERSON_WITH_POUTING_FACE = b'\xF0\x9F\x99\x8E' - PERSON_WITH_FOLDED_HANDS = b'\xF0\x9F\x99\x8F' - BLACK_SCISSORS = b'\xE2\x9C\x82' - WHITE_HEAVY_CHECK_MARK = b'\xE2\x9C\x85' - AIRPLANE = b'\xE2\x9C\x88' - ENVELOPE = b'\xE2\x9C\x89' - RAISED_FIST = b'\xE2\x9C\x8A' - RAISED_HAND = b'\xE2\x9C\x8B' - VICTORY_HAND = b'\xE2\x9C\x8C' - PENCIL = b'\xE2\x9C\x8F' - BLACK_NIB = b'\xE2\x9C\x92' - HEAVY_CHECK_MARK = b'\xE2\x9C\x94' - HEAVY_MULTIPLICATION_X = b'\xE2\x9C\x96' - SPARKLES = b'\xE2\x9C\xA8' - EIGHT_SPOKED_ASTERISK = b'\xE2\x9C\xB3' - EIGHT_POINTED_BLACK_STAR = b'\xE2\x9C\xB4' - SNOWFLAKE = b'\xE2\x9D\x84' - SPARKLE = b'\xE2\x9D\x87' - CROSS_MARK = b'\xE2\x9D\x8C' - NEGATIVE_SQUARED_CROSS_MARK = b'\xE2\x9D\x8E' - BLACK_QUESTION_MARK_ORNAMENT = b'\xE2\x9D\x93' - WHITE_QUESTION_MARK_ORNAMENT = b'\xE2\x9D\x94' - WHITE_EXCLAMATION_MARK_ORNAMENT = b'\xE2\x9D\x95' - HEAVY_EXCLAMATION_MARK_SYMBOL = b'\xE2\x9D\x97' - HEAVY_BLACK_HEART = b'\xE2\x9D\xA4' - HEAVY_PLUS_SIGN = b'\xE2\x9E\x95' - HEAVY_MINUS_SIGN = b'\xE2\x9E\x96' - HEAVY_DIVISION_SIGN = b'\xE2\x9E\x97' - BLACK_RIGHTWARDS_ARROW = b'\xE2\x9E\xA1' - CURLY_LOOP = b'\xE2\x9E\xB0' - ROCKET = b'\xF0\x9F\x9A\x80' - RAILWAY_CAR = b'\xF0\x9F\x9A\x83' - HIGH_SPEED_TRAIN = b'\xF0\x9F\x9A\x84' - HIGH_SPEED_TRAIN_WITH_BULLET_NOSE = b'\xF0\x9F\x9A\x85' - METRO = b'\xF0\x9F\x9A\x87' - STATION = b'\xF0\x9F\x9A\x89' - BUS = b'\xF0\x9F\x9A\x8C' - BUS_STOP = b'\xF0\x9F\x9A\x8F' - AMBULANCE = b'\xF0\x9F\x9A\x91' - FIRE_ENGINE = b'\xF0\x9F\x9A\x92' - POLICE_CAR = b'\xF0\x9F\x9A\x93' - TAXI = b'\xF0\x9F\x9A\x95' - AUTOMOBILE = b'\xF0\x9F\x9A\x97' - RECREATIONAL_VEHICLE = b'\xF0\x9F\x9A\x99' - DELIVERY_TRUCK = b'\xF0\x9F\x9A\x9A' - SHIP = b'\xF0\x9F\x9A\xA2' - SPEEDBOAT = b'\xF0\x9F\x9A\xA4' - HORIZONTAL_TRAFFIC_LIGHT = b'\xF0\x9F\x9A\xA5' - CONSTRUCTION_SIGN = b'\xF0\x9F\x9A\xA7' - POLICE_CARS_REVOLVING_LIGHT = b'\xF0\x9F\x9A\xA8' - TRIANGULAR_FLAG_ON_POST = b'\xF0\x9F\x9A\xA9' - DOOR = b'\xF0\x9F\x9A\xAA' - NO_ENTRY_SIGN = b'\xF0\x9F\x9A\xAB' - SMOKING_SYMBOL = b'\xF0\x9F\x9A\xAC' - NO_SMOKING_SYMBOL = b'\xF0\x9F\x9A\xAD' - BICYCLE = b'\xF0\x9F\x9A\xB2' - PEDESTRIAN = b'\xF0\x9F\x9A\xB6' - MENS_SYMBOL = b'\xF0\x9F\x9A\xB9' - WOMENS_SYMBOL = b'\xF0\x9F\x9A\xBA' - RESTROOM = b'\xF0\x9F\x9A\xBB' - BABY_SYMBOL = b'\xF0\x9F\x9A\xBC' - TOILET = b'\xF0\x9F\x9A\xBD' - WATER_CLOSET = b'\xF0\x9F\x9A\xBE' - BATH = b'\xF0\x9F\x9B\x80' - CIRCLED_LATIN_CAPITAL_LETTER_M = b'\xE2\x93\x82' - NEGATIVE_SQUARED_LATIN_CAPITAL_LETTER_A = b'\xF0\x9F\x85\xB0' - NEGATIVE_SQUARED_LATIN_CAPITAL_LETTER_B = b'\xF0\x9F\x85\xB1' - NEGATIVE_SQUARED_LATIN_CAPITAL_LETTER_O = b'\xF0\x9F\x85\xBE' - NEGATIVE_SQUARED_LATIN_CAPITAL_LETTER_P = b'\xF0\x9F\x85\xBF' - NEGATIVE_SQUARED_AB = b'\xF0\x9F\x86\x8E' - SQUARED_CL = b'\xF0\x9F\x86\x91' - SQUARED_COOL = b'\xF0\x9F\x86\x92' - SQUARED_FREE = b'\xF0\x9F\x86\x93' - SQUARED_ID = b'\xF0\x9F\x86\x94' - SQUARED_NEW = b'\xF0\x9F\x86\x95' - SQUARED_NG = b'\xF0\x9F\x86\x96' - SQUARED_OK = b'\xF0\x9F\x86\x97' - SQUARED_SOS = b'\xF0\x9F\x86\x98' - SQUARED_UP_WITH_EXCLAMATION_MARK = b'\xF0\x9F\x86\x99' - SQUARED_VS = b'\xF0\x9F\x86\x9A' - REGIONAL_INDICATOR_SYMBOL_LETTER_D_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_E\ - = b'\xF0\x9F\x87\xA9\xF0\x9F\x87\xAA' - REGIONAL_INDICATOR_SYMBOL_LETTER_G_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_B\ - = b'\xF0\x9F\x87\xAC\xF0\x9F\x87\xA7' - REGIONAL_INDICATOR_SYMBOL_LETTER_C_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_N\ - = b'\xF0\x9F\x87\xA8\xF0\x9F\x87\xB3' - REGIONAL_INDICATOR_SYMBOL_LETTER_J_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_P\ - = b'\xF0\x9F\x87\xAF\xF0\x9F\x87\xB5' - REGIONAL_INDICATOR_SYMBOL_LETTER_K_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_R\ - = b'\xF0\x9F\x87\xB0\xF0\x9F\x87\xB7' - REGIONAL_INDICATOR_SYMBOL_LETTER_F_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_R\ - = b'\xF0\x9F\x87\xAB\xF0\x9F\x87\xB7' - REGIONAL_INDICATOR_SYMBOL_LETTER_E_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_S\ - = b'\xF0\x9F\x87\xAA\xF0\x9F\x87\xB8' - REGIONAL_INDICATOR_SYMBOL_LETTER_I_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_T\ - = b'\xF0\x9F\x87\xAE\xF0\x9F\x87\xB9' - REGIONAL_INDICATOR_SYMBOL_LETTER_U_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_S\ - = b'\xF0\x9F\x87\xBA\xF0\x9F\x87\xB8' - REGIONAL_INDICATOR_SYMBOL_LETTER_R_PLUS_REGIONAL_INDICATOR_SYMBOL_LETTER_U\ - = b'\xF0\x9F\x87\xB7\xF0\x9F\x87\xBA' - SQUARED_KATAKANA_KOKO = b'\xF0\x9F\x88\x81' - SQUARED_KATAKANA_SA = b'\xF0\x9F\x88\x82' - SQUARED_CJK_UNIFIED_IDEOGRAPH_7121 = b'\xF0\x9F\x88\x9A' - SQUARED_CJK_UNIFIED_IDEOGRAPH_6307 = b'\xF0\x9F\x88\xAF' - SQUARED_CJK_UNIFIED_IDEOGRAPH_7981 = b'\xF0\x9F\x88\xB2' - SQUARED_CJK_UNIFIED_IDEOGRAPH_7A7A = b'\xF0\x9F\x88\xB3' - SQUARED_CJK_UNIFIED_IDEOGRAPH_5408 = b'\xF0\x9F\x88\xB4' - SQUARED_CJK_UNIFIED_IDEOGRAPH_6E80 = b'\xF0\x9F\x88\xB5' - SQUARED_CJK_UNIFIED_IDEOGRAPH_6709 = b'\xF0\x9F\x88\xB6' - SQUARED_CJK_UNIFIED_IDEOGRAPH_6708 = b'\xF0\x9F\x88\xB7' - SQUARED_CJK_UNIFIED_IDEOGRAPH_7533 = b'\xF0\x9F\x88\xB8' - SQUARED_CJK_UNIFIED_IDEOGRAPH_5272 = b'\xF0\x9F\x88\xB9' - SQUARED_CJK_UNIFIED_IDEOGRAPH_55B6 = b'\xF0\x9F\x88\xBA' - CIRCLED_IDEOGRAPH_ADVANTAGE = b'\xF0\x9F\x89\x90' - CIRCLED_IDEOGRAPH_ACCEPT = b'\xF0\x9F\x89\x91' - COPYRIGHT_SIGN = b'\xC2\xA9' - REGISTERED_SIGN = b'\xC2\xAE' - DOUBLE_EXCLAMATION_MARK = b'\xE2\x80\xBC' - EXCLAMATION_QUESTION_MARK = b'\xE2\x81\x89' - DIGIT_EIGHT_PLUS_COMBINING_ENCLOSING_KEYCAP = b'\x38\xE2\x83\xA3' - DIGIT_NINE_PLUS_COMBINING_ENCLOSING_KEYCAP = b'\x39\xE2\x83\xA3' - DIGIT_SEVEN_PLUS_COMBINING_ENCLOSING_KEYCAP = b'\x37\xE2\x83\xA3' - DIGIT_SIX_PLUS_COMBINING_ENCLOSING_KEYCAP = b'\x36\xE2\x83\xA3' - DIGIT_ONE_PLUS_COMBINING_ENCLOSING_KEYCAP = b'\x31\xE2\x83\xA3' - DIGIT_ZERO_PLUS_COMBINING_ENCLOSING_KEYCAP = b'\x30\xE2\x83\xA3' - DIGIT_TWO_PLUS_COMBINING_ENCLOSING_KEYCAP = b'\x32\xE2\x83\xA3' - DIGIT_THREE_PLUS_COMBINING_ENCLOSING_KEYCAP = b'\x33\xE2\x83\xA3' - DIGIT_FIVE_PLUS_COMBINING_ENCLOSING_KEYCAP = b'\x35\xE2\x83\xA3' - DIGIT_FOUR_PLUS_COMBINING_ENCLOSING_KEYCAP = b'\x34\xE2\x83\xA3' - NUMBER_SIGN_PLUS_COMBINING_ENCLOSING_KEYCAP = b'\x23\xE2\x83\xA3' - TRADE_MARK_SIGN = b'\xE2\x84\xA2' - INFORMATION_SOURCE = b'\xE2\x84\xB9' - LEFT_RIGHT_ARROW = b'\xE2\x86\x94' - UP_DOWN_ARROW = b'\xE2\x86\x95' - NORTH_WEST_ARROW = b'\xE2\x86\x96' - NORTH_EAST_ARROW = b'\xE2\x86\x97' - SOUTH_EAST_ARROW = b'\xE2\x86\x98' - SOUTH_WEST_ARROW = b'\xE2\x86\x99' - LEFTWARDS_ARROW_WITH_HOOK = b'\xE2\x86\xA9' - RIGHTWARDS_ARROW_WITH_HOOK = b'\xE2\x86\xAA' - WATCH = b'\xE2\x8C\x9A' - HOURGLASS = b'\xE2\x8C\x9B' - BLACK_RIGHT_POINTING_DOUBLE_TRIANGLE = b'\xE2\x8F\xA9' - BLACK_LEFT_POINTING_DOUBLE_TRIANGLE = b'\xE2\x8F\xAA' - BLACK_UP_POINTING_DOUBLE_TRIANGLE = b'\xE2\x8F\xAB' - BLACK_DOWN_POINTING_DOUBLE_TRIANGLE = b'\xE2\x8F\xAC' - ALARM_CLOCK = b'\xE2\x8F\xB0' - HOURGLASS_WITH_FLOWING_SAND = b'\xE2\x8F\xB3' - BLACK_SMALL_SQUARE = b'\xE2\x96\xAA' - WHITE_SMALL_SQUARE = b'\xE2\x96\xAB' - BLACK_RIGHT_POINTING_TRIANGLE = b'\xE2\x96\xB6' - BLACK_LEFT_POINTING_TRIANGLE = b'\xE2\x97\x80' - WHITE_MEDIUM_SQUARE = b'\xE2\x97\xBB' - BLACK_MEDIUM_SQUARE = b'\xE2\x97\xBC' - WHITE_MEDIUM_SMALL_SQUARE = b'\xE2\x97\xBD' - BLACK_MEDIUM_SMALL_SQUARE = b'\xE2\x97\xBE' - BLACK_SUN_WITH_RAYS = b'\xE2\x98\x80' - CLOUD = b'\xE2\x98\x81' - BLACK_TELEPHONE = b'\xE2\x98\x8E' - BALLOT_BOX_WITH_CHECK = b'\xE2\x98\x91' - UMBRELLA_WITH_RAIN_DROPS = b'\xE2\x98\x94' - HOT_BEVERAGE = b'\xE2\x98\x95' - WHITE_UP_POINTING_INDEX = b'\xE2\x98\x9D' - WHITE_SMILING_FACE = b'\xE2\x98\xBA' - ARIES = b'\xE2\x99\x88' - TAURUS = b'\xE2\x99\x89' - GEMINI = b'\xE2\x99\x8A' - CANCER = b'\xE2\x99\x8B' - LEO = b'\xE2\x99\x8C' - VIRGO = b'\xE2\x99\x8D' - LIBRA = b'\xE2\x99\x8E' - SCORPIUS = b'\xE2\x99\x8F' - SAGITTARIUS = b'\xE2\x99\x90' - CAPRICORN = b'\xE2\x99\x91' - AQUARIUS = b'\xE2\x99\x92' - PISCES = b'\xE2\x99\x93' - BLACK_SPADE_SUIT = b'\xE2\x99\xA0' - BLACK_CLUB_SUIT = b'\xE2\x99\xA3' - BLACK_HEART_SUIT = b'\xE2\x99\xA5' - BLACK_DIAMOND_SUIT = b'\xE2\x99\xA6' - HOT_SPRINGS = b'\xE2\x99\xA8' - BLACK_UNIVERSAL_RECYCLING_SYMBOL = b'\xE2\x99\xBB' - WHEELCHAIR_SYMBOL = b'\xE2\x99\xBF' - ANCHOR = b'\xE2\x9A\x93' - WARNING_SIGN = b'\xE2\x9A\xA0' - HIGH_VOLTAGE_SIGN = b'\xE2\x9A\xA1' - MEDIUM_WHITE_CIRCLE = b'\xE2\x9A\xAA' - MEDIUM_BLACK_CIRCLE = b'\xE2\x9A\xAB' - SOCCER_BALL = b'\xE2\x9A\xBD' - BASEBALL = b'\xE2\x9A\xBE' - SNOWMAN_WITHOUT_SNOW = b'\xE2\x9B\x84' - SUN_BEHIND_CLOUD = b'\xE2\x9B\x85' - OPHIUCHUS = b'\xE2\x9B\x8E' - NO_ENTRY = b'\xE2\x9B\x94' - CHURCH = b'\xE2\x9B\xAA' - FOUNTAIN = b'\xE2\x9B\xB2' - FLAG_IN_HOLE = b'\xE2\x9B\xB3' - SAILBOAT = b'\xE2\x9B\xB5' - TENT = b'\xE2\x9B\xBA' - FUEL_PUMP = b'\xE2\x9B\xBD' - ARROW_POINTING_RIGHTWARDS_THEN_CURVING_UPWARDS = b'\xE2\xA4\xB4' - ARROW_POINTING_RIGHTWARDS_THEN_CURVING_DOWNWARDS = b'\xE2\xA4\xB5' - LEFTWARDS_BLACK_ARROW = b'\xE2\xAC\x85' - UPWARDS_BLACK_ARROW = b'\xE2\xAC\x86' - DOWNWARDS_BLACK_ARROW = b'\xE2\xAC\x87' - BLACK_LARGE_SQUARE = b'\xE2\xAC\x9B' - WHITE_LARGE_SQUARE = b'\xE2\xAC\x9C' - WHITE_MEDIUM_STAR = b'\xE2\xAD\x90' - HEAVY_LARGE_CIRCLE = b'\xE2\xAD\x95' - WAVY_DASH = b'\xE3\x80\xB0' - PART_ALTERNATION_MARK = b'\xE3\x80\xBD' - CIRCLED_IDEOGRAPH_CONGRATULATION = b'\xE3\x8A\x97' - CIRCLED_IDEOGRAPH_SECRET = b'\xE3\x8A\x99' - MAHJONG_TILE_RED_DRAGON = b'\xF0\x9F\x80\x84' - PLAYING_CARD_BLACK_JOKER = b'\xF0\x9F\x83\x8F' - CYCLONE = b'\xF0\x9F\x8C\x80' - FOGGY = b'\xF0\x9F\x8C\x81' - CLOSED_UMBRELLA = b'\xF0\x9F\x8C\x82' - NIGHT_WITH_STARS = b'\xF0\x9F\x8C\x83' - SUNRISE_OVER_MOUNTAINS = b'\xF0\x9F\x8C\x84' - SUNRISE = b'\xF0\x9F\x8C\x85' - CITYSCAPE_AT_DUSK = b'\xF0\x9F\x8C\x86' - SUNSET_OVER_BUILDINGS = b'\xF0\x9F\x8C\x87' - RAINBOW = b'\xF0\x9F\x8C\x88' - BRIDGE_AT_NIGHT = b'\xF0\x9F\x8C\x89' - WATER_WAVE = b'\xF0\x9F\x8C\x8A' - VOLCANO = b'\xF0\x9F\x8C\x8B' - MILKY_WAY = b'\xF0\x9F\x8C\x8C' - EARTH_GLOBE_ASIA_AUSTRALIA = b'\xF0\x9F\x8C\x8F' - NEW_MOON_SYMBOL = b'\xF0\x9F\x8C\x91' - FIRST_QUARTER_MOON_SYMBOL = b'\xF0\x9F\x8C\x93' - WAXING_GIBBOUS_MOON_SYMBOL = b'\xF0\x9F\x8C\x94' - FULL_MOON_SYMBOL = b'\xF0\x9F\x8C\x95' - CRESCENT_MOON = b'\xF0\x9F\x8C\x99' - FIRST_QUARTER_MOON_WITH_FACE = b'\xF0\x9F\x8C\x9B' - GLOWING_STAR = b'\xF0\x9F\x8C\x9F' - SHOOTING_STAR = b'\xF0\x9F\x8C\xA0' - CHESTNUT = b'\xF0\x9F\x8C\xB0' - SEEDLING = b'\xF0\x9F\x8C\xB1' - PALM_TREE = b'\xF0\x9F\x8C\xB4' - CACTUS = b'\xF0\x9F\x8C\xB5' - TULIP = b'\xF0\x9F\x8C\xB7' - CHERRY_BLOSSOM = b'\xF0\x9F\x8C\xB8' - ROSE = b'\xF0\x9F\x8C\xB9' - HIBISCUS = b'\xF0\x9F\x8C\xBA' - SUNFLOWER = b'\xF0\x9F\x8C\xBB' - BLOSSOM = b'\xF0\x9F\x8C\xBC' - EAR_OF_MAIZE = b'\xF0\x9F\x8C\xBD' - EAR_OF_RICE = b'\xF0\x9F\x8C\xBE' - HERB = b'\xF0\x9F\x8C\xBF' - FOUR_LEAF_CLOVER = b'\xF0\x9F\x8D\x80' - MAPLE_LEAF = b'\xF0\x9F\x8D\x81' - FALLEN_LEAF = b'\xF0\x9F\x8D\x82' - LEAF_FLUTTERING_IN_WIND = b'\xF0\x9F\x8D\x83' - MUSHROOM = b'\xF0\x9F\x8D\x84' - TOMATO = b'\xF0\x9F\x8D\x85' - AUBERGINE = b'\xF0\x9F\x8D\x86' - GRAPES = b'\xF0\x9F\x8D\x87' - MELON = b'\xF0\x9F\x8D\x88' - WATERMELON = b'\xF0\x9F\x8D\x89' - TANGERINE = b'\xF0\x9F\x8D\x8A' - BANANA = b'\xF0\x9F\x8D\x8C' - PINEAPPLE = b'\xF0\x9F\x8D\x8D' - RED_APPLE = b'\xF0\x9F\x8D\x8E' - GREEN_APPLE = b'\xF0\x9F\x8D\x8F' - PEACH = b'\xF0\x9F\x8D\x91' - CHERRIES = b'\xF0\x9F\x8D\x92' - STRAWBERRY = b'\xF0\x9F\x8D\x93' - HAMBURGER = b'\xF0\x9F\x8D\x94' - SLICE_OF_PIZZA = b'\xF0\x9F\x8D\x95' - MEAT_ON_BONE = b'\xF0\x9F\x8D\x96' - POULTRY_LEG = b'\xF0\x9F\x8D\x97' - RICE_CRACKER = b'\xF0\x9F\x8D\x98' - RICE_BALL = b'\xF0\x9F\x8D\x99' - COOKED_RICE = b'\xF0\x9F\x8D\x9A' - CURRY_AND_RICE = b'\xF0\x9F\x8D\x9B' - STEAMING_BOWL = b'\xF0\x9F\x8D\x9C' - SPAGHETTI = b'\xF0\x9F\x8D\x9D' - BREAD = b'\xF0\x9F\x8D\x9E' - FRENCH_FRIES = b'\xF0\x9F\x8D\x9F' - ROASTED_SWEET_POTATO = b'\xF0\x9F\x8D\xA0' - DANGO = b'\xF0\x9F\x8D\xA1' - ODEN = b'\xF0\x9F\x8D\xA2' - SUSHI = b'\xF0\x9F\x8D\xA3' - FRIED_SHRIMP = b'\xF0\x9F\x8D\xA4' - FISH_CAKE_WITH_SWIRL_DESIGN = b'\xF0\x9F\x8D\xA5' - SOFT_ICE_CREAM = b'\xF0\x9F\x8D\xA6' - SHAVED_ICE = b'\xF0\x9F\x8D\xA7' - ICE_CREAM = b'\xF0\x9F\x8D\xA8' - DOUGHNUT = b'\xF0\x9F\x8D\xA9' - COOKIE = b'\xF0\x9F\x8D\xAA' - CHOCOLATE_BAR = b'\xF0\x9F\x8D\xAB' - CANDY = b'\xF0\x9F\x8D\xAC' - LOLLIPOP = b'\xF0\x9F\x8D\xAD' - CUSTARD = b'\xF0\x9F\x8D\xAE' - HONEY_POT = b'\xF0\x9F\x8D\xAF' - SHORTCAKE = b'\xF0\x9F\x8D\xB0' - BENTO_BOX = b'\xF0\x9F\x8D\xB1' - POT_OF_FOOD = b'\xF0\x9F\x8D\xB2' - COOKING = b'\xF0\x9F\x8D\xB3' - FORK_AND_KNIFE = b'\xF0\x9F\x8D\xB4' - TEACUP_WITHOUT_HANDLE = b'\xF0\x9F\x8D\xB5' - SAKE_BOTTLE_AND_CUP = b'\xF0\x9F\x8D\xB6' - WINE_GLASS = b'\xF0\x9F\x8D\xB7' - COCKTAIL_GLASS = b'\xF0\x9F\x8D\xB8' - TROPICAL_DRINK = b'\xF0\x9F\x8D\xB9' - BEER_MUG = b'\xF0\x9F\x8D\xBA' - CLINKING_BEER_MUGS = b'\xF0\x9F\x8D\xBB' - RIBBON = b'\xF0\x9F\x8E\x80' - WRAPPED_PRESENT = b'\xF0\x9F\x8E\x81' - BIRTHDAY_CAKE = b'\xF0\x9F\x8E\x82' - JACK_O_LANTERN = b'\xF0\x9F\x8E\x83' - CHRISTMAS_TREE = b'\xF0\x9F\x8E\x84' - FATHER_CHRISTMAS = b'\xF0\x9F\x8E\x85' - FIREWORKS = b'\xF0\x9F\x8E\x86' - FIREWORK_SPARKLER = b'\xF0\x9F\x8E\x87' - BALLOON = b'\xF0\x9F\x8E\x88' - PARTY_POPPER = b'\xF0\x9F\x8E\x89' - CONFETTI_BALL = b'\xF0\x9F\x8E\x8A' - TANABATA_TREE = b'\xF0\x9F\x8E\x8B' - CROSSED_FLAGS = b'\xF0\x9F\x8E\x8C' - PINE_DECORATION = b'\xF0\x9F\x8E\x8D' - JAPANESE_DOLLS = b'\xF0\x9F\x8E\x8E' - CARP_STREAMER = b'\xF0\x9F\x8E\x8F' - WIND_CHIME = b'\xF0\x9F\x8E\x90' - MOON_VIEWING_CEREMONY = b'\xF0\x9F\x8E\x91' - SCHOOL_SATCHEL = b'\xF0\x9F\x8E\x92' - GRADUATION_CAP = b'\xF0\x9F\x8E\x93' - CAROUSEL_HORSE = b'\xF0\x9F\x8E\xA0' - FERRIS_WHEEL = b'\xF0\x9F\x8E\xA1' - ROLLER_COASTER = b'\xF0\x9F\x8E\xA2' - FISHING_POLE_AND_FISH = b'\xF0\x9F\x8E\xA3' - MICROPHONE = b'\xF0\x9F\x8E\xA4' - MOVIE_CAMERA = b'\xF0\x9F\x8E\xA5' - CINEMA = b'\xF0\x9F\x8E\xA6' - HEADPHONE = b'\xF0\x9F\x8E\xA7' - ARTIST_PALETTE = b'\xF0\x9F\x8E\xA8' - TOP_HAT = b'\xF0\x9F\x8E\xA9' - CIRCUS_TENT = b'\xF0\x9F\x8E\xAA' - TICKET = b'\xF0\x9F\x8E\xAB' - CLAPPER_BOARD = b'\xF0\x9F\x8E\xAC' - PERFORMING_ARTS = b'\xF0\x9F\x8E\xAD' - VIDEO_GAME = b'\xF0\x9F\x8E\xAE' - DIRECT_HIT = b'\xF0\x9F\x8E\xAF' - SLOT_MACHINE = b'\xF0\x9F\x8E\xB0' - BILLIARDS = b'\xF0\x9F\x8E\xB1' - GAME_DIE = b'\xF0\x9F\x8E\xB2' - BOWLING = b'\xF0\x9F\x8E\xB3' - FLOWER_PLAYING_CARDS = b'\xF0\x9F\x8E\xB4' - MUSICAL_NOTE = b'\xF0\x9F\x8E\xB5' - MULTIPLE_MUSICAL_NOTES = b'\xF0\x9F\x8E\xB6' - SAXOPHONE = b'\xF0\x9F\x8E\xB7' - GUITAR = b'\xF0\x9F\x8E\xB8' - MUSICAL_KEYBOARD = b'\xF0\x9F\x8E\xB9' - TRUMPET = b'\xF0\x9F\x8E\xBA' - VIOLIN = b'\xF0\x9F\x8E\xBB' - MUSICAL_SCORE = b'\xF0\x9F\x8E\xBC' - RUNNING_SHIRT_WITH_SASH = b'\xF0\x9F\x8E\xBD' - TENNIS_RACQUET_AND_BALL = b'\xF0\x9F\x8E\xBE' - SKI_AND_SKI_BOOT = b'\xF0\x9F\x8E\xBF' - BASKETBALL_AND_HOOP = b'\xF0\x9F\x8F\x80' - CHEQUERED_FLAG = b'\xF0\x9F\x8F\x81' - SNOWBOARDER = b'\xF0\x9F\x8F\x82' - RUNNER = b'\xF0\x9F\x8F\x83' - SURFER = b'\xF0\x9F\x8F\x84' - TROPHY = b'\xF0\x9F\x8F\x86' - AMERICAN_FOOTBALL = b'\xF0\x9F\x8F\x88' - SWIMMER = b'\xF0\x9F\x8F\x8A' - HOUSE_BUILDING = b'\xF0\x9F\x8F\xA0' - HOUSE_WITH_GARDEN = b'\xF0\x9F\x8F\xA1' - OFFICE_BUILDING = b'\xF0\x9F\x8F\xA2' - JAPANESE_POST_OFFICE = b'\xF0\x9F\x8F\xA3' - HOSPITAL = b'\xF0\x9F\x8F\xA5' - BANK = b'\xF0\x9F\x8F\xA6' - AUTOMATED_TELLER_MACHINE = b'\xF0\x9F\x8F\xA7' - HOTEL = b'\xF0\x9F\x8F\xA8' - LOVE_HOTEL = b'\xF0\x9F\x8F\xA9' - CONVENIENCE_STORE = b'\xF0\x9F\x8F\xAA' - SCHOOL = b'\xF0\x9F\x8F\xAB' - DEPARTMENT_STORE = b'\xF0\x9F\x8F\xAC' - FACTORY = b'\xF0\x9F\x8F\xAD' - IZAKAYA_LANTERN = b'\xF0\x9F\x8F\xAE' - JAPANESE_CASTLE = b'\xF0\x9F\x8F\xAF' - EUROPEAN_CASTLE = b'\xF0\x9F\x8F\xB0' - SNAIL = b'\xF0\x9F\x90\x8C' - SNAKE = b'\xF0\x9F\x90\x8D' - HORSE = b'\xF0\x9F\x90\x8E' - SHEEP = b'\xF0\x9F\x90\x91' - MONKEY = b'\xF0\x9F\x90\x92' - CHICKEN = b'\xF0\x9F\x90\x94' - BOAR = b'\xF0\x9F\x90\x97' - ELEPHANT = b'\xF0\x9F\x90\x98' - OCTOPUS = b'\xF0\x9F\x90\x99' - SPIRAL_SHELL = b'\xF0\x9F\x90\x9A' - BUG = b'\xF0\x9F\x90\x9B' - ANT = b'\xF0\x9F\x90\x9C' - HONEYBEE = b'\xF0\x9F\x90\x9D' - LADY_BEETLE = b'\xF0\x9F\x90\x9E' - FISH = b'\xF0\x9F\x90\x9F' - TROPICAL_FISH = b'\xF0\x9F\x90\xA0' - BLOWFISH = b'\xF0\x9F\x90\xA1' - TURTLE = b'\xF0\x9F\x90\xA2' - HATCHING_CHICK = b'\xF0\x9F\x90\xA3' - BABY_CHICK = b'\xF0\x9F\x90\xA4' - FRONT_FACING_BABY_CHICK = b'\xF0\x9F\x90\xA5' - BIRD = b'\xF0\x9F\x90\xA6' - PENGUIN = b'\xF0\x9F\x90\xA7' - KOALA = b'\xF0\x9F\x90\xA8' - POODLE = b'\xF0\x9F\x90\xA9' - BACTRIAN_CAMEL = b'\xF0\x9F\x90\xAB' - DOLPHIN = b'\xF0\x9F\x90\xAC' - MOUSE_FACE = b'\xF0\x9F\x90\xAD' - COW_FACE = b'\xF0\x9F\x90\xAE' - TIGER_FACE = b'\xF0\x9F\x90\xAF' - RABBIT_FACE = b'\xF0\x9F\x90\xB0' - CAT_FACE = b'\xF0\x9F\x90\xB1' - DRAGON_FACE = b'\xF0\x9F\x90\xB2' - SPOUTING_WHALE = b'\xF0\x9F\x90\xB3' - HORSE_FACE = b'\xF0\x9F\x90\xB4' - MONKEY_FACE = b'\xF0\x9F\x90\xB5' - DOG_FACE = b'\xF0\x9F\x90\xB6' - PIG_FACE = b'\xF0\x9F\x90\xB7' - FROG_FACE = b'\xF0\x9F\x90\xB8' - HAMSTER_FACE = b'\xF0\x9F\x90\xB9' - WOLF_FACE = b'\xF0\x9F\x90\xBA' - BEAR_FACE = b'\xF0\x9F\x90\xBB' - PANDA_FACE = b'\xF0\x9F\x90\xBC' - PIG_NOSE = b'\xF0\x9F\x90\xBD' - PAW_PRINTS = b'\xF0\x9F\x90\xBE' - EYES = b'\xF0\x9F\x91\x80' - EAR = b'\xF0\x9F\x91\x82' - NOSE = b'\xF0\x9F\x91\x83' - MOUTH = b'\xF0\x9F\x91\x84' - TONGUE = b'\xF0\x9F\x91\x85' - WHITE_UP_POINTING_BACKHAND_INDEX = b'\xF0\x9F\x91\x86' - WHITE_DOWN_POINTING_BACKHAND_INDEX = b'\xF0\x9F\x91\x87' - WHITE_LEFT_POINTING_BACKHAND_INDEX = b'\xF0\x9F\x91\x88' - WHITE_RIGHT_POINTING_BACKHAND_INDEX = b'\xF0\x9F\x91\x89' - FISTED_HAND_SIGN = b'\xF0\x9F\x91\x8A' - WAVING_HAND_SIGN = b'\xF0\x9F\x91\x8B' - OK_HAND_SIGN = b'\xF0\x9F\x91\x8C' - THUMBS_UP_SIGN = b'\xF0\x9F\x91\x8D' - THUMBS_DOWN_SIGN = b'\xF0\x9F\x91\x8E' - CLAPPING_HANDS_SIGN = b'\xF0\x9F\x91\x8F' - OPEN_HANDS_SIGN = b'\xF0\x9F\x91\x90' - CROWN = b'\xF0\x9F\x91\x91' - WOMANS_HAT = b'\xF0\x9F\x91\x92' - EYEGLASSES = b'\xF0\x9F\x91\x93' - NECKTIE = b'\xF0\x9F\x91\x94' - T_SHIRT = b'\xF0\x9F\x91\x95' - JEANS = b'\xF0\x9F\x91\x96' - DRESS = b'\xF0\x9F\x91\x97' - KIMONO = b'\xF0\x9F\x91\x98' - BIKINI = b'\xF0\x9F\x91\x99' - WOMANS_CLOTHES = b'\xF0\x9F\x91\x9A' - PURSE = b'\xF0\x9F\x91\x9B' - HANDBAG = b'\xF0\x9F\x91\x9C' - POUCH = b'\xF0\x9F\x91\x9D' - MANS_SHOE = b'\xF0\x9F\x91\x9E' - ATHLETIC_SHOE = b'\xF0\x9F\x91\x9F' - HIGH_HEELED_SHOE = b'\xF0\x9F\x91\xA0' - WOMANS_SANDAL = b'\xF0\x9F\x91\xA1' - WOMANS_BOOTS = b'\xF0\x9F\x91\xA2' - FOOTPRINTS = b'\xF0\x9F\x91\xA3' - BUST_IN_SILHOUETTE = b'\xF0\x9F\x91\xA4' - BOY = b'\xF0\x9F\x91\xA6' - GIRL = b'\xF0\x9F\x91\xA7' - MAN = b'\xF0\x9F\x91\xA8' - WOMAN = b'\xF0\x9F\x91\xA9' - FAMILY = b'\xF0\x9F\x91\xAA' - MAN_AND_WOMAN_HOLDING_HANDS = b'\xF0\x9F\x91\xAB' - POLICE_OFFICER = b'\xF0\x9F\x91\xAE' - WOMAN_WITH_BUNNY_EARS = b'\xF0\x9F\x91\xAF' - BRIDE_WITH_VEIL = b'\xF0\x9F\x91\xB0' - PERSON_WITH_BLOND_HAIR = b'\xF0\x9F\x91\xB1' - MAN_WITH_GUA_PI_MAO = b'\xF0\x9F\x91\xB2' - MAN_WITH_TURBAN = b'\xF0\x9F\x91\xB3' - OLDER_MAN = b'\xF0\x9F\x91\xB4' - OLDER_WOMAN = b'\xF0\x9F\x91\xB5' - BABY = b'\xF0\x9F\x91\xB6' - CONSTRUCTION_WORKER = b'\xF0\x9F\x91\xB7' - PRINCESS = b'\xF0\x9F\x91\xB8' - JAPANESE_OGRE = b'\xF0\x9F\x91\xB9' - JAPANESE_GOBLIN = b'\xF0\x9F\x91\xBA' - GHOST = b'\xF0\x9F\x91\xBB' - BABY_ANGEL = b'\xF0\x9F\x91\xBC' - EXTRATERRESTRIAL_ALIEN = b'\xF0\x9F\x91\xBD' - ALIEN_MONSTER = b'\xF0\x9F\x91\xBE' - IMP = b'\xF0\x9F\x91\xBF' - SKULL = b'\xF0\x9F\x92\x80' - INFORMATION_DESK_PERSON = b'\xF0\x9F\x92\x81' - GUARDSMAN = b'\xF0\x9F\x92\x82' - DANCER = b'\xF0\x9F\x92\x83' - LIPSTICK = b'\xF0\x9F\x92\x84' - NAIL_POLISH = b'\xF0\x9F\x92\x85' - FACE_MASSAGE = b'\xF0\x9F\x92\x86' - HAIRCUT = b'\xF0\x9F\x92\x87' - BARBER_POLE = b'\xF0\x9F\x92\x88' - SYRINGE = b'\xF0\x9F\x92\x89' - PILL = b'\xF0\x9F\x92\x8A' - KISS_MARK = b'\xF0\x9F\x92\x8B' - LOVE_LETTER = b'\xF0\x9F\x92\x8C' - RING = b'\xF0\x9F\x92\x8D' - GEM_STONE = b'\xF0\x9F\x92\x8E' - KISS = b'\xF0\x9F\x92\x8F' - BOUQUET = b'\xF0\x9F\x92\x90' - COUPLE_WITH_HEART = b'\xF0\x9F\x92\x91' - WEDDING = b'\xF0\x9F\x92\x92' - BEATING_HEART = b'\xF0\x9F\x92\x93' - BROKEN_HEART = b'\xF0\x9F\x92\x94' - TWO_HEARTS = b'\xF0\x9F\x92\x95' - SPARKLING_HEART = b'\xF0\x9F\x92\x96' - GROWING_HEART = b'\xF0\x9F\x92\x97' - HEART_WITH_ARROW = b'\xF0\x9F\x92\x98' - BLUE_HEART = b'\xF0\x9F\x92\x99' - GREEN_HEART = b'\xF0\x9F\x92\x9A' - YELLOW_HEART = b'\xF0\x9F\x92\x9B' - PURPLE_HEART = b'\xF0\x9F\x92\x9C' - HEART_WITH_RIBBON = b'\xF0\x9F\x92\x9D' - REVOLVING_HEARTS = b'\xF0\x9F\x92\x9E' - HEART_DECORATION = b'\xF0\x9F\x92\x9F' - DIAMOND_SHAPE_WITH_A_DOT_INSIDE = b'\xF0\x9F\x92\xA0' - ELECTRIC_LIGHT_BULB = b'\xF0\x9F\x92\xA1' - ANGER_SYMBOL = b'\xF0\x9F\x92\xA2' - BOMB = b'\xF0\x9F\x92\xA3' - SLEEPING_SYMBOL = b'\xF0\x9F\x92\xA4' - COLLISION_SYMBOL = b'\xF0\x9F\x92\xA5' - SPLASHING_SWEAT_SYMBOL = b'\xF0\x9F\x92\xA6' - DROPLET = b'\xF0\x9F\x92\xA7' - DASH_SYMBOL = b'\xF0\x9F\x92\xA8' - PILE_OF_POO = b'\xF0\x9F\x92\xA9' - FLEXED_BICEPS = b'\xF0\x9F\x92\xAA' - DIZZY_SYMBOL = b'\xF0\x9F\x92\xAB' - SPEECH_BALLOON = b'\xF0\x9F\x92\xAC' - WHITE_FLOWER = b'\xF0\x9F\x92\xAE' - HUNDRED_POINTS_SYMBOL = b'\xF0\x9F\x92\xAF' - MONEY_BAG = b'\xF0\x9F\x92\xB0' - CURRENCY_EXCHANGE = b'\xF0\x9F\x92\xB1' - HEAVY_DOLLAR_SIGN = b'\xF0\x9F\x92\xB2' - CREDIT_CARD = b'\xF0\x9F\x92\xB3' - BANKNOTE_WITH_YEN_SIGN = b'\xF0\x9F\x92\xB4' - BANKNOTE_WITH_DOLLAR_SIGN = b'\xF0\x9F\x92\xB5' - MONEY_WITH_WINGS = b'\xF0\x9F\x92\xB8' - CHART_WITH_UPWARDS_TREND_AND_YEN_SIGN = b'\xF0\x9F\x92\xB9' - SEAT = b'\xF0\x9F\x92\xBA' - PERSONAL_COMPUTER = b'\xF0\x9F\x92\xBB' - BRIEFCASE = b'\xF0\x9F\x92\xBC' - MINIDISC = b'\xF0\x9F\x92\xBD' - FLOPPY_DISK = b'\xF0\x9F\x92\xBE' - OPTICAL_DISC = b'\xF0\x9F\x92\xBF' - DVD = b'\xF0\x9F\x93\x80' - FILE_FOLDER = b'\xF0\x9F\x93\x81' - OPEN_FILE_FOLDER = b'\xF0\x9F\x93\x82' - PAGE_WITH_CURL = b'\xF0\x9F\x93\x83' - PAGE_FACING_UP = b'\xF0\x9F\x93\x84' - CALENDAR = b'\xF0\x9F\x93\x85' - TEAR_OFF_CALENDAR = b'\xF0\x9F\x93\x86' - CARD_INDEX = b'\xF0\x9F\x93\x87' - CHART_WITH_UPWARDS_TREND = b'\xF0\x9F\x93\x88' - CHART_WITH_DOWNWARDS_TREND = b'\xF0\x9F\x93\x89' - BAR_CHART = b'\xF0\x9F\x93\x8A' - CLIPBOARD = b'\xF0\x9F\x93\x8B' - PUSHPIN = b'\xF0\x9F\x93\x8C' - ROUND_PUSHPIN = b'\xF0\x9F\x93\x8D' - PAPERCLIP = b'\xF0\x9F\x93\x8E' - STRAIGHT_RULER = b'\xF0\x9F\x93\x8F' - TRIANGULAR_RULER = b'\xF0\x9F\x93\x90' - BOOKMARK_TABS = b'\xF0\x9F\x93\x91' - LEDGER = b'\xF0\x9F\x93\x92' - NOTEBOOK = b'\xF0\x9F\x93\x93' - NOTEBOOK_WITH_DECORATIVE_COVER = b'\xF0\x9F\x93\x94' - CLOSED_BOOK = b'\xF0\x9F\x93\x95' - OPEN_BOOK = b'\xF0\x9F\x93\x96' - GREEN_BOOK = b'\xF0\x9F\x93\x97' - BLUE_BOOK = b'\xF0\x9F\x93\x98' - ORANGE_BOOK = b'\xF0\x9F\x93\x99' - BOOKS = b'\xF0\x9F\x93\x9A' - NAME_BADGE = b'\xF0\x9F\x93\x9B' - SCROLL = b'\xF0\x9F\x93\x9C' - MEMO = b'\xF0\x9F\x93\x9D' - TELEPHONE_RECEIVER = b'\xF0\x9F\x93\x9E' - PAGER = b'\xF0\x9F\x93\x9F' - FAX_MACHINE = b'\xF0\x9F\x93\xA0' - SATELLITE_ANTENNA = b'\xF0\x9F\x93\xA1' - PUBLIC_ADDRESS_LOUDSPEAKER = b'\xF0\x9F\x93\xA2' - CHEERING_MEGAPHONE = b'\xF0\x9F\x93\xA3' - OUTBOX_TRAY = b'\xF0\x9F\x93\xA4' - INBOX_TRAY = b'\xF0\x9F\x93\xA5' - PACKAGE = b'\xF0\x9F\x93\xA6' - E_MAIL_SYMBOL = b'\xF0\x9F\x93\xA7' - INCOMING_ENVELOPE = b'\xF0\x9F\x93\xA8' - ENVELOPE_WITH_DOWNWARDS_ARROW_ABOVE = b'\xF0\x9F\x93\xA9' - CLOSED_MAILBOX_WITH_LOWERED_FLAG = b'\xF0\x9F\x93\xAA' - CLOSED_MAILBOX_WITH_RAISED_FLAG = b'\xF0\x9F\x93\xAB' - POSTBOX = b'\xF0\x9F\x93\xAE' - NEWSPAPER = b'\xF0\x9F\x93\xB0' - MOBILE_PHONE = b'\xF0\x9F\x93\xB1' - MOBILE_PHONE_WITH_RIGHTWARDS_ARROW_AT_LEFT = b'\xF0\x9F\x93\xB2' - VIBRATION_MODE = b'\xF0\x9F\x93\xB3' - MOBILE_PHONE_OFF = b'\xF0\x9F\x93\xB4' - ANTENNA_WITH_BARS = b'\xF0\x9F\x93\xB6' - CAMERA = b'\xF0\x9F\x93\xB7' - VIDEO_CAMERA = b'\xF0\x9F\x93\xB9' - TELEVISION = b'\xF0\x9F\x93\xBA' - RADIO = b'\xF0\x9F\x93\xBB' - VIDEOCASSETTE = b'\xF0\x9F\x93\xBC' - CLOCKWISE_DOWNWARDS_AND_UPWARDS_OPEN_CIRCLE_ARROWS = b'\xF0\x9F\x94\x83' - SPEAKER_WITH_THREE_SOUND_WAVES = b'\xF0\x9F\x94\x8A' - BATTERY = b'\xF0\x9F\x94\x8B' - ELECTRIC_PLUG = b'\xF0\x9F\x94\x8C' - LEFT_POINTING_MAGNIFYING_GLASS = b'\xF0\x9F\x94\x8D' - RIGHT_POINTING_MAGNIFYING_GLASS = b'\xF0\x9F\x94\x8E' - LOCK_WITH_INK_PEN = b'\xF0\x9F\x94\x8F' - CLOSED_LOCK_WITH_KEY = b'\xF0\x9F\x94\x90' - KEY = b'\xF0\x9F\x94\x91' - LOCK = b'\xF0\x9F\x94\x92' - OPEN_LOCK = b'\xF0\x9F\x94\x93' - BELL = b'\xF0\x9F\x94\x94' - BOOKMARK = b'\xF0\x9F\x94\x96' - LINK_SYMBOL = b'\xF0\x9F\x94\x97' - RADIO_BUTTON = b'\xF0\x9F\x94\x98' - BACK_WITH_LEFTWARDS_ARROW_ABOVE = b'\xF0\x9F\x94\x99' - END_WITH_LEFTWARDS_ARROW_ABOVE = b'\xF0\x9F\x94\x9A' - ON_WITH_EXCLAMATION_MARK_WITH_LEFT_RIGHT_ARROW_ABOVE = b'\xF0\x9F\x94\x9B' - SOON_WITH_RIGHTWARDS_ARROW_ABOVE = b'\xF0\x9F\x94\x9C' - TOP_WITH_UPWARDS_ARROW_ABOVE = b'\xF0\x9F\x94\x9D' - NO_ONE_UNDER_EIGHTEEN_SYMBOL = b'\xF0\x9F\x94\x9E' - KEYCAP_TEN = b'\xF0\x9F\x94\x9F' - INPUT_SYMBOL_FOR_LATIN_CAPITAL_LETTERS = b'\xF0\x9F\x94\xA0' - INPUT_SYMBOL_FOR_LATIN_SMALL_LETTERS = b'\xF0\x9F\x94\xA1' - INPUT_SYMBOL_FOR_NUMBERS = b'\xF0\x9F\x94\xA2' - INPUT_SYMBOL_FOR_SYMBOLS = b'\xF0\x9F\x94\xA3' - INPUT_SYMBOL_FOR_LATIN_LETTERS = b'\xF0\x9F\x94\xA4' - FIRE = b'\xF0\x9F\x94\xA5' - ELECTRIC_TORCH = b'\xF0\x9F\x94\xA6' - WRENCH = b'\xF0\x9F\x94\xA7' - HAMMER = b'\xF0\x9F\x94\xA8' - NUT_AND_BOLT = b'\xF0\x9F\x94\xA9' - HOCHO = b'\xF0\x9F\x94\xAA' - PISTOL = b'\xF0\x9F\x94\xAB' - CRYSTAL_BALL = b'\xF0\x9F\x94\xAE' - SIX_POINTED_STAR_WITH_MIDDLE_DOT = b'\xF0\x9F\x94\xAF' - JAPANESE_SYMBOL_FOR_BEGINNER = b'\xF0\x9F\x94\xB0' - TRIDENT_EMBLEM = b'\xF0\x9F\x94\xB1' - BLACK_SQUARE_BUTTON = b'\xF0\x9F\x94\xB2' - WHITE_SQUARE_BUTTON = b'\xF0\x9F\x94\xB3' - LARGE_RED_CIRCLE = b'\xF0\x9F\x94\xB4' - LARGE_BLUE_CIRCLE = b'\xF0\x9F\x94\xB5' - LARGE_ORANGE_DIAMOND = b'\xF0\x9F\x94\xB6' - LARGE_BLUE_DIAMOND = b'\xF0\x9F\x94\xB7' - SMALL_ORANGE_DIAMOND = b'\xF0\x9F\x94\xB8' - SMALL_BLUE_DIAMOND = b'\xF0\x9F\x94\xB9' - UP_POINTING_RED_TRIANGLE = b'\xF0\x9F\x94\xBA' - DOWN_POINTING_RED_TRIANGLE = b'\xF0\x9F\x94\xBB' - UP_POINTING_SMALL_RED_TRIANGLE = b'\xF0\x9F\x94\xBC' - DOWN_POINTING_SMALL_RED_TRIANGLE = b'\xF0\x9F\x94\xBD' - CLOCK_FACE_ONE_OCLOCK = b'\xF0\x9F\x95\x90' - CLOCK_FACE_TWO_OCLOCK = b'\xF0\x9F\x95\x91' - CLOCK_FACE_THREE_OCLOCK = b'\xF0\x9F\x95\x92' - CLOCK_FACE_FOUR_OCLOCK = b'\xF0\x9F\x95\x93' - CLOCK_FACE_FIVE_OCLOCK = b'\xF0\x9F\x95\x94' - CLOCK_FACE_SIX_OCLOCK = b'\xF0\x9F\x95\x95' - CLOCK_FACE_SEVEN_OCLOCK = b'\xF0\x9F\x95\x96' - CLOCK_FACE_EIGHT_OCLOCK = b'\xF0\x9F\x95\x97' - CLOCK_FACE_NINE_OCLOCK = b'\xF0\x9F\x95\x98' - CLOCK_FACE_TEN_OCLOCK = b'\xF0\x9F\x95\x99' - CLOCK_FACE_ELEVEN_OCLOCK = b'\xF0\x9F\x95\x9A' - CLOCK_FACE_TWELVE_OCLOCK = b'\xF0\x9F\x95\x9B' - MOUNT_FUJI = b'\xF0\x9F\x97\xBB' - TOKYO_TOWER = b'\xF0\x9F\x97\xBC' - STATUE_OF_LIBERTY = b'\xF0\x9F\x97\xBD' - SILHOUETTE_OF_JAPAN = b'\xF0\x9F\x97\xBE' - MOYAI = b'\xF0\x9F\x97\xBF' - GRINNING_FACE = b'\xF0\x9F\x98\x80' - SMILING_FACE_WITH_HALO = b'\xF0\x9F\x98\x87' - SMILING_FACE_WITH_HORNS = b'\xF0\x9F\x98\x88' - SMILING_FACE_WITH_SUNGLASSES = b'\xF0\x9F\x98\x8E' - NEUTRAL_FACE = b'\xF0\x9F\x98\x90' - EXPRESSIONLESS_FACE = b'\xF0\x9F\x98\x91' - CONFUSED_FACE = b'\xF0\x9F\x98\x95' - KISSING_FACE = b'\xF0\x9F\x98\x97' - KISSING_FACE_WITH_SMILING_EYES = b'\xF0\x9F\x98\x99' - FACE_WITH_STUCK_OUT_TONGUE = b'\xF0\x9F\x98\x9B' - WORRIED_FACE = b'\xF0\x9F\x98\x9F' - FROWNING_FACE_WITH_OPEN_MOUTH = b'\xF0\x9F\x98\xA6' - ANGUISHED_FACE = b'\xF0\x9F\x98\xA7' - GRIMACING_FACE = b'\xF0\x9F\x98\xAC' - FACE_WITH_OPEN_MOUTH = b'\xF0\x9F\x98\xAE' - HUSHED_FACE = b'\xF0\x9F\x98\xAF' - SLEEPING_FACE = b'\xF0\x9F\x98\xB4' - FACE_WITHOUT_MOUTH = b'\xF0\x9F\x98\xB6' - HELICOPTER = b'\xF0\x9F\x9A\x81' - STEAM_LOCOMOTIVE = b'\xF0\x9F\x9A\x82' - TRAIN = b'\xF0\x9F\x9A\x86' - LIGHT_RAIL = b'\xF0\x9F\x9A\x88' - TRAM = b'\xF0\x9F\x9A\x8A' - ONCOMING_BUS = b'\xF0\x9F\x9A\x8D' - TROLLEYBUS = b'\xF0\x9F\x9A\x8E' - MINIBUS = b'\xF0\x9F\x9A\x90' - ONCOMING_POLICE_CAR = b'\xF0\x9F\x9A\x94' - ONCOMING_TAXI = b'\xF0\x9F\x9A\x96' - ONCOMING_AUTOMOBILE = b'\xF0\x9F\x9A\x98' - ARTICULATED_LORRY = b'\xF0\x9F\x9A\x9B' - TRACTOR = b'\xF0\x9F\x9A\x9C' - MONORAIL = b'\xF0\x9F\x9A\x9D' - MOUNTAIN_RAILWAY = b'\xF0\x9F\x9A\x9E' - SUSPENSION_RAILWAY = b'\xF0\x9F\x9A\x9F' - MOUNTAIN_CABLEWAY = b'\xF0\x9F\x9A\xA0' - AERIAL_TRAMWAY = b'\xF0\x9F\x9A\xA1' - ROWBOAT = b'\xF0\x9F\x9A\xA3' - VERTICAL_TRAFFIC_LIGHT = b'\xF0\x9F\x9A\xA6' - PUT_LITTER_IN_ITS_PLACE_SYMBOL = b'\xF0\x9F\x9A\xAE' - DO_NOT_LITTER_SYMBOL = b'\xF0\x9F\x9A\xAF' - POTABLE_WATER_SYMBOL = b'\xF0\x9F\x9A\xB0' - NON_POTABLE_WATER_SYMBOL = b'\xF0\x9F\x9A\xB1' - NO_BICYCLES = b'\xF0\x9F\x9A\xB3' - BICYCLIST = b'\xF0\x9F\x9A\xB4' - MOUNTAIN_BICYCLIST = b'\xF0\x9F\x9A\xB5' - NO_PEDESTRIANS = b'\xF0\x9F\x9A\xB7' - CHILDREN_CROSSING = b'\xF0\x9F\x9A\xB8' - SHOWER = b'\xF0\x9F\x9A\xBF' - BATHTUB = b'\xF0\x9F\x9B\x81' - PASSPORT_CONTROL = b'\xF0\x9F\x9B\x82' - CUSTOMS = b'\xF0\x9F\x9B\x83' - BAGGAGE_CLAIM = b'\xF0\x9F\x9B\x84' - LEFT_LUGGAGE = b'\xF0\x9F\x9B\x85' - EARTH_GLOBE_EUROPE_AFRICA = b'\xF0\x9F\x8C\x8D' - EARTH_GLOBE_AMERICAS = b'\xF0\x9F\x8C\x8E' - GLOBE_WITH_MERIDIANS = b'\xF0\x9F\x8C\x90' - WAXING_CRESCENT_MOON_SYMBOL = b'\xF0\x9F\x8C\x92' - WANING_GIBBOUS_MOON_SYMBOL = b'\xF0\x9F\x8C\x96' - LAST_QUARTER_MOON_SYMBOL = b'\xF0\x9F\x8C\x97' - WANING_CRESCENT_MOON_SYMBOL = b'\xF0\x9F\x8C\x98' - NEW_MOON_WITH_FACE = b'\xF0\x9F\x8C\x9A' - LAST_QUARTER_MOON_WITH_FACE = b'\xF0\x9F\x8C\x9C' - FULL_MOON_WITH_FACE = b'\xF0\x9F\x8C\x9D' - SUN_WITH_FACE = b'\xF0\x9F\x8C\x9E' - EVERGREEN_TREE = b'\xF0\x9F\x8C\xB2' - DECIDUOUS_TREE = b'\xF0\x9F\x8C\xB3' - LEMON = b'\xF0\x9F\x8D\x8B' - PEAR = b'\xF0\x9F\x8D\x90' - BABY_BOTTLE = b'\xF0\x9F\x8D\xBC' - HORSE_RACING = b'\xF0\x9F\x8F\x87' - RUGBY_FOOTBALL = b'\xF0\x9F\x8F\x89' - EUROPEAN_POST_OFFICE = b'\xF0\x9F\x8F\xA4' - RAT = b'\xF0\x9F\x90\x80' - MOUSE = b'\xF0\x9F\x90\x81' - OX = b'\xF0\x9F\x90\x82' - WATER_BUFFALO = b'\xF0\x9F\x90\x83' - COW = b'\xF0\x9F\x90\x84' - TIGER = b'\xF0\x9F\x90\x85' - LEOPARD = b'\xF0\x9F\x90\x86' - RABBIT = b'\xF0\x9F\x90\x87' - CAT = b'\xF0\x9F\x90\x88' - DRAGON = b'\xF0\x9F\x90\x89' - CROCODILE = b'\xF0\x9F\x90\x8A' - WHALE = b'\xF0\x9F\x90\x8B' - RAM = b'\xF0\x9F\x90\x8F' - GOAT = b'\xF0\x9F\x90\x90' - ROOSTER = b'\xF0\x9F\x90\x93' - DOG = b'\xF0\x9F\x90\x95' - PIG = b'\xF0\x9F\x90\x96' - DROMEDARY_CAMEL = b'\xF0\x9F\x90\xAA' - BUSTS_IN_SILHOUETTE = b'\xF0\x9F\x91\xA5' - TWO_MEN_HOLDING_HANDS = b'\xF0\x9F\x91\xAC' - TWO_WOMEN_HOLDING_HANDS = b'\xF0\x9F\x91\xAD' - THOUGHT_BALLOON = b'\xF0\x9F\x92\xAD' - BANKNOTE_WITH_EURO_SIGN = b'\xF0\x9F\x92\xB6' - BANKNOTE_WITH_POUND_SIGN = b'\xF0\x9F\x92\xB7' - OPEN_MAILBOX_WITH_RAISED_FLAG = b'\xF0\x9F\x93\xAC' - OPEN_MAILBOX_WITH_LOWERED_FLAG = b'\xF0\x9F\x93\xAD' - POSTAL_HORN = b'\xF0\x9F\x93\xAF' - NO_MOBILE_PHONES = b'\xF0\x9F\x93\xB5' - TWISTED_RIGHTWARDS_ARROWS = b'\xF0\x9F\x94\x80' - CLOCKWISE_RIGHTWARDS_AND_LEFTWARDS_OPEN_CIRCLE_ARROWS = b'\xF0\x9F\x94\x81' - CLOCKWISE_RIGHTWARDS_AND_LEFTWARDS_OPEN_CIRCLE_ARROWS_WITH_CIRCLED_ONE_OVERLAY = b'\xF0\x9F\x94\x82' - ANTICLOCKWISE_DOWNWARDS_AND_UPWARDS_OPEN_CIRCLE_ARROWS = b'\xF0\x9F\x94\x84' - LOW_BRIGHTNESS_SYMBOL = b'\xF0\x9F\x94\x85' - HIGH_BRIGHTNESS_SYMBOL = b'\xF0\x9F\x94\x86' - SPEAKER_WITH_CANCELLATION_STROKE = b'\xF0\x9F\x94\x87' - SPEAKER_WITH_ONE_SOUND_WAVE = b'\xF0\x9F\x94\x89' - BELL_WITH_CANCELLATION_STROKE = b'\xF0\x9F\x94\x95' - MICROSCOPE = b'\xF0\x9F\x94\xAC' - TELESCOPE = b'\xF0\x9F\x94\xAD' - CLOCK_FACE_ONE_THIRTY = b'\xF0\x9F\x95\x9C' - CLOCK_FACE_TWO_THIRTY = b'\xF0\x9F\x95\x9D' - CLOCK_FACE_THREE_THIRTY = b'\xF0\x9F\x95\x9E' - CLOCK_FACE_FOUR_THIRTY = b'\xF0\x9F\x95\x9F' - CLOCK_FACE_FIVE_THIRTY = b'\xF0\x9F\x95\xA0' - CLOCK_FACE_SIX_THIRTY = b'\xF0\x9F\x95\xA1' - CLOCK_FACE_SEVEN_THIRTY = b'\xF0\x9F\x95\xA2' - CLOCK_FACE_EIGHT_THIRTY = b'\xF0\x9F\x95\xA3' - CLOCK_FACE_NINE_THIRTY = b'\xF0\x9F\x95\xA4' - CLOCK_FACE_TEN_THIRTY = b'\xF0\x9F\x95\xA5' - CLOCK_FACE_ELEVEN_THIRTY = b'\xF0\x9F\x95\xA6' - CLOCK_FACE_TWELVE_THIRTY = b'\xF0\x9F\x95\xA7' diff --git a/lib/telegram/error.py b/lib/telegram/error.py deleted file mode 100644 index f8b7e21f..00000000 --- a/lib/telegram/error.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram Error""" - -import re - - -class TelegramError(Exception): - """This object represents a Telegram Error.""" - - def __init__(self, message): - """ - Returns: - str: - """ - super(TelegramError, self).__init__() - - api_error = re.match(r'^Error: (?P.*)', message) - if api_error: - self.message = api_error.group('message').capitalize() - else: - self.message = message - - def __str__(self): - return '%s' % (self.message) diff --git a/lib/telegram/file.py b/lib/telegram/file.py deleted file mode 100644 index 9474d2ff..00000000 --- a/lib/telegram/file.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram File""" - -from os.path import basename - -from telegram import TelegramObject -from telegram.utils.request import download as _download - - -class File(TelegramObject): - - """This object represents a Telegram File. - - Attributes: - file_id (str): - file_size (str): - file_path (str): - - Args: - file_id (str): - **kwargs: Arbitrary keyword arguments. - - Keyword Args: - file_size (Optional[int]): - file_path (Optional[str]): - """ - - def __init__(self, - file_id, - **kwargs): - # Required - self.file_id = str(file_id) - # Optionals - self.file_size = int(kwargs.get('file_size', 0)) - self.file_path = str(kwargs.get('file_path', '')) - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.File: - """ - if not data: - return None - - return File(**data) - - def download(self, - custom_path=None): - """ - Args: - custom_path (str): - """ - url = self.file_path - - if custom_path: - filename = basename(custom_path) - else: - filename = basename(url) - - _download(url, filename) diff --git a/lib/telegram/forcereply.py b/lib/telegram/forcereply.py deleted file mode 100644 index 28057bee..00000000 --- a/lib/telegram/forcereply.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram ForceReply""" - -from telegram import ReplyMarkup - - -class ForceReply(ReplyMarkup): - """This object represents a Telegram ForceReply. - - Attributes: - force_reply (bool): - selective (bool): - - Args: - force_reply (bool): - **kwargs: Arbitrary keyword arguments. - - Keyword Args: - selective (Optional[bool]): - """ - - def __init__(self, - force_reply=True, - **kwargs): - # Required - self.force_reply = bool(force_reply) - # Optionals - self.selective = bool(kwargs.get('selective', False)) - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.ForceReply: - """ - if not data: - return None - - return ForceReply(**data) diff --git a/lib/telegram/groupchat.py b/lib/telegram/groupchat.py deleted file mode 100644 index f4d59723..00000000 --- a/lib/telegram/groupchat.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python -# pylint: disable=C0103,W0622 -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram GroupChat""" - -from telegram import TelegramObject - - -class GroupChat(TelegramObject): - """This object represents a Telegram GroupChat. - - Attributes: - id (int): - title (str): - type (str): - - Args: - id (int): - title (str): - **kwargs: Arbitrary keyword arguments. - - Keyword Args: - type (Optional[str]): - """ - - def __init__(self, - id, - title, - **kwargs): - # Required - self.id = int(id) - self.title = title - # Optionals - self.type = kwargs.get('type', '') - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.GroupChat: - """ - if not data: - return None - - return GroupChat(**data) diff --git a/lib/telegram/inputfile.py b/lib/telegram/inputfile.py deleted file mode 100644 index 0946f972..00000000 --- a/lib/telegram/inputfile.py +++ /dev/null @@ -1,193 +0,0 @@ -#!/usr/bin/env python -# pylint: disable=W0622,E0611 -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram InputFile""" - -try: - from email.generator import _make_boundary as choose_boundary - from urllib.request import urlopen - from io import BufferedReader as file -except ImportError: - from mimetools import choose_boundary - from urllib2 import urlopen -import mimetypes -import os -import sys -import imghdr - -from telegram import TelegramError - -DEFAULT_MIME_TYPE = 'application/octet-stream' -USER_AGENT = 'Python Telegram Bot' \ - ' (https://github.com/leandrotoledo/python-telegram-bot)' - - -class InputFile(object): - """This object represents a Telegram InputFile.""" - - def __init__(self, - data): - self.data = data - self.boundary = choose_boundary() - - if 'audio' in data: - self.input_name = 'audio' - self.input_file = data.pop('audio') - if 'document' in data: - self.input_name = 'document' - self.input_file = data.pop('document') - if 'photo' in data: - self.input_name = 'photo' - self.input_file = data.pop('photo') - if 'sticker' in data: - self.input_name = 'sticker' - self.input_file = data.pop('sticker') - if 'video' in data: - self.input_name = 'video' - self.input_file = data.pop('video') - if 'voice' in data: - self.input_name = 'voice' - self.input_file = data.pop('voice') - if 'certificate' in data: - self.input_name = 'certificate' - self.input_file = data.pop('certificate') - - if isinstance(self.input_file, file): - self.input_file_content = self.input_file.read() - if 'filename' in data: - self.filename = self.data.pop('filename') - else: - self.filename = os.path.basename(self.input_file.name) - self.mimetype = mimetypes.guess_type(self.filename)[0] or \ - DEFAULT_MIME_TYPE - - if 'http' in self.input_file: - self.input_file_content = urlopen(self.input_file).read() - self.mimetype = InputFile.is_image(self.input_file_content) - self.filename = self.mimetype.replace('/', '.') - - @property - def headers(self): - """ - Returns: - str: - """ - return {'User-agent': USER_AGENT, - 'Content-type': self.content_type} - - @property - def content_type(self): - """ - Returns: - str: - """ - return 'multipart/form-data; boundary=%s' % self.boundary - - def to_form(self): - """ - Returns: - str: - """ - form = [] - form_boundary = '--' + self.boundary - - # Add data fields - for name, value in self.data.items(): - form.extend([ - form_boundary, - 'Content-Disposition: form-data; name="%s"' % name, - '', - str(value) - ]) - - # Add input_file to upload - form.extend([ - form_boundary, - 'Content-Disposition: form-data; name="%s"; filename="%s"' % ( - self.input_name, self.filename - ), - 'Content-Type: %s' % self.mimetype, - '', - self.input_file_content - ]) - - form.append('--' + self.boundary + '--') - form.append('') - - return InputFile._parse(form) - - @staticmethod - def _parse(form): - """ - Returns: - str: - """ - if sys.version_info > (3,): - # on Python 3 form needs to be byte encoded - encoded_form = [] - for item in form: - try: - encoded_form.append(item.encode()) - except AttributeError: - encoded_form.append(item) - - return b'\r\n'.join(encoded_form) - return '\r\n'.join(form) - - @staticmethod - def is_image(stream): - """Check if the content file is an image by analyzing its headers. - - Args: - stream (str): A str representing the content of a file. - - Returns: - str: The str mimetype of an image. - """ - image = imghdr.what(None, stream) - if image: - return 'image/%s' % image - - raise TelegramError('Could not parse file content') - - @staticmethod - def is_inputfile(data): - """Check if the request is a file request. - - Args: - data (str): A dict of (str, unicode) key/value pairs - - Returns: - bool - """ - if data: - file_types = ['audio', 'document', 'photo', 'sticker', 'video', - 'voice', 'certificate'] - file_type = [i for i in list(data.keys()) if i in file_types] - - if file_type: - file_content = data[file_type[0]] - - if file_type[0] == 'photo' or file_type[0] == 'document': - return isinstance(file_content, file) or \ - str(file_content).startswith('http') - - return isinstance(file_content, file) - - return False diff --git a/lib/telegram/location.py b/lib/telegram/location.py deleted file mode 100644 index 66c28fc5..00000000 --- a/lib/telegram/location.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram Location""" - -from telegram import TelegramObject - - -class Location(TelegramObject): - """This object represents a Telegram Sticker. - - Attributes: - longitude (float): - latitude (float): - - Args: - longitude (float): - latitude (float): - """ - - def __init__(self, - longitude, - latitude): - # Required - self.longitude = float(longitude) - self.latitude = float(latitude) - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.Location: - """ - if not data: - return None - - return Location(**data) diff --git a/lib/telegram/message.py b/lib/telegram/message.py deleted file mode 100644 index e77f3ea4..00000000 --- a/lib/telegram/message.py +++ /dev/null @@ -1,231 +0,0 @@ -#!/usr/bin/env python -# pylint: disable=R0902,R0912,R0913 -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram Message""" - -from datetime import datetime -from time import mktime - -from telegram import (Audio, Contact, Document, GroupChat, Location, PhotoSize, - Sticker, TelegramObject, User, Video, Voice) - - -class Message(TelegramObject): - """This object represents a Telegram Message. - - Note: - * In Python `from` is a reserved word, use `from_user` instead. - - Attributes: - message_id (int): - from_user (:class:`telegram.User`): - date (:class:`datetime.datetime`): - forward_from (:class:`telegram.User`): - forward_date (:class:`datetime.datetime`): - reply_to_message (:class:`telegram.Message`): - text (str): - audio (:class:`telegram.Audio`): - document (:class:`telegram.Document`): - photo (List[:class:`telegram.PhotoSize`]): - sticker (:class:`telegram.Sticker`): - video (:class:`telegram.Video`): - voice (:class:`telegram.Voice`): - caption (str): - contact (:class:`telegram.Contact`): - location (:class:`telegram.Location`): - new_chat_participant (:class:`telegram.User`): - left_chat_participant (:class:`telegram.User`): - new_chat_title (str): - new_chat_photo (List[:class:`telegram.PhotoSize`]): - delete_chat_photo (bool): - group_chat_created (bool): - - Args: - message_id (int): - from_user (:class:`telegram.User`): - date (:class:`datetime.datetime`): - chat (:class:`telegram.User` or :class:`telegram.GroupChat`): - **kwargs: Arbitrary keyword arguments. - - Keyword Args: - forward_from (Optional[:class:`telegram.User`]): - forward_date (Optional[:class:`datetime.datetime`]): - reply_to_message (Optional[:class:`telegram.Message`]): - text (Optional[str]): - audio (Optional[:class:`telegram.Audio`]): - document (Optional[:class:`telegram.Document`]): - photo (Optional[List[:class:`telegram.PhotoSize`]]): - sticker (Optional[:class:`telegram.Sticker`]): - video (Optional[:class:`telegram.Video`]): - voice (Optional[:class:`telegram.Voice`]): - caption (Optional[str]): - contact (Optional[:class:`telegram.Contact`]): - location (Optional[:class:`telegram.Location`]): - new_chat_participant (Optional[:class:`telegram.User`]): - left_chat_participant (Optional[:class:`telegram.User`]): - new_chat_title (Optional[str]): - new_chat_photo (Optional[List[:class:`telegram.PhotoSize`]): - delete_chat_photo (Optional[bool]): - group_chat_created (Optional[bool]): - """ - - def __init__(self, - message_id, - from_user, - date, - chat, - **kwargs): - # Required - self.message_id = int(message_id) - self.from_user = from_user - self.date = date - self.chat = chat - # Optionals - self.forward_from = kwargs.get('forward_from') - self.forward_date = kwargs.get('forward_date') - self.reply_to_message = kwargs.get('reply_to_message') - self.text = kwargs.get('text', '') - self.audio = kwargs.get('audio') - self.document = kwargs.get('document') - self.photo = kwargs.get('photo') - self.sticker = kwargs.get('sticker') - self.video = kwargs.get('video') - self.voice = kwargs.get('voice') - self.caption = kwargs.get('caption', '') - self.contact = kwargs.get('contact') - self.location = kwargs.get('location') - self.new_chat_participant = kwargs.get('new_chat_participant') - self.left_chat_participant = kwargs.get('left_chat_participant') - self.new_chat_title = kwargs.get('new_chat_title', '') - self.new_chat_photo = kwargs.get('new_chat_photo') - self.delete_chat_photo = bool(kwargs.get('delete_chat_photo', False)) - self.group_chat_created = bool(kwargs.get('group_chat_created', False)) - - @property - def chat_id(self): - """int: Short for :attr:`Message.chat.id`""" - return self.chat.id - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.Message: - """ - if not data: - return None - - data['from_user'] = User.de_json(data['from']) - data['date'] = datetime.fromtimestamp(data['date']) - if 'first_name' in data.get('chat', ''): - data['chat'] = User.de_json(data.get('chat')) - elif 'title' in data.get('chat', ''): - data['chat'] = GroupChat.de_json(data.get('chat')) - data['forward_from'] = \ - User.de_json(data.get('forward_from')) - data['forward_date'] = \ - Message._fromtimestamp(data.get('forward_date')) - data['reply_to_message'] = \ - Message.de_json(data.get('reply_to_message')) - data['audio'] = \ - Audio.de_json(data.get('audio')) - data['document'] = \ - Document.de_json(data.get('document')) - data['photo'] = \ - PhotoSize.de_list(data.get('photo')) - data['sticker'] = \ - Sticker.de_json(data.get('sticker')) - data['video'] = \ - Video.de_json(data.get('video')) - data['voice'] = \ - Voice.de_json(data.get('voice')) - data['contact'] = \ - Contact.de_json(data.get('contact')) - data['location'] = \ - Location.de_json(data.get('location')) - data['new_chat_participant'] = \ - User.de_json(data.get('new_chat_participant')) - data['left_chat_participant'] = \ - User.de_json(data.get('left_chat_participant')) - data['new_chat_photo'] = \ - PhotoSize.de_list(data.get('new_chat_photo')) - - return Message(**data) - - def __getitem__(self, item): - if item in self.__dict__.keys(): - return self.__dict__[item] - elif item == 'chat_id': - return self.chat.id - - def to_dict(self): - """ - Returns: - dict: - """ - data = super(Message, self).to_dict() - - # Required - data['from'] = data.pop('from_user') - data['date'] = self._totimestamp(self.date) - # Optionals - if self.forward_date: - data['forward_date'] = self._totimestamp(self.forward_date) - if self.photo: - data['photo'] = [p.to_dict() for p in self.photo] - if self.new_chat_photo: - data['new_chat_photo'] = [p.to_dict() for p in self.new_chat_photo] - - return data - - @staticmethod - def _fromtimestamp(unixtime): - """ - Args: - unixtime (int): - - Returns: - datetime.datetime: - """ - if not unixtime: - return None - - return datetime.fromtimestamp(unixtime) - - @staticmethod - def _totimestamp(dt_obj): - """ - Args: - dt_obj (:class:`datetime.datetime`): - - Returns: - int: - """ - if not dt_obj: - return None - - try: - # Python 3.3+ - return int(dt_obj.timestamp()) - except AttributeError: - # Python 3 (< 3.3) and Python 2 - return int(mktime(dt_obj.timetuple())) diff --git a/lib/telegram/nullhandler.py b/lib/telegram/nullhandler.py deleted file mode 100644 index 50bd370e..00000000 --- a/lib/telegram/nullhandler.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a logging NullHandler""" - -import logging - - -class NullHandler(logging.Handler): - """This object represents a logging NullHandler.""" - - def emit(self, record): - """ - Args: - record (str): - """ - pass diff --git a/lib/telegram/parsemode.py b/lib/telegram/parsemode.py deleted file mode 100644 index 897693ac..00000000 --- a/lib/telegram/parsemode.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python -# pylint: disable=R0903 -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram Message Parse Modes""" - - -class ParseMode(object): - """This object represents a Telegram Message Parse Modes.""" - - MARKDOWN = 'Markdown' diff --git a/lib/telegram/photosize.py b/lib/telegram/photosize.py deleted file mode 100644 index adc47649..00000000 --- a/lib/telegram/photosize.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram PhotoSize""" - -from telegram import TelegramObject - - -class PhotoSize(TelegramObject): - """This object represents a Telegram PhotoSize. - - Attributes: - file_id (str): - width (int): - height (int): - file_size (int): - - Args: - file_id (str): - width (int): - height (int): - **kwargs: Arbitrary keyword arguments. - - Keyword Args: - file_size (Optional[int]): - """ - - def __init__(self, - file_id, - width, - height, - **kwargs): - # Required - self.file_id = file_id - self.width = int(width) - self.height = int(height) - # Optionals - self.file_size = int(kwargs.get('file_size', 0)) - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.PhotoSize: - """ - if not data: - return None - - return PhotoSize(**data) - - @staticmethod - def de_list(data): - """ - Args: - data (list): - - Returns: - List: - """ - if not data: - return [] - - photos = list() - for photo in data: - photos.append(PhotoSize.de_json(photo)) - - return photos diff --git a/lib/telegram/replykeyboardhide.py b/lib/telegram/replykeyboardhide.py deleted file mode 100644 index f2cb80bb..00000000 --- a/lib/telegram/replykeyboardhide.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram -ReplyKeyboardHide""" - -from telegram import ReplyMarkup - - -class ReplyKeyboardHide(ReplyMarkup): - """This object represents a Telegram ReplyKeyboardHide. - - Attributes: - hide_keyboard (bool): - selective (bool): - - Args: - hide_keyboard (bool): - **kwargs: Arbitrary keyword arguments. - - Keyword Args: - selective (Optional[bool]): - """ - - def __init__(self, - hide_keyboard=True, - **kwargs): - # Required - self.hide_keyboard = bool(hide_keyboard) - # Optionals - self.selective = bool(kwargs.get('selective', False)) - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.ReplyKeyboardHide: - """ - if not data: - return None - - return ReplyKeyboardHide(**data) diff --git a/lib/telegram/replykeyboardmarkup.py b/lib/telegram/replykeyboardmarkup.py deleted file mode 100644 index 39912ea3..00000000 --- a/lib/telegram/replykeyboardmarkup.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram -ReplyKeyboardMarkup""" - -from telegram import ReplyMarkup - - -class ReplyKeyboardMarkup(ReplyMarkup): - """This object represents a Telegram ReplyKeyboardMarkup. - - Attributes: - keyboard (List[List[str]]): - resize_keyboard (bool): - one_time_keyboard (bool): - selective (bool): - - Args: - keyboard (List[List[str]]): - **kwargs: Arbitrary keyword arguments. - - Keyword Args: - resize_keyboard (Optional[bool]): - one_time_keyboard (Optional[bool]): - selective (Optional[bool]): - """ - - def __init__(self, - keyboard, - **kwargs): - # Required - self.keyboard = keyboard - # Optionals - self.resize_keyboard = bool(kwargs.get('resize_keyboard', False)) - self.one_time_keyboard = bool(kwargs.get('one_time_keyboard', False)) - self.selective = bool(kwargs.get('selective', False)) - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.ReplyKeyboardMarkup: - """ - if not data: - return None - - return ReplyKeyboardMarkup(**data) diff --git a/lib/telegram/replymarkup.py b/lib/telegram/replymarkup.py deleted file mode 100644 index 1d086c89..00000000 --- a/lib/telegram/replymarkup.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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/]. - -"""Base class for Telegram ReplyMarkup Objects""" - -from telegram import TelegramObject - - -class ReplyMarkup(TelegramObject): - """Base class for Telegram ReplyMarkup Objects""" - - @staticmethod - def de_json(data): - pass diff --git a/lib/telegram/sticker.py b/lib/telegram/sticker.py deleted file mode 100644 index 06089e35..00000000 --- a/lib/telegram/sticker.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram Sticker""" - -from telegram import PhotoSize, TelegramObject - - -class Sticker(TelegramObject): - """This object represents a Telegram Sticker. - - Attributes: - file_id (str): - width (int): - height (int): - thumb (:class:`telegram.PhotoSize`): - file_size (int): - - Args: - file_id (str): - width (int): - height (int): - **kwargs: Arbitrary keyword arguments. - - Keyword Args: - thumb (Optional[:class:`telegram.PhotoSize`]): - file_size (Optional[int]): - """ - - def __init__(self, - file_id, - width, - height, - **kwargs): - # Required - self.file_id = str(file_id) - self.width = int(width) - self.height = int(height) - # Optionals - self.thumb = kwargs.get('thumb') - self.file_size = int(kwargs.get('file_size', 0)) - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.Sticker: - """ - if not data: - return None - - data['thumb'] = PhotoSize.de_json(data.get('thumb')) - - return Sticker(**data) diff --git a/lib/telegram/update.py b/lib/telegram/update.py deleted file mode 100644 index 3bccc7d2..00000000 --- a/lib/telegram/update.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram Update""" - -from telegram import Message, TelegramObject - - -class Update(TelegramObject): - """This object represents a Telegram Update. - - Attributes: - update_id (int): - message (:class:`telegram.Message`): - - Args: - update_id (int): - **kwargs: Arbitrary keyword arguments. - - Keyword Args: - message (Optional[:class:`telegram.Message`]): - """ - def __init__(self, - update_id, - **kwargs): - # Required - self.update_id = int(update_id) - # Optionals - self.message = kwargs.get('message') - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.Update: - """ - if not data: - return None - - data['message'] = Message.de_json(data['message']) - - return Update(**data) diff --git a/lib/telegram/user.py b/lib/telegram/user.py deleted file mode 100644 index 4fa88295..00000000 --- a/lib/telegram/user.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env python -# pylint: disable=C0103,W0622 -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram User""" - -from telegram import TelegramObject - - -class User(TelegramObject): - """This object represents a Telegram User. - - Attributes: - id (int): - first_name (str): - last_name (str): - username (str): - type (str): - - Args: - id (int): - first_name (str): - **kwargs: Arbitrary keyword arguments. - - Keyword Args: - type (Optional[str]): - last_name (Optional[str]): - username (Optional[str]): - """ - - def __init__(self, - id, - first_name, - **kwargs): - # Required - self.id = int(id) - self.first_name = first_name - # Optionals - self.type = kwargs.get('type', '') - self.last_name = kwargs.get('last_name', '') - self.username = kwargs.get('username', '') - - @property - def name(self): - """str: """ - if self.username: - return '@%s' % self.username - if self.last_name: - return '%s %s' % (self.first_name, self.last_name) - return self.first_name - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.User: - """ - if not data: - return None - - return User(**data) diff --git a/lib/telegram/userprofilephotos.py b/lib/telegram/userprofilephotos.py deleted file mode 100644 index bce623b3..00000000 --- a/lib/telegram/userprofilephotos.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram -UserProfilePhotos""" - -from telegram import PhotoSize, TelegramObject - - -class UserProfilePhotos(TelegramObject): - """This object represents a Telegram UserProfilePhotos. - - Attributes: - total_count (int): - photos (List[List[:class:`telegram.PhotoSize`]]): - - Args: - total_count (int): - photos (List[List[:class:`telegram.PhotoSize`]]): - """ - - def __init__(self, - total_count, - photos): - # Required - self.total_count = int(total_count) - self.photos = photos - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.UserProfilePhotos: - """ - if not data: - return None - - data['photos'] = [PhotoSize.de_list(photo) for photo in data['photos']] - - return UserProfilePhotos(**data) - - def to_dict(self): - """ - Returns: - dict: - """ - data = super(UserProfilePhotos, self).to_dict() - - data['photos'] = [] - for photo in self.photos: - data['photos'].append([x.to_dict() for x in photo]) - - return data diff --git a/lib/telegram/utils/__init__.py b/lib/telegram/utils/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/telegram/utils/request.py b/lib/telegram/utils/request.py deleted file mode 100644 index 5347f9c6..00000000 --- a/lib/telegram/utils/request.py +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env python -# pylint: disable=no-name-in-module,unused-import -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 methods to make POST and GET requests""" - -import json - -try: - from urllib.parse import urlencode - from urllib.request import urlopen, urlretrieve, Request - from urllib.error import HTTPError, URLError -except ImportError: - from urllib import urlencode, urlretrieve - from urllib2 import urlopen, Request - from urllib2 import HTTPError, URLError - -from telegram import (InputFile, TelegramError) - - -def _parse(json_data): - """Try and parse the JSON returned from Telegram and return an empty - dictionary if there is any error. - - Args: - url: - urllib.urlopen object - - Returns: - A JSON parsed as Python dict with results. - """ - data = json.loads(json_data.decode()) - - if not data.get('ok') and data.get('description'): - return data['description'] - - return data['result'] - - -def get(url): - """Request an URL. - Args: - url: - The web location we want to retrieve. - - Returns: - A JSON object. - """ - result = urlopen(url).read() - - return _parse(result) - - -def post(url, - data): - """Request an URL. - Args: - url: - The web location we want to retrieve. - data: - A dict of (str, unicode) key/value pairs. - - Returns: - A JSON object. - """ - try: - if InputFile.is_inputfile(data): - data = InputFile(data) - request = Request(url, - data=data.to_form(), - headers=data.headers) - else: - data = json.dumps(data) - request = Request(url, - data=data.encode(), - headers={'Content-Type': 'application/json'}) - - result = urlopen(request).read() - except HTTPError as error: - if error.getcode() == 403: - raise TelegramError('Unauthorized') - if error.getcode() == 502: - raise TelegramError('Bad Gateway') - - message = _parse(error.read()) - raise TelegramError(message) - - return _parse(result) - - -def download(url, - filename): - """Download a file by its URL. - Args: - url: - The web location we want to retrieve. - - filename: - The filename wihtin the path to download the file. - """ - - urlretrieve(url, filename) diff --git a/lib/telegram/video.py b/lib/telegram/video.py deleted file mode 100644 index d6930633..00000000 --- a/lib/telegram/video.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram Video""" - -from telegram import PhotoSize, TelegramObject - - -class Video(TelegramObject): - """This object represents a Telegram Video. - - Attributes: - file_id (str): - width (int): - height (int): - duration (int): - thumb (:class:`telegram.PhotoSize`): - mime_type (str): - file_size (int): - - Args: - file_id (str): - width (int): - height (int): - duration (int): - **kwargs: Arbitrary keyword arguments. - - Keyword Args: - thumb (Optional[:class:`telegram.PhotoSize`]): - mime_type (Optional[str]): - file_size (Optional[int]): - """ - - def __init__(self, - file_id, - width, - height, - duration, - **kwargs): - # Required - self.file_id = str(file_id) - self.width = int(width) - self.height = int(height) - self.duration = int(duration) - # Optionals - self.thumb = kwargs.get('thumb') - self.mime_type = str(kwargs.get('mime_type', '')) - self.file_size = int(kwargs.get('file_size', 0)) - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.Video: - """ - if not data: - return None - - data['thumb'] = PhotoSize.de_json(data.get('thumb')) - - return Video(**data) diff --git a/lib/telegram/voice.py b/lib/telegram/voice.py deleted file mode 100644 index 53dcdc44..00000000 --- a/lib/telegram/voice.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015 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 a object that represents a Telegram Voice""" - -from telegram import TelegramObject - - -class Voice(TelegramObject): - """This object represents a Telegram Voice. - - Attributes: - file_id (str): - duration (int): - mime_type (str): - file_size (int): - - Args: - file_id (str): - **kwargs: Arbitrary keyword arguments. - - Keyword Args: - duration (Optional[int]): - mime_type (Optional[str]): - file_size (Optional[int]): - """ - - def __init__(self, - file_id, - **kwargs): - # Required - self.file_id = str(file_id) - # Optionals - self.duration = int(kwargs.get('duration', 0)) - self.mime_type = str(kwargs.get('mime_type', '')) - self.file_size = int(kwargs.get('file_size', 0)) - - @staticmethod - def de_json(data): - """ - Args: - data (str): - - Returns: - telegram.Voice: - """ - if not data: - return None - - return Voice(**data) diff --git a/plexpy/notifiers.py b/plexpy/notifiers.py index 3cd40b35..9b211239 100644 --- a/plexpy/notifiers.py +++ b/plexpy/notifiers.py @@ -35,8 +35,6 @@ import json import oauth2 as oauth import pythontwitter as twitter -import telegram - from email.mime.text import MIMEText import smtplib import email.utils @@ -291,8 +289,8 @@ def get_notification_agent_config(config_id): iftttClient = IFTTT() return iftttClient.return_config_options() elif config_id == 13: - telegramClient = TELEGRAM() - return telegramClient.return_config_options() + telegramClient = TELEGRAM() + return telegramClient.return_config_options() else: return [] else: @@ -342,8 +340,8 @@ def send_notification(config_id, subject, body): iftttClient = IFTTT() iftttClient.notify(subject=subject, message=body) elif config_id == 13: - telegramClient = TELEGRAM() - telegramClient.notify(message=body, event=subject) + telegramClient = TELEGRAM() + telegramClient.notify(message=body, event=subject) else: logger.debug(u"PlexPy Notifier :: Unknown agent id received.") else: @@ -1447,11 +1445,6 @@ class TELEGRAM(object): self.bot_token = plexpy.CONFIG.TELEGRAM_BOT_TOKEN self.chat_id = plexpy.CONFIG.TELEGRAM_CHAT_ID - self.on_play = plexpy.CONFIG.TELEGRAM_ON_PLAY - self.on_stop = plexpy.CONFIG.TELEGRAM_ON_STOP - self.on_watched = plexpy.CONFIG.TELEGRAM_ON_WATCHED - - def conf(self, options): return cherrypy.config['config'].get('Telegram', options) @@ -1459,13 +1452,28 @@ class TELEGRAM(object): if not message or not event: return - bot = telegram.Bot(self.bot_token) + http_handler = HTTPSConnection("api.telegram.org") - bot.sendMessage(chat_id=self.chat_id, text=message.encode("utf-8")) + data = {'chat_id': self.chat_id, + 'text': message.encode("utf-8")} - logger.info(u"Telegram notifications sent.") + http_handler.request("POST", + "/bot%s/%s" % (self.bot_token, "sendMessage"), + headers={'Content-type': "application/x-www-form-urlencoded"}, + body=json.dumps(data)) - return True + response = http_handler.getresponse() + request_status = response.status + + if request_status == 200: + logger.info(u"Telegram notifications sent.") + return True + elif request_status >= 400 and request_status < 500: + logger.info(u"Telegram request failed: %s" % response.reason) + return False + else: + logger.info(u"Telegram notification failed serverside.") + return False def updateLibrary(self): #For uniformity reasons not removed @@ -1479,16 +1487,16 @@ class TELEGRAM(object): self.notify('Main Screen Activate', 'Test Message') def return_config_options(self): - config_option = [{'label': 'Telegram Bot ID', + config_option = [{'label': 'Telegram Bot Token', 'value': self.bot_token, 'name': 'telegram_bot_token', - 'description': 'Your Bot ID here.', + 'description': 'Your Bot Token here.', 'input_type': 'text' }, {'label': 'Telegram Chat ID', 'value': self.chat_id, 'name': 'telegram_chat_id', - 'description': 'Your Telegram Chat or Group ID.', + 'description': 'Your Telegram Chat ID or Group ID.', 'input_type': 'text' } ]