Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b79530b

Browse files
committed
Adding File and its tests
1 parent 778c63a commit b79530b

File tree

6 files changed

+311
-9
lines changed

6 files changed

+311
-9
lines changed

README.rst

+7
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ sendLocation Yes
9494
sendChatAction Yes
9595
getUpdates Yes
9696
getUserProfilePhotos Yes
97+
getFile Yes
9798
setWebhook Yes
9899
========================= ============
99100

@@ -220,6 +221,12 @@ To hide `Custom Keyboards <https://core.telegram.org/bots#keyboards>`_::
220221
>>> reply_markup = telegram.ReplyKeyboardHide()
221222
>>> bot.sendMessage(chat_id=chat_id, text="I'm back.", reply_markup=reply_markup)
222223

224+
To download a file (you will need its file_id)::
225+
226+
>>> file_id = message.voice.file_id
227+
>>> newFile = bot.getFile(file_id)
228+
>>> newFile.download('voice.ogg')
229+
223230
There are many more API methods, to read the full API documentation::
224231

225232
$ pydoc telegram.Bot

telegram/__init__.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,17 @@
4040
from .forcereply import ForceReply
4141
from .error import TelegramError
4242
from .inputfile import InputFile
43+
from .file import File
4344
from .nullhandler import NullHandler
4445
from .emoji import Emoji
4546
from .parsemode import ParseMode
4647
from .message import Message
4748
from .update import Update
4849
from .bot import Bot
49-
from .command_handler import *
5050

5151
__all__ = ['Bot', 'Emoji', 'TelegramError', 'InputFile', 'ReplyMarkup',
5252
'ForceReply', 'ReplyKeyboardHide', 'ReplyKeyboardMarkup',
5353
'UserProfilePhotos', 'ChatAction', 'Location', 'Contact',
54-
'Video', 'Sticker', 'Document', 'Audio', 'PhotoSize', 'GroupChat',
55-
'Update', 'ParseMode', 'Message', 'User', 'TelegramObject', 'NullHandler',
56-
'Voice', 'CommandHandler', 'CommandHandlerWithHelp',
57-
'CommandHandlerWithFatherCommand', 'CommandHandlerWithHelpAndFather']
54+
'Video', 'Sticker', 'Document', 'File', 'Audio', 'PhotoSize',
55+
'GroupChat', 'Update', 'ParseMode', 'Message', 'User',
56+
'TelegramObject', 'NullHandler', 'Voice']

telegram/bot.py

+32-2
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@
2222
import functools
2323
import logging
2424

25-
from telegram import (User, Message, Update, UserProfilePhotos, TelegramError,
26-
ReplyMarkup, TelegramObject, NullHandler)
25+
from telegram import (User, Message, Update, UserProfilePhotos, File,
26+
TelegramError, ReplyMarkup, TelegramObject, NullHandler)
2727
from telegram.utils import request
2828

2929
H = NullHandler()
3030
logging.getLogger(__name__).addHandler(H)
3131

3232

