Removing redundant parentheses, Python3 support, user.name property

This commit is contained in:
leandrotoledo 2015-07-15 10:05:31 -03:00
parent 9f27537176
commit 92c3f48cda
6 changed files with 96 additions and 68 deletions

View file

@ -1,4 +1,9 @@
language: python language: python
python: python:
- 2.7 - "2.6"
- "2.7"
- "3.2"
- "3.3"
- "3.4"
- "nightly"
script: make test script: make test

View file

@ -4,8 +4,14 @@
"""A library that provides a Python interface to the Telegram Bot API""" """A library that provides a Python interface to the Telegram Bot API"""
import json import json
import urllib try:
import urllib2 from urllib.parse import urlencode
from urllib.request import urlopen, Request
from urllib.error import HTTPError, URLError
except ImportError:
from urllib import urlencode
from urllib2 import urlopen, Request
from urllib2 import HTTPError, URLError
import functools import functools
from telegram import (User, Message, Update, UserProfilePhotos, TelegramError, from telegram import (User, Message, Update, UserProfilePhotos, TelegramError,
@ -28,30 +34,22 @@ class Bot(object):
try: try:
bot = self.getMe() bot = self.getMe()
self._id = bot.id self.id = bot.id
self._first_name = bot.first_name self.first_name = bot.first_name
self._last_name = bot.last_name self.last_name = bot.last_name
self._username = bot.username self.username = bot.username
self.__auth = True self.__auth = True
except TelegramError: except TelegramError:
raise TelegramError({'message': 'Bad token'}) raise TelegramError({'message': 'Bad token'})
@property @property
def id(self): def name(self):
return self._id if self.username:
return '@%s' % self.username
@property if self.last_name:
def first_name(self): return '%s %s' % (self.first_name, self.last_name)
return self._first_name return self.first_name
@property
def last_name(self):
return self._last_name
@property
def username(self):
return self._username
def clearCredentials(self): def clearCredentials(self):
"""Clear any credentials for this instance. """Clear any credentials for this instance.
@ -65,7 +63,7 @@ class Bot(object):
A telegram.User instance representing that bot if the A telegram.User instance representing that bot if the
credentials are valid, None otherwise. credentials are valid, None otherwise.
""" """
url = '%s/getMe' % (self.base_url) url = '%s/getMe' % self.base_url
json_data = self._requestUrl(url, 'GET') json_data = self._requestUrl(url, 'GET')
data = self._parseAndCheckTelegram(json_data) data = self._parseAndCheckTelegram(json_data)
@ -141,7 +139,7 @@ class Bot(object):
A telegram.Message instance representing the message posted. A telegram.Message instance representing the message posted.
""" """
url = '%s/sendMessage' % (self.base_url) url = '%s/sendMessage' % self.base_url
data = {'chat_id': chat_id, data = {'chat_id': chat_id,
'text': text} 'text': text}
@ -149,7 +147,7 @@ class Bot(object):
if disable_web_page_preview: if disable_web_page_preview:
data['disable_web_page_preview'] = disable_web_page_preview data['disable_web_page_preview'] = disable_web_page_preview
return (url, data) return url, data
@message @message
@require_authentication @require_authentication
@ -172,7 +170,7 @@ class Bot(object):
A telegram.Message instance representing the message forwarded. A telegram.Message instance representing the message forwarded.
""" """
url = '%s/forwardMessage' % (self.base_url) url = '%s/forwardMessage' % self.base_url
data = {} data = {}
if chat_id: if chat_id:
@ -182,7 +180,7 @@ class Bot(object):
if message_id: if message_id:
data['message_id'] = message_id data['message_id'] = message_id
return (url, data) return url, data
@message @message
@require_authentication @require_authentication
@ -215,7 +213,7 @@ class Bot(object):
A telegram.Message instance representing the message posted. A telegram.Message instance representing the message posted.
""" """
url = '%s/sendPhoto' % (self.base_url) url = '%s/sendPhoto' % self.base_url
data = {'chat_id': chat_id, data = {'chat_id': chat_id,
'photo': photo} 'photo': photo}
@ -223,7 +221,7 @@ class Bot(object):
if caption: if caption:
data['caption'] = caption data['caption'] = caption
return (url, data) return url, data
@message @message
@require_authentication @require_authentication
@ -255,12 +253,12 @@ class Bot(object):
A telegram.Message instance representing the message posted. A telegram.Message instance representing the message posted.
""" """
url = '%s/sendAudio' % (self.base_url) url = '%s/sendAudio' % self.base_url
data = {'chat_id': chat_id, data = {'chat_id': chat_id,
'audio': audio} 'audio': audio}
return (url, data) return url, data
@message @message
@require_authentication @require_authentication
@ -289,12 +287,12 @@ class Bot(object):
A telegram.Message instance representing the message posted. A telegram.Message instance representing the message posted.
""" """
url = '%s/sendDocument' % (self.base_url) url = '%s/sendDocument' % self.base_url
data = {'chat_id': chat_id, data = {'chat_id': chat_id,
'document': document} 'document': document}
return (url, data) return url, data
@message @message
@require_authentication @require_authentication
@ -323,12 +321,12 @@ class Bot(object):
A telegram.Message instance representing the message posted. A telegram.Message instance representing the message posted.
""" """
url = '%s/sendSticker' % (self.base_url) url = '%s/sendSticker' % self.base_url
data = {'chat_id': chat_id, data = {'chat_id': chat_id,
'sticker': sticker} 'sticker': sticker}
return (url, data) return url, data
@message @message
@require_authentication @require_authentication
@ -358,12 +356,12 @@ class Bot(object):
A telegram.Message instance representing the message posted. A telegram.Message instance representing the message posted.
""" """
url = '%s/sendVideo' % (self.base_url) url = '%s/sendVideo' % self.base_url
data = {'chat_id': chat_id, data = {'chat_id': chat_id,
'video': video} 'video': video}
return (url, data) return url, data
@message @message
@require_authentication @require_authentication
@ -393,13 +391,13 @@ class Bot(object):
A telegram.Message instance representing the message posted. A telegram.Message instance representing the message posted.
""" """
url = '%s/sendLocation' % (self.base_url) url = '%s/sendLocation' % self.base_url
data = {'chat_id': chat_id, data = {'chat_id': chat_id,
'latitude': latitude, 'latitude': latitude,
'longitude': longitude} 'longitude': longitude}
return (url, data) return url, data
@message @message
@require_authentication @require_authentication
@ -425,12 +423,12 @@ class Bot(object):
- ChatAction.FIND_LOCATION for location data. - ChatAction.FIND_LOCATION for location data.
""" """
url = '%s/sendChatAction' % (self.base_url) url = '%s/sendChatAction' % self.base_url
data = {'chat_id': chat_id, data = {'chat_id': chat_id,
'action': action} 'action': action}
return (url, data) return url, data
@require_authentication @require_authentication
def getUserProfilePhotos(self, def getUserProfilePhotos(self,
@ -453,7 +451,7 @@ class Bot(object):
Returns a telegram.UserProfilePhotos object. Returns a telegram.UserProfilePhotos object.
""" """
url = '%s/getUserProfilePhotos' % (self.base_url) url = '%s/getUserProfilePhotos' % self.base_url
data = {'user_id': user_id} data = {'user_id': user_id}
@ -492,7 +490,7 @@ class Bot(object):
A list of telegram.Update objects are returned. A list of telegram.Update objects are returned.
""" """
url = '%s/getUpdates' % (self.base_url) url = '%s/getUpdates' % self.base_url
data = {} data = {}
if offset: if offset:
@ -524,7 +522,7 @@ class Bot(object):
Returns: Returns:
True if successful else TelegramError was raised True if successful else TelegramError was raised
""" """
url = '%s/setWebhook' % (self.base_url) url = '%s/setWebhook' % self.base_url
data = {'url': webhook_url} data = {'url': webhook_url}
@ -556,29 +554,29 @@ class Bot(object):
if InputFile.is_inputfile(data): if InputFile.is_inputfile(data):
data = InputFile(data) data = InputFile(data)
request = urllib2.Request( request = Request(
url, url,
data=data.to_form(), data=data.to_form(),
headers=data.headers headers=data.headers
) )
return urllib2.urlopen(request).read() return urlopen(request).read()
else: else:
return urllib2.urlopen( return urlopen(
url, url,
urllib.urlencode(data) urlencode(data).encode()
).read() ).read()
except IOError as e: except IOError as e:
raise TelegramError(str(e)) raise TelegramError(str(e))
except urllib2.HTTPError as e: except HTTPError as e:
raise TelegramError(str(e)) raise TelegramError(str(e))
except urllib2.URLError as e: except URLError as e:
raise TelegramError(str(e)) raise TelegramError(str(e))
if method == 'GET': if method == 'GET':
try: try:
return urllib2.urlopen(url).read() return urlopen(url).read()
except urllib2.URLError as e: except URLError as e:
raise TelegramError(str(e)) raise TelegramError(str(e))
return 0 # if not a POST or GET request return 0 # if not a POST or GET request

View file

@ -1,11 +1,16 @@
#!/usr/bin/env python #!/usr/bin/env python
try:
import mimetools 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 mimetypes
import os import os
import re import re
import urllib2 import sys
from .error import TelegramError from .error import TelegramError
@ -18,7 +23,7 @@ class InputFile(object):
def __init__(self, def __init__(self,
data): data):
self.data = data self.data = data
self.boundary = mimetools.choose_boundary() self.boundary = choose_boundary()
if 'audio' in data: if 'audio' in data:
self.input_name = 'audio' self.input_name = 'audio'
@ -40,7 +45,7 @@ class InputFile(object):
DEFAULT_MIME_TYPE 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 = urlopen(self.input_file).read()
self.mimetype = InputFile.is_image(self.input_file_content) self.mimetype = InputFile.is_image(self.input_file_content)
self.filename = self.mimetype.replace('/', '.') self.filename = self.mimetype.replace('/', '.')
@ -58,10 +63,10 @@ class InputFile(object):
form_boundary = '--' + self.boundary form_boundary = '--' + self.boundary
# Add data fields # Add data fields
for name, value in self.data.iteritems(): for name, value in self.data.items():
form.extend([ form.extend([
form_boundary, form_boundary,
str('Content-Disposition: form-data; name="%s"' % name), 'Content-Disposition: form-data; name="%s"' % name,
'', '',
str(value) str(value)
]) ])
@ -69,9 +74,9 @@ class InputFile(object):
# Add input_file to upload # Add input_file to upload
form.extend([ form.extend([
form_boundary, form_boundary,
str('Content-Disposition: form-data; name="%s"; filename="%s"' % ( '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
@ -80,6 +85,19 @@ class InputFile(object):
form.append('--' + self.boundary + '--') form.append('--' + self.boundary + '--')
form.append('') form.append('')
return self._parse(form)
def _parse(self, form):
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) return '\r\n'.join(form)
@staticmethod @staticmethod
@ -96,14 +114,14 @@ class InputFile(object):
try: try:
header = stream[:10] header = stream[:10]
if re.match(r'GIF8', header): if re.match(b'GIF8', header):
return 'image/gif' return 'image/gif'
if re.match(r'\x89PNG', header): if re.match(b'\x89PNG', header):
return 'image/png' return 'image/png'
if re.match(r'\xff\xd8\xff\xe0\x00\x10JFIF', header) or \ if re.match(b'\xff\xd8\xff\xe0\x00\x10JFIF', header) or \
re.match(r'\xff\xd8\xff\xe1(.*){2}Exif', header): re.match(b'\xff\xd8\xff\xe1(.*){2}Exif', header):
return 'image/jpeg' return 'image/jpeg'
except IndexError as e: except IndexError as e:
raise TelegramError(str(e)) raise TelegramError(str(e))
@ -122,7 +140,7 @@ class InputFile(object):
""" """
if data: if data:
file_types = ['audio', 'document', 'photo', 'video'] file_types = ['audio', 'document', 'photo', 'video']
file_type = [i for i in data.keys() if i in file_types] file_type = [i for i in list(data.keys()) if i in file_types]
if file_type: if file_type:
file_content = data[file_type[0]] file_content = data[file_type[0]]

View file

@ -83,7 +83,7 @@ class Message(object):
reply_to_message = None reply_to_message = None
if 'text' in data: if 'text' in data:
text = data['text'].encode('utf-8') text = data['text']
else: else:
text = None text = None

View file

@ -15,6 +15,14 @@ class User(object):
self.last_name = last_name self.last_name = last_name
self.username = username self.username = username
@property
def name(self):
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 @staticmethod
def de_json(data): def de_json(data):
return User(id=data.get('id', None), return User(id=data.get('id', None),

View file

@ -1,6 +1,5 @@
#!/usr/bin/env python #!/usr/bin/env python
# encoding: utf-8 # encoding: utf-8
import os import os
import telegram import telegram
import unittest import unittest
@ -27,7 +26,7 @@ class BotTest(unittest.TestCase):
print('Testing sendMessage') print('Testing sendMessage')
message = self._bot.sendMessage(chat_id=12173560, message = self._bot.sendMessage(chat_id=12173560,
text='Моё судно на воздушной подушке полно угрей') text='Моё судно на воздушной подушке полно угрей')
self.assertEqual('Моё судно на воздушной подушке полно угрей', message.text) self.assertEqual(u'Моё судно на воздушной подушке полно угрей', message.text)
def testGetUpdates(self): def testGetUpdates(self):
'''Test the telegram.Bot getUpdates method''' '''Test the telegram.Bot getUpdates method'''