From fd1f16598bd57faa53656ff61a5a22dc39273301 Mon Sep 17 00:00:00 2001 From: pieter Date: Fri, 18 Sep 2015 20:31:29 +0200 Subject: [PATCH 1/4] Added File & getFile, including testing --- README.md | 10 ++++++++++ telebot/__init__.py | 3 +++ telebot/apihelper.py | 4 ++++ telebot/types.py | 20 ++++++++++++++++++++ tests/test_telebot.py | 8 ++++++++ 5 files changed, 45 insertions(+) diff --git a/README.md b/README.md index 15708ac..c950015 100644 --- a/README.md +++ b/README.md @@ -251,6 +251,16 @@ tb.send_location(chat_id, lat, lon) # action_string can be one of the following strings: 'typing', 'upload_photo', 'record_video', 'upload_video', # 'record_audio', 'upload_audio', 'upload_document' or 'find_location'. tb.send_chat_action(chat_id, action_string) + +# getFile +# Downloading a file is straightforward +# Returns a File object +import requests +file_info = tb.get_file(file_id) + +file = requests.get('https://api.telegram.org/file/bot{0}/{1}'.format(API_TOKEN, file_info.file_path)) + + ``` #### Reply markup All `send_xyz` functions of TeleBot take an optional `reply_markup` argument. This argument must be an instance of `ReplyKeyboardMarkup`, `ReplyKeyboardHide` or `ForceReply`, which are defined in types.py. diff --git a/telebot/__init__.py b/telebot/__init__.py index 3474c09..c7ae6f6 100644 --- a/telebot/__init__.py +++ b/telebot/__init__.py @@ -169,6 +169,9 @@ class TeleBot: result = apihelper.get_me(self.token) return types.User.de_json(result) + def get_file(self, file_id): + return types.File.de_json(apihelper.get_file(self.token, file_id)) + def get_user_profile_photos(self, user_id, offset=None, limit=None): """ Retrieves the user profile photos of the person with 'user_id' diff --git a/telebot/apihelper.py b/telebot/apihelper.py index 07e8d3e..2a26b2f 100644 --- a/telebot/apihelper.py +++ b/telebot/apihelper.py @@ -61,6 +61,10 @@ def get_me(token): method_url = 'getMe' return _make_request(token, method_url) +def get_file(token, file_id): + method_url = 'getFile' + return _make_request(token, method_url, params={'file_id': file_id}) + def send_message(token, chat_id, text, disable_web_page_preview=None, reply_to_message_id=None, reply_markup=None, parse_mode=None): diff --git a/telebot/types.py b/telebot/types.py index 37d84ea..e71ac05 100644 --- a/telebot/types.py +++ b/telebot/types.py @@ -408,6 +408,26 @@ class UserProfilePhotos(JsonDeserializable): self.total_count = total_count self.photos = photos +class File(JsonDeserializable): + + @classmethod + def de_json(cls, json_type): + obj = cls.check_json(json_type) + file_id = obj['file_id'] + + file_size = None + file_path = None + if 'file_size' in obj: + file_size = obj['file_size'] + if 'file_path' in obj: + file_path = obj['file_path'] + return File(file_id, file_size, file_path) + + def __init__(self, file_id, file_size, file_path): + self.file_id = file_id + self.file_size = file_size + self.file_path = file_path + class ForceReply(JsonSerializable): def __init__(self, selective=None): diff --git a/tests/test_telebot.py b/tests/test_telebot.py index 6090bec..2c26da3 100644 --- a/tests/test_telebot.py +++ b/tests/test_telebot.py @@ -155,6 +155,14 @@ class TestTeleBot: ret_msg = tb.send_voice(CHAT_ID, file_data) assert ret_msg.voice.mime_type == 'audio/ogg' + def test_get_file(self): + file_data = open('./test_data/record.ogg') + tb = telebot.TeleBot(TOKEN) + ret_msg = tb.send_voice(CHAT_ID, file_data) + file_id = ret_msg.voice.file_id + file_info = tb.get_file(file_id) + assert file_info.file_id == file_id + def test_send_message(self): text = 'CI Test Message' tb = telebot.TeleBot(TOKEN) From 1038d4fafaf952fd4466286d77571244b62eb0ae Mon Sep 17 00:00:00 2001 From: pieter Date: Fri, 18 Sep 2015 20:53:10 +0200 Subject: [PATCH 2/4] Added download_file --- telebot/__init__.py | 7 +++---- telebot/apihelper.py | 20 +++++++++++++++++--- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/telebot/__init__.py b/telebot/__init__.py index c7ae6f6..7274187 100644 --- a/telebot/__init__.py +++ b/telebot/__init__.py @@ -22,10 +22,6 @@ from telebot import apihelper, types, util """ Module : telebot """ - -API_URL = r"https://api.telegram.org/" - - class TeleBot: """ This is TeleBot Class Methods: @@ -172,6 +168,9 @@ class TeleBot: def get_file(self, file_id): return types.File.de_json(apihelper.get_file(self.token, file_id)) + def download_file(self, file_path): + return apihelper.download_file(self.token, file_path) + def get_user_profile_photos(self, user_id, offset=None, limit=None): """ Retrieves the user profile photos of the person with 'user_id' diff --git a/telebot/apihelper.py b/telebot/apihelper.py index 2a26b2f..0e9e14b 100644 --- a/telebot/apihelper.py +++ b/telebot/apihelper.py @@ -7,8 +7,11 @@ from telebot import util logger = telebot.logger +API_URL = "https://api.telegram.org/bot{0}/{1}" +FILE_URL = "https://api.telegram.org/file/bot{0}/{1}" -def _make_request(token, method_name, method='get', params=None, files=None): + +def _make_request(token, method_name, method='get', params=None, files=None, base_url=API_URL): """ Makes a request to the Telegram API. :param token: The bot's API token. (Created with @BotFather) @@ -18,10 +21,10 @@ def _make_request(token, method_name, method='get', params=None, files=None): :param files: Optional files. :return: The result parsed to a JSON dictionary. """ - request_url = telebot.API_URL + 'bot' + token + '/' + method_name + request_url = base_url.format(token, method_name) logger.debug("Request: method={0} url={1} params={2} files={3}".format(method, request_url, params, files)) result = requests.request(method, request_url, params=params, files=files) - logger.debug("The server returned: '{0}'".format(result.text)) + logger.debug("The server returned: '{0}'".format(result.text.encode('utf8'))) return _check_result(method_name, result)['result'] @@ -61,11 +64,22 @@ def get_me(token): method_url = 'getMe' return _make_request(token, method_url) + def get_file(token, file_id): method_url = 'getFile' return _make_request(token, method_url, params={'file_id': file_id}) +def download_file(token, file_path): + url = FILE_URL.format(token, file_path) + result = requests.get(url) + if result.status_code != 200: + msg = 'The server returned HTTP {0} {1}. Response body:\n[{2}]'\ + .format(result.status_code, result.reason, result.text) + raise ApiException(msg, 'Download file', result) + return result.content + + def send_message(token, chat_id, text, disable_web_page_preview=None, reply_to_message_id=None, reply_markup=None, parse_mode=None): """ From 61b4ca8a37e534386a7dcda9ba3944b9b3de1e15 Mon Sep 17 00:00:00 2001 From: pieter Date: Fri, 18 Sep 2015 20:54:22 +0200 Subject: [PATCH 3/4] Added download_file and created an example --- examples/download_file_example.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 examples/download_file_example.py diff --git a/examples/download_file_example.py b/examples/download_file_example.py new file mode 100644 index 0000000..d9003d1 --- /dev/null +++ b/examples/download_file_example.py @@ -0,0 +1,15 @@ +import telebot + +TOKEN = 'YOUR BOT TOKEN' +CHAT_ID = 'YOUR CHAT ID' + +bot = telebot.TeleBot(TOKEN) + +ret_msg = bot.send_voice(CHAT_ID, open('tests/test_data/record.ogg')) + +file_info = bot.get_file(ret_msg.voice.file_id) + +downloaded_file = bot.download_file(file_info.file_path) + +with open('new_file.ogg', 'wb') as new_file: + new_file.write(downloaded_file) From 19b4e35ee5d41e603b1954d47a0ef2a30e4203fc Mon Sep 17 00:00:00 2001 From: pieter Date: Fri, 18 Sep 2015 21:11:56 +0200 Subject: [PATCH 4/4] Attempt to fix failing test case --- tests/test_telebot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_telebot.py b/tests/test_telebot.py index 2c26da3..8c72302 100644 --- a/tests/test_telebot.py +++ b/tests/test_telebot.py @@ -156,7 +156,7 @@ class TestTeleBot: assert ret_msg.voice.mime_type == 'audio/ogg' def test_get_file(self): - file_data = open('./test_data/record.ogg') + file_data = open('./test_data/record.ogg', 'rb') tb = telebot.TeleBot(TOKEN) ret_msg = tb.send_voice(CHAT_ID, file_data) file_id = ret_msg.voice.file_id