3333
class Bot(TelegramObject):
34+
3435
"""This object represents a Telegram Bot.
3536
3637
Attributes:
@@ -58,6 +59,8 @@ def __init__(self,
5859
else:
5960
self.base_url = base_url + self.token
6061

62+
self.base_file_url = 'https://api.telegram.org/file/bot%s' % self.token
63+
6164
self.bot = None
6265

6366
self.logger = logging.getLogger(__name__)
@@ -615,6 +618,33 @@ def getUserProfilePhotos(self,
615618

616619
return UserProfilePhotos.de_json(result)
617620

621+
@log
622+
def getFile(self,
623+
file_id):
624+
"""Use this method to get basic info about a file and prepare it for
625+
downloading. For the moment, bots can download files of up to 20MB in
626+
size.
627+
628+
Args:
629+
file_id:
630+
File identifier to get info about.
631+
632+
Returns:
633+
Returns a telegram.File object
634+
"""
635+
636+
url = '%s/getFile' % self.base_url
637+
638+
data = {'file_id': file_id}
639+
640+
result = request.post(url, data)
641+
642+
if result.get('file_path'):
643+
result['file_path'] = '%s/%s' % (self.base_file_url,
644+
result['file_path'])
645+
646+
return File.de_json(result)
647+
618648
@log
619649
def getUpdates(self,
620650
offset=None,

telegram/file.py

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#!/usr/bin/env python
2+
#
3+
# A library that provides a Python interface to the Telegram Bot API
4+
# Copyright (C) 2015 Leandro Toledo de Souza <[email protected]>
5+
#
6+
# This program is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU Lesser Public License as published by
8+
# the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU Lesser Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Lesser Public License
17+
# along with this program. If not, see [http://www.gnu.org/licenses/].
18+
19+
"""This module contains a object that represents a Telegram File"""
20+
21+
from os.path import basename
22+
23+
from telegram import TelegramObject
24+
from telegram.utils.request import download as _download
25+
26+
27+
class File(TelegramObject):
28+
29+
"""This object represents a Telegram File.
30+
31+
Attributes:
32+
file_id (str):
33+
file_size (str):
34+
file_path (str):
35+
36+
Args:
37+
file_id (str):
38+
**kwargs: Arbitrary keyword arguments.
39+
40+
Keyword Args:
41+
file_size (Optional[int]):
42+
file_path (Optional[str]):
43+
"""
44+
45+
def __init__(self,
46+
file_id,
47+
**kwargs):
48+
# Required
49+
self.file_id = str(file_id)
50+
# Optionals
51+
self.file_size = int(kwargs.get('file_size', 0))
52+
self.file_path = str(kwargs.get('file_path', ''))
53+
54+
@staticmethod
55+
def de_json(data):
56+
"""
57+
Args:
58+
data (str):
59+
60+
Returns:
61+
telegram.File:
62+
"""
63+
if not data:
64+
return None
65+
66+
return File(**data)
67+
68+
def download(self,
69+
custom_path=None):
70+
"""
71+
Args:
72+
custom_path (str):
73+
"""
74+
url = self.file_path
75+
76+
if custom_path:
77+
filename = basename(custom_path)
78+
else:
79+
filename = basename(url)
80+
81+
_download(url, filename)

telegram/utils/request.py

+16-2
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323

2424
try:
2525
from urllib.parse import urlencode
26-
from urllib.request import urlopen, Request
26+
from urllib.request import urlopen, urlretrieve, Request
2727
from urllib.error import HTTPError, URLError
2828
except ImportError:
29-
from urllib import urlencode
29+
from urllib import urlencode, urlretrieve
3030
from urllib2 import urlopen, Request
3131
from urllib2 import HTTPError, URLError
3232

@@ -99,3 +99,17 @@ def post(url,
9999
raise TelegramError(message)
100100

101101
return _parse(result)
102+
103+
104+
def download(url,
105+
filename):
106+
"""Download a file by its URL.
107+
Args:
108+
url:
109+
The web location we want to retrieve.
110+
111+
filename:
112+
The filename wihtin the path to download the file.
113+
"""
114+
115+
urlretrieve(url, filename)

tests/test_file.py

+171
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
#!/usr/bin/env python
2+
#
3+
# A library that provides a Python interface to the Telegram Bot API
4+
# Copyright (C) 2015 Leandro Toledo de Souza <[email protected]>
5+
#
6+
# This program is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU General Public License as published by
8+
# the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU General Public License
17+
# along with this program. If not, see [http://www.gnu.org/licenses/].
18+
19+
"""This module contains a object that represents Tests for Telegram File"""
20+
21+
import os
22+
import unittest
23+
import sys
24+
sys.path.append('.')
25+
26+
import telegram
27+
from tests.base import BaseTest
28+
29+
30+
class FileTest(BaseTest, unittest.TestCase):
31+
"""This object represents Tests for Telegram File."""
32+
33+
def setUp(self):
34+
self.audio_file_id = 'BQADAQADDwADHyP1B6PSPq2HjX8kAg'
35+
self.document_file_id = 'BQADAQADpAADHyP1B04ipZxJTe2BAg'
36+
self.sticker_file_id = 'BQADAQADHAADyIsGAAFZfq1bphjqlgI'
37+
self.video_file_id = 'BAADAQADXwADHyP1BwJFTcmY2RYCAg'
38+
self.voice_file_id = 'AwADAQADTgADHyP1B_mbw34svXPHAg'
39+
40+
41+
self.json_dict = {
42+
'file_id': self.audio_file_id,
43+
'file_path': 'https://api.telegram.org/file/bot133505823:AAHZFMHno3mzVLErU5b5jJvaeG--qUyLyG0/document/file_3',
44+
'file_size': 28232
45+
}
46+
47+
def test_get_and_download_file_audio(self):
48+
"""Test telegram.Bot getFile method - Audio"""
49+
print('Testing bot.getFile - With Audio.file_id')
50+
51+
newFile = self._bot.getFile(self.audio_file_id)
52+
53+
self.assertEqual(newFile.file_size, 28232)
54+
self.assertEqual(newFile.file_id, self.audio_file_id)
55+
self.assertTrue(newFile.file_path.startswith('https://'))
56+
57+
newFile.download('telegram.mp3')
58+
59+
self.assertTrue(os.path.isfile('telegram.mp3'))
60+
61+
def test_get_and_download_file_document(self):
62+
"""Test telegram.Bot getFile method - Document"""
63+
print('Testing bot.getFile - With Document.file_id')
64+
65+
newFile = self._bot.getFile(self.document_file_id)
66+
67+
self.assertEqual(newFile.file_size, 12948)
68+
self.assertEqual(newFile.file_id, self.document_file_id)
69+
self.assertTrue(newFile.file_path.startswith('https://'))
70+
71+
newFile.download('telegram.png')
72+
73+
self.assertTrue(os.path.isfile('telegram.png'))
74+
75+
def test_get_and_download_file_sticker(self):
76+
"""Test telegram.Bot getFile method - Sticker"""
77+
print('Testing bot.getFile - With Sticker.file_id')
78+
79+
newFile = self._bot.getFile(self.sticker_file_id)
80+
81+
self.assertEqual(newFile.file_size, 39518)
82+
self.assertEqual(newFile.file_id, self.sticker_file_id)
83+
self.assertTrue(newFile.file_path.startswith('https://'))
84+
85+
newFile.download('telegram.webp')
86+
87+
self.assertTrue(os.path.isfile('telegram.webp'))
88+
89+
def test_get_and_download_file_video(self):
90+
"""Test telegram.Bot getFile method - Video"""
91+
print('Testing bot.getFile - With Video.file_id')
92+
93+
newFile = self._bot.getFile(self.video_file_id)
94+
95+
self.assertEqual(newFile.file_size, 326534)
96+
self.assertEqual(newFile.file_id, self.video_file_id)
97+
self.assertTrue(newFile.file_path.startswith('https://'))
98+
99+
newFile.download('telegram.mp4')
100+
101+
self.assertTrue(os.path.isfile('telegram.mp4'))
102+
103+
def test_get_and_download_file_voice(self):
104+
"""Test telegram.Bot getFile method - Voice"""
105+
print('Testing bot.getFile - With Voice.file_id')
106+
107+
newFile = self._bot.getFile(self.voice_file_id)
108+
109+
self.assertEqual(newFile.file_size, 9199)
110+
self.assertEqual(newFile.file_id, self.voice_file_id)
111+
self.assertTrue(newFile.file_path.startswith('https://'))
112+
113+
newFile.download('telegram.ogg')
114+
115+
self.assertTrue(os.path.isfile('telegram.ogg'))
116+
117+
def test_file_de_json(self):
118+
"""Test File.de_json() method"""
119+
print('Testing File.de_json()')
120+
121+
newFile = telegram.File.de_json(self.json_dict)
122+
123+
self.assertEqual(newFile.file_id, self.json_dict['file_id'])
124+
self.assertEqual(newFile.file_path, self.json_dict['file_path'])
125+
self.assertEqual(newFile.file_size, self.json_dict['file_size'])
126+
127+
def test_file_to_json(self):
128+
"""Test File.to_json() method"""
129+
print('Testing File.to_json()')
130+
131+
newFile = telegram.File.de_json(self.json_dict)
132+
133+
self.assertTrue(self.is_json(newFile.to_json()))
134+
135+
def test_file_to_dict(self):
136+
"""Test File.to_dict() method"""
137+
print('Testing File.to_dict()')
138+
139+
newFile = telegram.File.de_json(self.json_dict)
140+
141+
self.assertTrue(self.is_dict(newFile.to_dict()))
142+
self.assertEqual(newFile['file_id'], self.json_dict['file_id'])
143+
self.assertEqual(newFile['file_path'], self.json_dict['file_path'])
144+
self.assertEqual(newFile['file_size'], self.json_dict['file_size'])
145+
146+
def test_error_get_empty_file_id(self):
147+
print('Testing bot.getFile - Null file_id')
148+
149+
json_dict = self.json_dict
150+
151+
json_dict['file_id'] = ''
152+
del(json_dict['file_path'])
153+
del(json_dict['file_size'])
154+
155+
self.assertRaises(telegram.TelegramError,
156+
lambda: self._bot.getFile(**json_dict))
157+
158+
def test_error_file_without_required_args(self):
159+
print('Testing bot.getFile - Without required arguments')
160+
161+
json_dict = self.json_dict
162+
163+
del(json_dict['file_id'])
164+
del(json_dict['file_path'])
165+
del(json_dict['file_size'])
166+
167+
self.assertRaises(TypeError,
168+
lambda: self._bot.getFile(**json_dict))
169+
170+
if __name__ == '__main__':
171+
unittest.main()

0 commit comments

Comments
 (0)