move isFileRequest to InputFile as @staticmethod, new tests written, README updated

This commit is contained in:
leandrotoledo 2015-07-14 05:24:08 -03:00
parent 7d8fcc5fb9
commit d8912f5290
4 changed files with 83 additions and 67 deletions

View file

@ -135,7 +135,7 @@ To post an Emoji (special thanks to `Tim Whitlock <http://apps.timwhitlock.info/
>>> bot.sendMessage(chat_id=chat_id, text=telegram.Emoji.PILE_OF_POO) >>> bot.sendMessage(chat_id=chat_id, text=telegram.Emoji.PILE_OF_POO)
To post an image file via URL:: To post an image file via URL (right now only sendPhoto supports this)::
>>> bot.sendPhoto(chat_id=chat_id, photo='https://telegram.org/img/t_logo.png') >>> bot.sendPhoto(chat_id=chat_id, photo='https://telegram.org/img/t_logo.png')

View file

@ -533,27 +533,6 @@ class Bot(object):
return True return True
def _isFileRequest(self,
data=None):
"""Check if the request is a file request
Args:
data:
A dict of (str, unicode) key/value pairs
Returns:
bool
"""
if data:
file_types = ['audio', 'document', 'photo', 'video']
file_type = [i for i in data.keys() if i in file_types]
if file_type:
file_content = data[file_type[0]]
return isinstance(file_content, file) or \
str(file_content).startswith('http')
return False
def _requestUrl(self, def _requestUrl(self,
url, url,
method, method,
@ -574,7 +553,7 @@ class Bot(object):
if method == 'POST': if method == 'POST':
try: try:
if self._isFileRequest(data): if InputFile.is_inputfile(data):
data = InputFile(data) data = InputFile(data)
request = urllib2.Request( request = urllib2.Request(
@ -619,25 +598,11 @@ class Bot(object):
try: try:
data = json.loads(json_data.decode()) data = json.loads(json_data.decode())
self._checkForTelegramError(data) if not data['ok']:
raise TelegramError(data['description'])
except ValueError: except ValueError:
if '<title>403 Forbidden</title>' in json_data: if '<title>403 Forbidden</title>' in json_data:
raise TelegramError({'message': 'API must be authenticated'}) raise TelegramError({'message': 'API must be authenticated'})
raise TelegramError({'message': 'JSON decoding'}) raise TelegramError({'message': 'JSON decoding'})
return data['result'] return data['result']
def _checkForTelegramError(self,
data):
"""Raises a TelegramError if Telegram returns an error message.
Args:
data:
A Python dict created from the Telegram JSON response.
Raises:
TelegramError wrapping the Telegram error message if one exists.
"""
if not data['ok']:
raise TelegramError(data['description'])

View file

@ -7,6 +7,12 @@ import os
import re import re
import urllib2 import urllib2
from .error import TelegramError
DEFAULT_MIME_TYPE = 'application/octet-stream'
USER_AGENT = 'Python Telegram Bot' \
' (https://github.com/leandrotoledo/python-telegram-bot)'
class InputFile(object): class InputFile(object):
def __init__(self, def __init__(self,
@ -31,17 +37,16 @@ class InputFile(object):
self.input_file_content = self.input_file.read() self.input_file_content = self.input_file.read()
self.filename = os.path.basename(self.input_file.name) self.filename = os.path.basename(self.input_file.name)
self.mimetype = mimetypes.guess_type(self.filename)[0] or \ self.mimetype = mimetypes.guess_type(self.filename)[0] or \
'application/octet-stream' DEFAULT_MIME_TYPE
if 'http' in self.input_file: if 'http' in self.input_file:
self.input_file_content = urllib2.urlopen(self.input_file).read() self.input_file_content = urllib2.urlopen(self.input_file).read()
self.mimetype = InputFile.image_type(self.input_file_content) self.mimetype = InputFile.is_image(self.input_file_content)
self.filename = self.mimetype.replace('/', '.') self.filename = self.mimetype.replace('/', '.')
@property @property
def headers(self): def headers(self):
return {'User-agent': 'Python Telegram Bot (https://github.com/leandrotoledo/python-telegram-bot)', return {'User-agent': USER_AGENT,
'Content-type': self.content_type} 'Content-type': self.content_type}
@property @property
@ -66,7 +71,7 @@ class InputFile(object):
form_boundary, form_boundary,
str('Content-Disposition: form-data; name="%s"; filename="%s"' % ( str('Content-Disposition: form-data; name="%s"; filename="%s"' % (
self.input_name, self.filename self.input_name, self.filename
)), )),
'Content-Type: %s' % self.mimetype, 'Content-Type: %s' % self.mimetype,
'', '',
self.input_file_content self.input_file_content
@ -78,15 +83,54 @@ class InputFile(object):
return '\r\n'.join(form) return '\r\n'.join(form)
@staticmethod @staticmethod
def image_type(stream): def is_image(stream):
header = stream[:10] """Check if the content file is an image by analyzing its headers.
if re.match(r'GIF8', header): Args:
return 'image/gif' stream:
A str representing the content of a file.
if re.match(r'\x89PNG', header): Returns:
return 'image/png' The str mimetype of an image.
"""
try:
header = stream[:10]
if re.match(r'\xff\xd8\xff\xe0\x00\x10JFIF', header) or \ if re.match(r'GIF8', header):
re.match(r'\xff\xd8\xff\xe1(.*){2}Exif', header): return 'image/gif'
return 'image/jpeg'
if re.match(r'\x89PNG', header):
return 'image/png'
if re.match(r'\xff\xd8\xff\xe0\x00\x10JFIF', header) or \
re.match(r'\xff\xd8\xff\xe1(.*){2}Exif', header):
return 'image/jpeg'
except IndexError as e:
raise TelegramError(str(e))
raise TelegramError({'message': 'Could not parse file content'})
@staticmethod
def is_inputfile(data):
"""Check if the request is a file request
Args:
data:
A dict of (str, unicode) key/value pairs
Returns:
bool
"""
if data:
file_types = ['audio', 'document', 'photo', 'video']
file_type = [i for i in data.keys() if i in file_types]
if file_type:
file_content = data[file_type[0]]
if file_type[0] == 'photo':
return isinstance(file_content, file) or \
str(file_content).startswith('http')
return isinstance(file_content, file)
return False

View file

@ -16,11 +16,11 @@ class BotTest(unittest.TestCase):
def testGetMe(self): def testGetMe(self):
'''Test the telegram.Bot getMe method''' '''Test the telegram.Bot getMe method'''
print('Testing getMe') print('Testing getMe')
user = self._bot.getMe() bot = self._bot.getMe()
self.assertEqual(120405045, user.id) self.assertEqual(120405045, bot.id)
self.assertEqual('Toledo\'s Palace Bot', user.first_name) self.assertEqual('Toledo\'s Palace Bot', bot.first_name)
self.assertEqual(None, user.last_name) self.assertEqual(None, bot.last_name)
self.assertEqual('ToledosPalaceBot', user.username) self.assertEqual('ToledosPalaceBot', bot.username)
def testSendMessage(self): def testSendMessage(self):
'''Test the telegram.Bot sendMessage method''' '''Test the telegram.Bot sendMessage method'''
@ -33,7 +33,7 @@ class BotTest(unittest.TestCase):
'''Test the telegram.Bot getUpdates method''' '''Test the telegram.Bot getUpdates method'''
print('Testing getUpdates') print('Testing getUpdates')
updates = self._bot.getUpdates() updates = self._bot.getUpdates()
self.assertEqual(129566614, updates[0].update_id) self.assertIsInstance(updates[0], telegram.Update)
def testForwardMessage(self): def testForwardMessage(self):
'''Test the telegram.Bot forwardMessage method''' '''Test the telegram.Bot forwardMessage method'''
@ -58,6 +58,13 @@ class BotTest(unittest.TestCase):
chat_id=12173560) chat_id=12173560)
self.assertEqual('AgADAQADr6cxGzU8LQe6q0dMJD2rHYkP2ykABFymiQqJgjxRGGMAAgI', message.photo[0].file_id) self.assertEqual('AgADAQADr6cxGzU8LQe6q0dMJD2rHYkP2ykABFymiQqJgjxRGGMAAgI', message.photo[0].file_id)
def testSendURLPhoto(self):
'''Test the telegram.Bot sendPhoto method'''
print('Testing sendPhoto - URL')
message = self._bot.sendPhoto(photo=str('http://dummyimage.com/600x400/000/fff.jpg&text=telegram'),
chat_id=12173560)
self.assertEqual(822, message.photo[0].file_size)
def testSendAudio(self): def testSendAudio(self):
'''Test the telegram.Bot sendAudio method''' '''Test the telegram.Bot sendAudio method'''
print('Testing sendAudio - File') print('Testing sendAudio - File')
@ -86,13 +93,6 @@ class BotTest(unittest.TestCase):
chat_id=12173560) chat_id=12173560)
self.assertEqual('BQADAQADHAADNTwtBxZxUGKyxYbYAg', message.document.file_id) self.assertEqual('BQADAQADHAADNTwtBxZxUGKyxYbYAg', message.document.file_id)
def testResendSticker(self):
'''Test the telegram.Bot sendSticker method'''
print('Testing sendSticker - Resend')
message = self._bot.sendSticker(sticker=str('BQADAQADHAADyIsGAAFZfq1bphjqlgI'),
chat_id=12173560)
self.assertEqual(39518, message.sticker.file_size)
def testSendVideo(self): def testSendVideo(self):
'''Test the telegram.Bot sendVideo method''' '''Test the telegram.Bot sendVideo method'''
print('Testing sendVideo - File') print('Testing sendVideo - File')
@ -107,6 +107,13 @@ class BotTest(unittest.TestCase):
chat_id=12173560) chat_id=12173560)
self.assertEqual(4, message.video.duration) self.assertEqual(4, message.video.duration)
def testResendSticker(self):
'''Test the telegram.Bot sendSticker method'''
print('Testing sendSticker - Resend')
message = self._bot.sendSticker(sticker=str('BQADAQADHAADyIsGAAFZfq1bphjqlgI'),
chat_id=12173560)
self.assertEqual(39518, message.sticker.file_size)
def testSendLocation(self): def testSendLocation(self):
'''Test the telegram.Bot sendLocation method''' '''Test the telegram.Bot sendLocation method'''
print('Testing sendLocation') print('Testing sendLocation')