From 17c28576226aeffd68527bb26c280e44302c853b Mon Sep 17 00:00:00 2001 From: Oleg Shlyazhko Date: Sat, 23 Jan 2016 14:24:34 +0300 Subject: [PATCH 01/16] add module for botan analytics --- telegram/utils/botan.py | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 telegram/utils/botan.py diff --git a/telegram/utils/botan.py b/telegram/utils/botan.py new file mode 100644 index 000000000..da1d7ee53 --- /dev/null +++ b/telegram/utils/botan.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +import json + +try: + from urllib.request import urlopen, Request + from urllib.parse import quote + from urllib.error import URLError +except ImportError: + from urllib2 import urlopen, Request + from urllib import quote + from urllib2 import URLError + + +class Botan(object): + token = '' + url_template = 'https://api.botan.io/track?token={token}&uid={uid}&name={name}' + + def __init__(self, token): + self.token = token + + def track(self, message, event_name='event'): + try: + uid = message.chat_id + except AttributeError: + print('no chat_id in message') + return False + data = json.dumps(message.__dict__) + try: + url = self.url_template.format(token=str(self.token), uid=str(uid), name=quote(event_name)) + request = Request(url, + data=data, + headers={'Content-Type': 'application/json'}) + response = urlopen(request, json.dumps(data)) + if response.getcode() != 200: + return False + return True + except URLError as error: + print('botan track error ' + str(error.code) + ':' + error.reason) + print(url) + return False + From 7931045bf3fa1ef2ba171498121d8935043ed131 Mon Sep 17 00:00:00 2001 From: Oleg Shlyazhko Date: Sat, 23 Jan 2016 14:24:49 +0300 Subject: [PATCH 02/16] test for botan analytics module --- tests/botan.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/botan.py diff --git a/tests/botan.py b/tests/botan.py new file mode 100644 index 000000000..304618f5f --- /dev/null +++ b/tests/botan.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python + +"""This module contains a object that represents Tests for Botan analytics integration""" + +import os +import unittest +import sys +sys.path.append('.') + +from telegram.utils.botan import Botan +from tests.base import BaseTest + +class MessageMock(object): + chat_id = None + + def __init__(self, chat_id): + self.chat_id = chat_id + +class BotanTest(BaseTest, unittest.TestCase): + """This object represents Tests for Botan analytics integration.""" + token = os.environ.get('TOKEN') + + def test_track(self): + """Test sending event to botan""" + print('Test sending event to botan') + botan = Botan(self.token) + message = MessageMock(self._chat_id) + result = botan.track(message, 'named event') + self.assertTrue(result) + + + def test_track_fail(self): + """Test fail when sending event to botan""" + print('Test fail when sending event to botan') + botan = Botan(self.token) + botan.url_template = 'https://api.botan.io/traccc?token={token}&uid={uid}&name={name}' + message = MessageMock(self._chat_id) + result = botan.track(message, 'named event') + self.assertFalse(result) + +if __name__ == '__main__': + unittest.main() From 545767ea40fed4f5b420c9d8f3d04f0a243a9a4b Mon Sep 17 00:00:00 2001 From: Oleg Shlyazhko Date: Sat, 23 Jan 2016 14:25:09 +0300 Subject: [PATCH 03/16] add myself to authors --- AUTHORS.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.rst b/AUTHORS.rst index cc898d1fc..c21c55e0e 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -20,6 +20,7 @@ The following wonderful people contributed directly or indirectly to this projec - `naveenvhegde `_ - `njittam `_ - `Noam Meltzer `_ +- `Oleg Shlyazhko `_ - `Rahiel Kasim `_ - `sooyhwang `_ - `wjt `_ From adb446abf699ece2491b802cd0c0d57915ddb074 Mon Sep 17 00:00:00 2001 From: Oleg Shlyazhko Date: Sat, 23 Jan 2016 15:14:17 +0300 Subject: [PATCH 04/16] fix pep8 styling --- telegram/utils/botan.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/telegram/utils/botan.py b/telegram/utils/botan.py index da1d7ee53..1f98af585 100644 --- a/telegram/utils/botan.py +++ b/telegram/utils/botan.py @@ -14,7 +14,8 @@ except ImportError: class Botan(object): token = '' - url_template = 'https://api.botan.io/track?token={token}&uid={uid}&name={name}' + url_template = 'https://api.botan.io/track?' \ + 'token={token}&uid={uid}&name={name}' def __init__(self, token): self.token = token @@ -27,7 +28,9 @@ class Botan(object): return False data = json.dumps(message.__dict__) try: - url = self.url_template.format(token=str(self.token), uid=str(uid), name=quote(event_name)) + url = self.url_template.format(token=str(self.token), + uid=str(uid), + name=quote(event_name)) request = Request(url, data=data, headers={'Content-Type': 'application/json'}) @@ -39,4 +42,3 @@ class Botan(object): print('botan track error ' + str(error.code) + ':' + error.reason) print(url) return False - From 5b05bcc8f2621947aee492bdba233eff0031755a Mon Sep 17 00:00:00 2001 From: Oleg Shlyazhko Date: Sat, 23 Jan 2016 15:21:13 +0300 Subject: [PATCH 05/16] add http error exception handling --- telegram/utils/botan.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/telegram/utils/botan.py b/telegram/utils/botan.py index 1f98af585..4db59a0e7 100644 --- a/telegram/utils/botan.py +++ b/telegram/utils/botan.py @@ -5,11 +5,11 @@ import json try: from urllib.request import urlopen, Request from urllib.parse import quote - from urllib.error import URLError + from urllib.error import URLError, HTTPError except ImportError: from urllib2 import urlopen, Request from urllib import quote - from urllib2 import URLError + from urllib2 import URLError, HTTPError class Botan(object): @@ -38,7 +38,9 @@ class Botan(object): if response.getcode() != 200: return False return True - except URLError as error: + except HTTPError as error: print('botan track error ' + str(error.code) + ':' + error.reason) - print(url) + return False + except URLError as error: + print('botan track error ' + error.reason) return False From 2c12bd6775be0a6f3d2be36dd29b895d300ce479 Mon Sep 17 00:00:00 2001 From: Oleg Shlyazhko Date: Sat, 23 Jan 2016 16:58:01 +0300 Subject: [PATCH 06/16] replace print with logging --- telegram/utils/botan.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/telegram/utils/botan.py b/telegram/utils/botan.py index 4db59a0e7..67d33fe65 100644 --- a/telegram/utils/botan.py +++ b/telegram/utils/botan.py @@ -1,6 +1,8 @@ #!/usr/bin/env python import json +import logging +from telegram import NullHandler try: from urllib.request import urlopen, Request @@ -11,6 +13,9 @@ except ImportError: from urllib import quote from urllib2 import URLError, HTTPError +H = NullHandler() +logging.getLogger(__name__).addHandler(H) + class Botan(object): token = '' @@ -19,12 +24,13 @@ class Botan(object): def __init__(self, token): self.token = token + self.logger = logging.getLogger(__name__) def track(self, message, event_name='event'): try: uid = message.chat_id except AttributeError: - print('no chat_id in message') + self.logger.warn('No chat_id in message') return False data = json.dumps(message.__dict__) try: @@ -39,8 +45,9 @@ class Botan(object): return False return True except HTTPError as error: - print('botan track error ' + str(error.code) + ':' + error.reason) + self.logger.warn('Botan track error ' + + str(error.code) + ':' + error.reason) return False except URLError as error: - print('botan track error ' + error.reason) + self.logger.warn('Botan track error ' + error.reason) return False From bb2cce56a387a0d665ae37569788f0188d7794ab Mon Sep 17 00:00:00 2001 From: Oleg Shlyazhko Date: Sat, 23 Jan 2016 16:58:44 +0300 Subject: [PATCH 07/16] insert correct appmetrica token instead of bot token in botan test --- tests/botan.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/botan.py b/tests/botan.py index 304618f5f..b33521b0e 100644 --- a/tests/botan.py +++ b/tests/botan.py @@ -18,7 +18,8 @@ class MessageMock(object): class BotanTest(BaseTest, unittest.TestCase): """This object represents Tests for Botan analytics integration.""" - token = os.environ.get('TOKEN') + + token = '26c6df87-56ea-4764-a588-0e25de3a64a9' def test_track(self): """Test sending event to botan""" From 7508c2f8bf6e6b585799a96500819d75b2a3aa77 Mon Sep 17 00:00:00 2001 From: Oleg Shlyazhko Date: Sat, 23 Jan 2016 16:59:53 +0300 Subject: [PATCH 08/16] add detailed comment in class and src key to tracking url --- telegram/utils/botan.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/telegram/utils/botan.py b/telegram/utils/botan.py index 67d33fe65..9d8716146 100644 --- a/telegram/utils/botan.py +++ b/telegram/utils/botan.py @@ -18,9 +18,12 @@ logging.getLogger(__name__).addHandler(H) class Botan(object): + """This class helps to send incoming events in your botan analytics account. + See more: https://github.com/botanio/sdk#botan-sdk""" + token = '' - url_template = 'https://api.botan.io/track?' \ - 'token={token}&uid={uid}&name={name}' + url_template = 'https://api.botan.io/track?token={token}' \ + '&uid={uid}&name={name}&src=python-telegram-bot' def __init__(self, token): self.token = token From 5a2a541ae0426402d757a3647c3ef4d78dcab6ad Mon Sep 17 00:00:00 2001 From: Oleg Shlyazhko Date: Sat, 23 Jan 2016 19:09:56 +0300 Subject: [PATCH 09/16] rename botan test correctly and move token to ENV --- tests/{botan.py => test_botan.py} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests/{botan.py => test_botan.py} (95%) diff --git a/tests/botan.py b/tests/test_botan.py similarity index 95% rename from tests/botan.py rename to tests/test_botan.py index b33521b0e..f99eb1b84 100644 --- a/tests/botan.py +++ b/tests/test_botan.py @@ -19,7 +19,7 @@ class MessageMock(object): class BotanTest(BaseTest, unittest.TestCase): """This object represents Tests for Botan analytics integration.""" - token = '26c6df87-56ea-4764-a588-0e25de3a64a9' + token = os.environ.get('BOTAN_TOKEN') def test_track(self): """Test sending event to botan""" From 0faa38b8afb905fedc9bb7f11b39e1e6d8081760 Mon Sep 17 00:00:00 2001 From: Oleg Shlyazhko Date: Sat, 23 Jan 2016 19:29:01 +0300 Subject: [PATCH 10/16] fix httperror logging --- telegram/utils/botan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telegram/utils/botan.py b/telegram/utils/botan.py index 9d8716146..1dd8c4478 100644 --- a/telegram/utils/botan.py +++ b/telegram/utils/botan.py @@ -49,7 +49,7 @@ class Botan(object): return True except HTTPError as error: self.logger.warn('Botan track error ' + - str(error.code) + ':' + error.reason) + str(error.code) + ':' + error.read()) return False except URLError as error: self.logger.warn('Botan track error ' + error.reason) From 80b53f1ab702a1662c0f5489509dafccd622ec58 Mon Sep 17 00:00:00 2001 From: Oleg Shlyazhko Date: Sat, 23 Jan 2016 19:44:40 +0300 Subject: [PATCH 11/16] fix urlopen call --- telegram/utils/botan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telegram/utils/botan.py b/telegram/utils/botan.py index 1dd8c4478..5b29c9ff2 100644 --- a/telegram/utils/botan.py +++ b/telegram/utils/botan.py @@ -43,7 +43,7 @@ class Botan(object): request = Request(url, data=data, headers={'Content-Type': 'application/json'}) - response = urlopen(request, json.dumps(data)) + response = urlopen(request) if response.getcode() != 200: return False return True From d1e4eeaf306276c7eb2cf481531878fa2a5b90a8 Mon Sep 17 00:00:00 2001 From: Oleg Shlyazhko Date: Sat, 23 Jan 2016 19:49:55 +0300 Subject: [PATCH 12/16] fix urlopen data format --- telegram/utils/botan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telegram/utils/botan.py b/telegram/utils/botan.py index 5b29c9ff2..0f9cbeedc 100644 --- a/telegram/utils/botan.py +++ b/telegram/utils/botan.py @@ -41,7 +41,7 @@ class Botan(object): uid=str(uid), name=quote(event_name)) request = Request(url, - data=data, + data=data.encode(), headers={'Content-Type': 'application/json'}) response = urlopen(request) if response.getcode() != 200: From 383a2d3742480f7f2bf1026e9384ddf56d812589 Mon Sep 17 00:00:00 2001 From: Oleg Shlyazhko Date: Sat, 23 Jan 2016 20:03:29 +0300 Subject: [PATCH 13/16] fix httperror error output --- telegram/utils/botan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/telegram/utils/botan.py b/telegram/utils/botan.py index 0f9cbeedc..075e146bc 100644 --- a/telegram/utils/botan.py +++ b/telegram/utils/botan.py @@ -49,7 +49,7 @@ class Botan(object): return True except HTTPError as error: self.logger.warn('Botan track error ' + - str(error.code) + ':' + error.read()) + str(error.code) + ':' + error.read().decode('utf-8')) return False except URLError as error: self.logger.warn('Botan track error ' + error.reason) From 9eec34edd1719836fa6359f4248aec111a413ffb Mon Sep 17 00:00:00 2001 From: Oleg Shlyazhko Date: Sat, 23 Jan 2016 20:13:48 +0300 Subject: [PATCH 14/16] pep8 fix --- telegram/utils/botan.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/telegram/utils/botan.py b/telegram/utils/botan.py index 075e146bc..37c8c928f 100644 --- a/telegram/utils/botan.py +++ b/telegram/utils/botan.py @@ -49,7 +49,8 @@ class Botan(object): return True except HTTPError as error: self.logger.warn('Botan track error ' + - str(error.code) + ':' + error.read().decode('utf-8')) + str(error.code) + + ':' + error.read().decode('utf-8')) return False except URLError as error: self.logger.warn('Botan track error ' + error.reason) From c3bca9af486c2c341d2b57ac1d3288d1310bff5d Mon Sep 17 00:00:00 2001 From: Oleg Shlyazhko Date: Sun, 24 Jan 2016 18:28:27 +0300 Subject: [PATCH 15/16] remove checking for non 200 http codes, exceptions already handle it --- telegram/utils/botan.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/telegram/utils/botan.py b/telegram/utils/botan.py index 37c8c928f..1c6b774c3 100644 --- a/telegram/utils/botan.py +++ b/telegram/utils/botan.py @@ -43,9 +43,7 @@ class Botan(object): request = Request(url, data=data.encode(), headers={'Content-Type': 'application/json'}) - response = urlopen(request) - if response.getcode() != 200: - return False + urlopen(request) return True except HTTPError as error: self.logger.warn('Botan track error ' + @@ -53,5 +51,5 @@ class Botan(object): ':' + error.read().decode('utf-8')) return False except URLError as error: - self.logger.warn('Botan track error ' + error.reason) + self.logger.warn('Botan track error ' + str(error.reason)) return False From 1000a56e0de74d91de1c5861d5d728e884e9966a Mon Sep 17 00:00:00 2001 From: Oleg Shlyazhko Date: Sun, 24 Jan 2016 18:32:12 +0300 Subject: [PATCH 16/16] more test vor botan module, increase coverage --- tests/test_botan.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tests/test_botan.py b/tests/test_botan.py index f99eb1b84..1206b8bab 100644 --- a/tests/test_botan.py +++ b/tests/test_botan.py @@ -10,12 +10,14 @@ sys.path.append('.') from telegram.utils.botan import Botan from tests.base import BaseTest + class MessageMock(object): chat_id = None def __init__(self, chat_id): self.chat_id = chat_id + class BotanTest(BaseTest, unittest.TestCase): """This object represents Tests for Botan analytics integration.""" @@ -29,7 +31,6 @@ class BotanTest(BaseTest, unittest.TestCase): result = botan.track(message, 'named event') self.assertTrue(result) - def test_track_fail(self): """Test fail when sending event to botan""" print('Test fail when sending event to botan') @@ -39,5 +40,23 @@ class BotanTest(BaseTest, unittest.TestCase): result = botan.track(message, 'named event') self.assertFalse(result) + def test_wrong_message(self): + """Test sending wrong message""" + print('Test sending wrong message') + botan = Botan(self.token) + message = MessageMock(self._chat_id) + message = delattr(message, 'chat_id') + result = botan.track(message, 'named event') + self.assertFalse(result) + + def test_wrong_endpoint(self): + """Test wrong endpoint""" + print('Test wrong endpoint') + botan = Botan(self.token) + botan.url_template = 'https://api.botaaaaan.io/traccc?token={token}&uid={uid}&name={name}' + message = MessageMock(self._chat_id) + result = botan.track(message, 'named event') + self.assertFalse(result) + if __name__ == '__main__': unittest.main()