Compare commits

...

190 Commits

Author SHA1 Message Date
Leandro Toledo c6533a2d69 Releasing v2.9 2015-11-10 12:21:04 -02:00
Leandro Toledo 6c13762c93 Fixes PEP8 and Lint minor issues 2015-11-10 12:10:50 -02:00
Leandro Toledo 06c09b96cf Fixes travis to support future module 2015-11-10 12:04:21 -02:00
Leandro Toledo 8a5ec3b2a1 Merge pull request #92 from jh0ker/emoticons
Decode Emoji byte strings into unicode strings if using Python 3 (Alternative)
2015-11-10 11:58:57 -02:00
Leandro Toledo 21c26aed2f Merge pull request #96 from leandrotoledo/revert-85-master
Revert 1879cff82d
2015-11-10 11:55:50 -02:00
Leandro Toledo 5fe1481ae9 Revert 1879cff82d 2015-11-10 11:55:42 -02:00
Leandro Toledo 1879cff82d Merge pull request #85 from jh0ker/master
Decode Emoji byte strings into unicode strings if using Python 3
2015-11-10 11:55:19 -02:00
Jannes Höke cd5e805692 added documentation 2015-11-10 05:16:16 +01:00
Jannes Höke 90a77ab7a1 Merge pull request #87 from franciscod/patch-1
Remove `.encode('utf-8')` from echobot
2015-11-10 04:58:21 +01:00
Jannes Höke 3928e27cf4 Merge pull request #90 from rahiel/master
raise exception if telegram times out on long-polling
2015-11-10 04:56:18 +01:00
Leandro Toledo 45b1124553 Merge pull request #95 from rahiel/readme
fix LGPLv3 badge
2015-11-09 16:53:47 -02:00
Rahiel Kasim 252b43dcb7 fix LGPLv3 badge 2015-11-09 19:06:30 +01:00
Leandro Toledo d3d5c1e907 Merge pull request #91 from jh0ker/useroptional
Make user_from optional to work with channels channels
2015-11-04 09:52:00 -02:00
Jannes Höke cbf66d411d add jh0ker to AUTHORS.rst 2015-11-03 14:47:26 +01:00
Jannes Höke 0e5b48f3b4 Add tests for Emoji class, since it now contains actual code 2015-11-03 14:47:13 +01:00
Jannes Höke df7cfdc8d0 create file requirements.txt and add 'future' 2015-11-03 14:42:16 +01:00
Jannes Höke 89015e5ecc fix for sending into a channel 2015-11-03 13:46:23 +01:00
Jannes Höke 025d4c9a75 fix emojis for python3 2015-11-03 12:24:44 +01:00
Jannes Höke d3bea4c3b4 make user_from optional, because of channels 2015-11-03 10:28:06 +01:00
Jannes Höke a6c12adda2 make user_from optional, because of channels 2015-11-03 10:20:45 +01:00
Rahiel Kasim dcb9129809 raise exception if telegram times out on long-polling 2015-11-02 20:30:37 +01:00
Francisco Demartino bd1f171f51 Remove .encode('utf-8') from echobot
This was making the bot throw TypeError on py3.

Closes #86
2015-10-23 16:48:26 -03:00
Jannes Höke 54efb034a4 add jh0ker to AUTHORS.rst 2015-10-23 01:18:05 +02:00
Jannes Höke fe94f146bb Add tests for Emoji class, since it now contains actual code 2015-10-23 01:16:10 +02:00
Jannes Höke 22b492762b Decode Emoji byte strings into unicode strings if using Python 3 (missed something) 2015-10-23 00:32:10 +02:00
Jannes Höke fea0c5cc2b Decode Emoji byte strings into unicode strings if using Python 3 2015-10-23 00:29:26 +02:00
Leandro Toledo 688d6af541 Releasing v2.8.7 2015-10-08 11:31:48 -03:00
Leandro Toledo bcbd32cdd3 Merge branch 'master' of https://github.com/leandrotoledo/python-telegram-bot 2015-10-08 11:30:16 -03:00
Leandro Toledo 3fa8b97ed2 Type as optional for GroupChat 2015-10-08 11:30:02 -03:00
Leandro Toledo 7cd4e2e205 Update README.rst 2015-10-08 10:40:27 -03:00
Leandro Toledo f2b0cb46a2 Releasing v2.8.6 2015-10-08 10:23:12 -03:00
Leandro Toledo cf5d184766 Add type to User and GroupChat classes 2015-10-08 10:19:05 -03:00
Leandro Toledo 5738dc553f Releasing v2.8.5 2015-09-24 09:29:23 -03:00
Leandro Toledo 386accab80 Merge pull request #74 from leandrotoledo/http_bad_gateway_as_except
Handles HTTP Bad Gateway error (503) on request module #63
2015-09-24 09:26:19 -03:00
Leandro Toledo e7686db759 Merge pull request #73 from leandrotoledo/stop_casting_unicode_fields
Fixes regression on Audio and Document models for unicode fields #65
2015-09-24 09:26:10 -03:00
Leandro Toledo 6c9490f2c6 Handles HTTP Bad Gateway error (503) on request module #63 2015-09-24 09:17:50 -03:00
Leandro Toledo 855ab19dea Fixes regression on Audio and Document models for unicode fields #65 2015-09-24 09:10:33 -03:00
Leandro Toledo 797a3e6ea4 Update README.rst 2015-09-22 09:41:31 -03:00
Leandro Toledo bbd443d397 Merge pull request #71 from zeehio/patch-1
[doc] fix "Telegram sticker" -> "Telegram user"
2015-09-22 09:39:19 -03:00
Sergio Oller 4e1597c614 [doc] fix "Telegram user" -> "telegram sticker" 2015-09-22 11:52:10 +02:00
Leandro Toledo 75e338d5df Releasing v2.8.4 2015-09-20 12:52:40 -03:00
Leandro Toledo 1919f873c0 Fix tests 2015-09-20 12:47:02 -03:00
Leandro Toledo a1f35355f6 Keep bleeding edge features on testing branch 2015-09-20 12:43:32 -03:00
Leandro Toledo c4c17e8036 Merge branch 'testing' 2015-09-20 12:34:34 -03:00
Leandro Toledo 3024c1ce3d Merge branch 'master' into testing 2015-09-20 12:34:02 -03:00
Leandro Toledo b79530b10c Adding File and its tests 2015-09-20 12:28:10 -03:00
Leandro Toledo 778c63a6d3 Merge pull request #68 from leandrotoledo/revert-67-feature/requests
Revert "Feature/requests"
2015-09-16 00:22:03 -03:00
Leandro Toledo f623db06ea Revert "Feature/requests" 2015-09-16 00:21:45 -03:00
Leandro Toledo 026673dc05 Merge pull request #67 from peczony/feature/requests
Feature/requests
2015-09-16 00:17:38 -03:00
Leandro Toledo 6893da5dd3 Update keywords for pip package 2015-09-16 00:15:51 -03:00
pecheny d5a9c185f0 use requests instead of urllib if possible; add timeout and decorator to get and post 2015-09-14 19:13:22 +03:00
Leandro Toledo cbdeacd22d Releasing v2.8.3 2015-09-10 21:00:05 -03:00
Leandro Toledo 1e2fdedc45 Removing command_handler from master (under dev) 2015-09-10 20:44:23 -03:00
Leandro Toledo c1c0e66233 Merge branch 'testing' 2015-09-10 20:37:41 -03:00
Leandro Toledo eb557e0eba Keeping features under development off this release 2015-09-10 20:37:25 -03:00
Leandro Toledo a7ac4193fe PEP8, lint and TelegramError class refactor 2015-09-10 20:08:24 -03:00
Leandro Toledo 354bfcad79 legacy tests now run using BaseTest 2015-09-10 20:06:27 -03:00
Leandro Toledo a1e12d424c Fix inverted lat/long 2015-09-10 16:59:08 -03:00
Leandro Toledo 38c6d002c8 Merge pull request #60 from ergoz/ISSUE-58
Add Markdown support for sendMessage method.[#58]
2015-09-10 15:25:01 -03:00
ErgoZ c8a14bf34d Merge branch 'testing' of https://github.com/leandrotoledo/python-telegram-bot into ISSUE-58
Conflicts:
	telegram/__init__.py
2015-09-10 20:42:56 +03:00
ErgoZ 53c44f14bd Add Markdown support for sendMessage method. 2015-09-10 20:15:20 +03:00
Leandro Toledo e75deea25c Merge pull request #59 from ergoz/PR57-Fix
Code cleanup for filename. Filename uses only for sendDocument.
2015-09-10 08:56:11 -03:00
ErgoZ 17b8bb4881 Code cleanup for filename. Filename uses only for sendDocument. 2015-09-10 14:46:49 +03:00
leandrotoledo 009862593b Fix Py3 2015-09-09 09:34:45 -03:00
leandrotoledo e2fa052f54 Send JSON requests over urlencoded post data 2015-09-09 09:29:23 -03:00
leandrotoledo dcfe08dbda Add sticker as an inputfile 2015-09-09 09:28:58 -03:00
leandrotoledo dc2dfa24ad Adding .sublime 2015-09-09 09:12:59 -03:00
leandrotoledo ce58f45c4f Adding .sublime 2015-09-09 09:12:35 -03:00
Leandro Toledo 7059930b5d Merge pull request #55 from njittam/testing
add a father command. and hide commands in help.
2015-09-09 09:08:39 -03:00
leandrotoledo 77977b99b1 Add tests to custom filename arg #56 2015-09-08 15:52:10 -03:00
Leandro Toledo ed77afaab9 Merge pull request #57 from ergoz/testing
Add ability for custom filename in send methods and InputFile
2015-09-08 15:22:58 -03:00
ErgoZ Riftbit Vaper c7f2add463 small pretty fix for self.data.pop('filename') 2015-09-08 21:17:54 +03:00
ErgoZ Riftbit Vaper 8a074fd719 Delete unused check (forget from previous local version) 2015-09-08 21:13:11 +03:00
leandrotoledo cfa5e8a6fe Using nose to run tests 2015-09-08 15:03:04 -03:00
leandrotoledo c6bf13e407 Using nose to test on travis 2015-09-08 15:02:28 -03:00
ErgoZ Riftbit Vaper 6237bb636c Fix InputFile class for python 3+ support 2015-09-08 20:54:50 +03:00
ErgoZ Riftbit Vaper 0496781501 Update AUTHORS.rst 2015-09-08 20:45:44 +03:00
ErgoZ 4a761d0611 Add ability to set custom filename (fix InputFile class)
For commands that uses InputFile class
2015-09-08 20:43:28 +03:00
ErgoZ 714adc13ee Add ability to set custom filename
For commands that uses InputFile class
2015-09-08 20:42:23 +03:00
leandrotoledo fa387d1821 Ignore coveralls token settings 2015-09-07 20:11:46 -03:00
leandrotoledo 073d43fd75 Improve tests for GroupChat and User 2015-09-07 20:11:02 -03:00
leandrotoledo 5c0eeac036 Fix coveralls 2015-09-07 20:06:34 -03:00
leandrotoledo 64ca4d7b82 Fix travis, this time for real 2015-09-07 16:53:01 -03:00
leandrotoledo 6d7542ce50 Fix travis 2015-09-07 16:33:00 -03:00
leandrotoledo 0cfaaa590c Fix travis 2015-09-07 16:29:39 -03:00
leandrotoledo 48bb8a2413 Fix travis 2015-09-07 16:28:00 -03:00
leandrotoledo 36dc1633f5 Move old tests to legacy dir until get new ones written 2015-09-07 15:54:50 -03:00
leandrotoledo e1edeb7bec Improve design of this class 2015-09-07 15:54:12 -03:00
leandrotoledo a409fc511d Improve raise of empty chat_id 2015-09-07 15:53:43 -03:00
leandrotoledo 69d705a99f strize raw String properties for Telegram Objects 2015-09-07 15:53:09 -03:00
leandrotoledo cdcf2481ba Update Makefile to support multiple tests 2015-09-07 15:47:50 -03:00
leandrotoledo 5c4f0f152a Much better, such wow Location tests 2015-09-07 14:31:08 -03:00
leandrotoledo f29a6f0e36 Update Document tests class 2015-09-07 14:17:41 -03:00
leandrotoledo 1b0c3731de Update Base tests class 2015-09-07 14:12:58 -03:00
leandrotoledo 4be946d116 Much better, such wow GroupChat tests 2015-09-07 14:10:57 -03:00
leandrotoledo 73e36e3b73 Much better, such wow User tests 2015-09-07 14:03:20 -03:00
leandrotoledo 6141e76693 Much better, such wow Update tests 2015-09-07 13:55:28 -03:00
leandrotoledo 61ef876532 Much better, such wow Contact tests 2015-09-07 13:42:51 -03:00
leandrotoledo 060442e0ae Much better, such wow Sticker tests 2015-09-07 12:10:29 -03:00
leandrotoledo 2254440671 Much better, such wow Document tests 2015-09-07 11:55:55 -03:00
leandrotoledo 65a224884f Much better, such wow Audio/Voice/Video tests 2015-09-07 11:22:25 -03:00
leandrotoledo 0218aa2f4e Much better, such wow Voice tests 2015-09-07 09:56:51 -03:00
leandrotoledo 28e81ee9f6 Much better, such wow Audio tests 2015-09-07 09:56:41 -03:00
mattijn 6ffcdcf2fe removed unused imports 2015-09-07 05:13:08 +02:00
mattijn 89bab207b6 pep8 2015-09-07 05:11:08 +02:00
mattijn 69aa1c252b added an easier way to get frequent commands from message. 2015-09-07 04:55:00 +02:00
mattijn 5b8f41b3c1 pep 8 command_handler.py 2015-09-07 04:17:43 +02:00
mattijn ea5c690e7a add a help for extra commands. 2015-09-07 03:38:07 +02:00
mattijn 9145f24efa added a father command. and some other a way to hide commands in the help. 2015-09-07 03:13:40 +02:00
leandrotoledo c590d9c2fd Moving _requestURL method to utils package 2015-09-05 11:56:06 -03:00
leandrotoledo cfd401f22b Moving _requestURL method to utils package 2015-09-05 11:55:55 -03:00
leandrotoledo 7f790c3cb2 Releasing v2.8.2 2015-09-04 23:23:41 -03:00
leandrotoledo 30749c3b66 Merging testing 2015-09-04 23:21:31 -03:00
leandrotoledo 8f0447156b Merge branch 'testing' 2015-09-04 23:20:31 -03:00
leandrotoledo df000f8086 Fix regression on ReplyMarkup and add certificate to is_inputfile method 2015-09-04 23:20:14 -03:00
Leandro Toledo 3d835527e0 Update README.rst 2015-09-04 23:07:03 -03:00
Leandro Toledo 323052a6c9 Update README.rst 2015-09-04 23:05:14 -03:00
Leandro Toledo ef4871cce1 Update README.rst 2015-09-04 19:14:54 -03:00
leandrotoledo f355af1d2b Restoring new features after rebase 2015-09-04 19:11:31 -03:00
leandrotoledo 121e365348 Oops, restoring file on testing 2015-09-04 19:07:20 -03:00
leandrotoledo 82f1d18f4b Releasing v2.8.1 2015-09-04 19:00:54 -03:00
leandrotoledo 79cdb6cafe Adding test to check if thumbs are PhotoSize instances 2015-09-04 18:58:48 -03:00
leandrotoledo 49ff02dcf4 Fix regression on Telegram objects with thumb properties 2015-09-04 18:50:26 -03:00
leandrotoledo be23ff5d29 Fix codeclimate 2015-09-04 18:35:35 -03:00
leandrotoledo 72a7355c2f Fix codeclimate 2015-09-04 18:33:51 -03:00
leandrotoledo 64cf9ed941 Fix codeclimate 2015-09-04 18:29:37 -03:00
leandrotoledo bb84113272 Releasing 2.8 2015-09-04 18:19:05 -03:00
leandrotoledo d740ce89cf Keep off some features still in progress 2015-09-04 18:11:47 -03:00
leandrotoledo 245238b3a2 Keep off some features still in progress 2015-09-04 18:03:04 -03:00
Leandro Toledo e693922fe8 Merge pull request #54 from leandrotoledo/testing
Merge Testing branch
2015-09-04 17:59:37 -03:00
leandrotoledo 62f06da897 Move command_handler tests to tests/ folder 2015-09-04 17:54:30 -03:00
leandrotoledo 05b7fda4a1 Add certificate arg to setWebhook function 2015-09-04 17:53:39 -03:00
leandrotoledo 910959b672 Raises error when chat_id is not set 2015-09-04 17:15:44 -03:00
Leandro Toledo 881b0b3d06 Update README.rst 2015-09-02 13:23:11 -03:00
Leandro Toledo 95ecd44c0e Merge pull request #51 from njittam/testing
Adding command handler
2015-09-02 13:20:33 -03:00
njittam 9241534ba6 Create command_handler_example.py
this is an example of how to write a commandHandler
2015-09-02 16:21:11 +02:00
njittam 256d219862 A command handler
I saw in the TODO list on pypi that you wanted a commandhandler. 
I am not sure about the run and run_once commands.
and  I didn't implement logging yet.
2015-09-02 16:17:57 +02:00
njittam 8fddd3b027 test for commandHandler
Not everything has a test. and I'm quite new to unit testing so I'm not sure if I am doing this the right way.
2015-09-02 16:11:21 +02:00
njittam 3f3cb1edc5 Update AUTHORS.rst 2015-09-02 16:04:15 +02:00
Leandro Toledo f037a8c776 Update README.rst 2015-08-29 10:55:23 -03:00
Leandro Toledo 98c489c44f Fix Python 3 2015-08-28 17:53:31 -03:00
Leandro Toledo a86fc6c2ac Improving the design of existing Telegram classes 2015-08-28 17:45:44 -03:00
Leandro Toledo 1c4595123c Add improvements to tests 2015-08-28 13:28:58 -03:00
Leandro Toledo 942706e20f Add PyPy to travis 2015-08-28 13:09:47 -03:00
Leandro Toledo 6837bef9bb Fix tests for Py2.6 2015-08-28 13:07:12 -03:00
Leandro Toledo 6132e65dc3 Fix travis 2015-08-28 13:04:36 -03:00
Leandro Toledo 0f924508f7 Fix tests and minor changes 2015-08-28 13:02:02 -03:00
Leandro Toledo b20f5af1e1 Improving the design of existing Telegram classes and adding docstrings 2015-08-28 12:19:30 -03:00
Leandro Toledo ce58f72566 Merge branch 'testing' of https://github.com/leandrotoledo/python-telegram-bot into testing 2015-08-28 11:11:32 -03:00
Leandro Toledo f4839a3afe Merge pull request #47 from mASOUDd/testing
Extended the Bot class. Added a dispatching mechanism, and decorators to add commands.
2015-08-28 10:50:18 -03:00
Masoud Naservand 25f9eb7898 Extended the Bot class. Added a dispatching mechanism,
and decorators to add command to the bot the flask routing style, e.g:
>>> @bot.command('/start')
... def start(command, user_id):
...    return ('Hello, there', None, None)
2015-08-28 18:08:03 +04:30
Leandro Toledo c625b9a449 Update README.rst 2015-08-26 21:45:09 -03:00
Leandro Toledo e239315cca Merge pull request #46 from rahiel/master
add remaining chat actions
2015-08-25 11:22:03 -03:00
rahiel ccdb999e37 add remaining chat actions 2015-08-25 13:45:02 +02:00
Leandro Toledo 2f99b785b2 Merge pull request #45 from rahiel/master
use long polling in examples
2015-08-24 09:26:20 -03:00
rahiel 41eb45918c use long polling in examples 2015-08-24 11:46:33 +02:00
leandrotoledo d43e292499 Adding required comments 2015-08-21 23:22:58 -03:00
leandrotoledo fdb5f2339c Improving the design of existing Telegram classes and adding docstrings 2015-08-21 23:15:29 -03:00
leandrotoledo d03a394075 Refactoring, improving the design of existing message class and adding docstrings 2015-08-21 14:49:07 -03:00
Leandro Toledo 3658b4231c Update README.rst 2015-08-21 14:09:13 -03:00
leandrotoledo 1d6e9502cb Adding botan.io support 2015-08-20 21:07:49 -03:00
Leandro Toledo 92ca92341a Merge pull request #43 from rahiel/master
confirm processed message in examples
2015-08-20 15:49:21 -03:00
rahiel 0691b1e971 confirm processed message in examples 2015-08-20 19:58:57 +02:00
leandrotoledo 8746222cf6 Releasing v2.7.1 2015-08-19 16:16:06 -03:00
leandrotoledo 32dc05ed36 Fix lines too long 2015-08-19 16:08:03 -03:00
leandrotoledo ba5902c1d4 Fix serialization when message has reply_to_message, new_chat_participant or new_chat_photo #42 2015-08-19 15:41:09 -03:00
Leandro Toledo 80371c9f6e Merge branch 'master' of https://github.com/leandrotoledo/python-telegram-bot 2015-08-17 13:15:41 -03:00
Leandro Toledo a8fd6b5061 Releasing v2.7 2015-08-17 13:15:29 -03:00
Leandro Toledo 53f5911aad Update README.rst 2015-08-17 11:45:28 -03:00
Leandro Toledo d4870148c7 Add telegram.voice to docs and minor docstring fixes #39 2015-08-17 11:40:21 -03:00
Leandro Toledo 6e2881b31b Adding support for Voice object and sendVoice method #39 2015-08-17 11:34:42 -03:00
Leandro Toledo 686aecb914 Fix tests for Python 3 2015-08-17 10:01:17 -03:00
Leandro Toledo 35f31bf136 Merge branch 'master' of https://github.com/leandrotoledo/python-telegram-bot 2015-08-17 09:57:07 -03:00
Leandro Toledo 56f6845969 Adding is_json tests and fixes json serialization when a forwared message #38 2015-08-17 09:56:51 -03:00
Leandro Toledo 505df01ae1 Update AUTHORS.rst 2015-08-15 15:19:17 -03:00
Leandro Toledo 3be58b759f Releasing v2.6.1 2015-08-15 15:06:32 -03:00
Leandro Toledo 5dc1e4cac1 Use imghdr instead re to match image headers. Fixes #37 2015-08-15 15:00:28 -03:00
Leandro Toledo 2cecca8324 Releasing v2.6.0 2015-08-14 16:36:39 -03:00
Leandro Toledo 109439022f Minor fixes and cfg for setuptools 2015-08-14 16:30:30 -03:00
Leandro Toledo 59ff1b68b5 clearCredentians and require_authentication are now decapred, bot properties will be called when needed only #33 2015-08-14 16:25:27 -03:00
Leandro Toledo fda1843593 Remove import pdb 2015-08-14 15:48:33 -03:00
Leandro Toledo 9b6ccaf94b Convert unix timestamp from date and forward_date in messages to date object #35 2015-08-14 15:47:31 -03:00
Leandro Toledo ea1614631e Update and rename CONTRIBUTING to CONTRIBUTING.rst 2015-08-12 18:57:46 -03:00
Leandro Toledo 6bcc8cdcfd Update AUTHORS.rst 2015-08-12 18:44:40 -03:00
leandrotoledo 9b3ce5069e Releasing 2.5.3 2015-08-11 23:49:26 -03:00
leandrotoledo f2671ffff3 fix space trailing 2015-08-11 23:46:09 -03:00
Leandro Toledo 3974690b90 Fixes base_url when pickling object 2015-08-11 23:43:40 -03:00
Leandro Toledo 66b3f8bbd3 Adding CONTRIBUTING 2015-08-11 18:24:53 -03:00
Leandro Toledo 140e68dd20 Update README.rst 2015-08-11 18:15:45 -03:00
Leandro Toledo 46cf2c250e Update README.rst 2015-08-11 18:07:32 -03:00
66 changed files with 4365 additions and 1735 deletions
+5
View File
@@ -0,0 +1,5 @@
languages:
Python: true
exclude_paths:
- "telegram/emoji.py"
- "tests/*"
+5
View File
@@ -0,0 +1,5 @@
[run]
source = telegram
[report]
omit = tests/
+4
View File
@@ -43,6 +43,7 @@ htmlcov/
nosetests.xml
coverage.xml
*,cover
.coveralls.yml
# Translations
*.mo
@@ -57,3 +58,6 @@ docs/_build/
# PyBuilder
target/
.idea/
# Sublime Text 2
*.sublime*
+4 -1
View File
@@ -4,9 +4,12 @@ python:
- "2.7"
- "3.3"
- "3.4"
- "pypy"
- "pypy3"
install:
- pip install coveralls
- pip install -r requirements.txt
script:
coverage run telegram_test.py
nosetests --with-coverage --cover-package telegram/
after_success:
coveralls
+24 -1
View File
@@ -1 +1,24 @@
* Leandro Toledo
Credits
=======
``python-telegram-bot`` is written and maintained by `Leandro Toledo <https://github.com/leandrotoledo>`_.
Contributors
------------
The following wonderful people contributed directly or indirectly to this project:
- `Avanatiker <https://github.com/Avanatiker>`_
- `bimmlerd <https://github.com/bimmlerd>`_
- `ErgoZ Riftbit Vaper <https://github.com/ergoz>`_
- `franciscod <https://github.com/franciscod>`_
- `JASON0916 <https://github.com/JASON0916>`_
- `jh0ker <https://github.com/jh0ker>`_
- `JRoot3D <https://github.com/JRoot3D>`_
- `macrojames <https://github.com/macrojames>`_
- `njittam <https://github.com/njittam>`_
- `Rahiel Kasim <https://github.com/rahiel>`_
- `sooyhwang <https://github.com/sooyhwang>`_
- `wjt <https://github.com/wjt>`_
Please add yourself here alphabetically when you submit your first pull request.
-109
View File
@@ -1,109 +0,0 @@
2015-08-11
Released 2.5.2
New changes from Telegram Bot API have been applied
telegram.Bot now supports to be pickled
Return empty str instead None when message.text is empty
2015-08-10
Released 2.5.1
Moved from GPLv2 to LGPLv3
2015-08-09
Released 2.5
Fixes logging calls in API
2015-08-08
Released 2.4
Fixes Emoji class for Python 3
PEP8 improvements
2015-08-08
Released 2.3
Fixes ForceReply class
Remove logging.basicConfig from library
2015-07-25
Released 2.2
Allows debug=True when initializing telegram.Bot
2015-07-20
Released 2.1
Fix to_dict for Document and Video
2015-07-19
Released 2.0
Fixes bugs
Improves __str__ over to_json()
Creates abstractclass TelegramObject
2015-07-15
Released 1.9
Python 3 officially supported
PEP8 improvements
2015-07-12
Released 1.8
Fixes crash when replying an unicode text message (special thanks to JRoot3D)
2015-07-11
Released 1.7
Fixes crash when username is not defined on chat (special thanks to JRoot3D)
2015-07-10
Released 1.6
Improvements for GAE support
2015-07-10
Released 1.5
Fixes randomly unicode issues when using InputFile
2015-07-10
Released 1.4
requests lib is no longer required
Google App Engine (GAE) is supported
2015-07-10
Released 1.3
Added support to setWebhook (special thanks to macrojames)
2015-07-09
Released 1.2
CustomKeyboard classes now available
Emojis available
PEP8 improvements
2015-07-08
Released 1.1
PyPi package now available
2015-07-08
Released 1.0
Initial checkin of python-telegram-bot
+189
View File
@@ -0,0 +1,189 @@
2015-11-10
Released 2.9
Emoji class now uses bytes_to_native_str from future 3rd party lib
Make user_from optional to work with channels channels
Raise exception if Telegram times out on long-polling
*Special thanks to @jh0ker for all hard work*
2015-10-08
Released 2.8.7
Type as optional for GroupChat class
2015-10-08
Released 2.8.6
Adds type to User and GroupChat classes (pre-release Telegram feature)
2015-09-24
Released 2.8.5
Handles HTTP Bad Gateway (503) errors on request
Fixes regression on Audio and Document for unicode fields
2015-09-20
Released 2.8.4
getFile and File.download is now fully supported
2015-09-10
Released 2.8.3
Moved Bot._requestURL to its own class (telegram.utils.request)
Much better, such wow, Telegram Objects tests
Add consistency for str properties on Telegram Objects
Better design to test if chat_id is invalid
Add ability to set custom filename on Bot.sendDocument(..,filename='')
Fix Sticker as InputFile
Send JSON requests over urlencoded post data
Markdown support for Bot.sendMessage(..., parse_mode=ParseMode.MARKDOWN)
Refactor of TelegramError class (no more handling IOError or URLError)
2015-09-05
Released 2.8.2
Fix regression on Telegram ReplyMarkup
Add certificate to is_inputfile method
2015-09-05
Released 2.8.1
Fix regression on Telegram objects with thumb properties
2015-09-04
Released 2.8
TelegramError when chat_id is empty for send* methods
setWebhook now supports sending self-signed certificate
Huge redesign of existing Telegram classes
Added support for PyPy
Added docstring for existing classes
2015-08-19
Released 2.7.1
Fixed JSON serialization for message
2015-08-17
Released 2.7
Added support for Voice object and sendVoice method
Due backward compatibility performer or/and title will be required for sendAudio
Fixed JSON serialization when forwarded message
2015-08-15
Released 2.6.1
Fixed parsing image header issue on < Python 2.7.3
2015-08-14
Released 2.6.0
Depreciation of require_authentication and clearCredentials methods
Giving AUTHORS the proper credits for their contribution for this project
Message.date and Message.forward_date are now datetime objects
2015-08-12
Released 2.5.3
telegram.Bot now supports to be unpickled
2015-08-11
Released 2.5.2
New changes from Telegram Bot API have been applied
telegram.Bot now supports to be pickled
Return empty str instead None when message.text is empty
2015-08-10
Released 2.5.1
Moved from GPLv2 to LGPLv3
2015-08-09
Released 2.5
Fixes logging calls in API
2015-08-08
Released 2.4
Fixes Emoji class for Python 3
PEP8 improvements
2015-08-08
Released 2.3
Fixes ForceReply class
Remove logging.basicConfig from library
2015-07-25
Released 2.2
Allows debug=True when initializing telegram.Bot
2015-07-20
Released 2.1
Fix to_dict for Document and Video
2015-07-19
Released 2.0
Fixes bugs
Improves __str__ over to_json()
Creates abstractclass TelegramObject
2015-07-15
Released 1.9
Python 3 officially supported
PEP8 improvements
2015-07-12
Released 1.8
Fixes crash when replying an unicode text message (special thanks to JRoot3D)
2015-07-11
Released 1.7
Fixes crash when username is not defined on chat (special thanks to JRoot3D)
2015-07-10
Released 1.6
Improvements for GAE support
2015-07-10
Released 1.5
Fixes randomly unicode issues when using InputFile
2015-07-10
Released 1.4
requests lib is no longer required
Google App Engine (GAE) is supported
2015-07-10
Released 1.3
Added support to setWebhook (special thanks to macrojames)
2015-07-09
Released 1.2
CustomKeyboard classes now available
Emojis available
PEP8 improvements
2015-07-08
Released 1.1
PyPi package now available
2015-07-08
Released 1.0
Initial checkin of python-telegram-bot
+39
View File
@@ -0,0 +1,39 @@
How To Contribute
=================
Every open source project lives from the generous help by contributors that sacrifice their time and ``python-telegram-bot`` is no different.
To make participation as pleasant as possible, this project adheres to the `Code of Conduct`_ by the Python Software Foundation.
Here are a few guidelines to get you started:
- Add yourself to the AUTHORS.rst_ file in an alphabetical fashion.
Every contribution is valuable and shall be credited.
- If your change is noteworthy, add an entry to the CHANGES_.
- No contribution is too small; please submit as many fixes for typos and grammar bloopers as you can!
- Dont break backward compatibility.
- *Always* add tests and docs for your code.
This is a hard rule; patches with missing tests or documentation wont be merged.
If a feature is not tested or documented, it doesnt exist.
- Obey `PEP 8`_ and `PEP 257`_.
- Follow `Google Python Style Guide`_ and `Google Python Style Docstrings`_.
- Write `good commit messages`_.
.. note::
If you have something great but arent sure whether it adheres -- or even can adhere -- to the rules above: **please submit a pull request anyway**!
In the best case, we can mold it into something, in the worst case the pull request gets politely closed.
Theres absolutely nothing to fear.
Thank you for considering to contribute to ``python-telegram-bot``!
If you have any question or concerns, feel free to reach out to me.
.. _`PEP 8`: https://www.python.org/dev/peps/pep-0008/
.. _`PEP 257`: https://www.python.org/dev/peps/pep-0257/
.. _`good commit messages`: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
.. _`Code of Conduct`: https://www.python.org/psf/codeofconduct/
.. _`Google Python Style Guide`: https://google-styleguide.googlecode.com/svn/trunk/pyguide.html
.. _`Google Python Style Docstrings`: http://sphinx-doc.org/latest/ext/example_google.html
.. _CHANGES: https://github.com/leandrotoledo/python-telegram-bot/blob/master/CHANGES
.. _AUTHORS.rst: https://github.com/leandrotoledo/python-telegram-bot/blob/master/AUTHORS.rst
+16 -6
View File
@@ -1,7 +1,4 @@
help:
@echo " clean remove unwanted stuff"
@echo " lint check style with flake8"
@echo " test run tests"
.PHONY: clean pep8 lint test install
clean:
rm -fr build
@@ -10,8 +7,21 @@ clean:
find . -name '*.pyo' -exec rm -f {} \;
find . -name '*~' -exec rm -f {} \;
pep8:
flake8 telegram
lint:
flake8 --doctests --max-complexity 10 telegram
pylint -E telegram
test:
python telegram_test.py
nosetests
install:
pip install -r requirements.txt
help:
@echo "Available targets:"
@echo "- clean Clean up the source directory"
@echo "- pep8 Check style with flake8"
@echo "- lint Check style with pylint"
@echo "- test Run tests"
+41 -11
View File
@@ -2,17 +2,23 @@ Python Telegram Bot
A Python wrapper around the Telegram Bot API.
*Stay tuned for library updates and new releases on our* `Telegram Channel <http://telegram.me/pythontelegrambotchannel>`_.
By `Leandro Toledo <leandrotoledodesouza@gmail.com>`_
.. image:: https://img.shields.io/pypi/v/python-telegram-bot.svg
:target: https://pypi.python.org/pypi/python-telegram-bot
:alt: PyPi Package Version
.. image:: https://img.shields.io/pypi/dm/python-telegram-bot.svg
:target: https://pypi.python.org/pypi/python-telegram-bot
:alt: PyPi Package Monthly Download
.. image:: https://img.shields.io/github/license/leandrotoledo/python-telegram-bot.svg
.. image:: https://readthedocs.org/projects/python-telegram-bot/badge/?version=latest
:target: https://readthedocs.org/projects/python-telegram-bot/?badge=latest
:alt: Documentation Status
.. image:: https://img.shields.io/pypi/l/python-telegram-bot.svg
:target: http://www.gnu.org/licenses/lgpl-3.0.html
:alt: LGPLv3 License
@@ -23,7 +29,7 @@ By `Leandro Toledo <leandrotoledodesouza@gmail.com>`_
.. image:: https://codeclimate.com/github/leandrotoledo/python-telegram-bot/badges/gpa.svg
:target: https://codeclimate.com/github/leandrotoledo/python-telegram-bot
:alt: Code Climate
.. image:: https://coveralls.io/repos/leandrotoledo/python-telegram-bot/badge.svg?branch=master&service=github
:target: https://coveralls.io/github/leandrotoledo/python-telegram-bot?branch=master
:alt: Coveralls
@@ -44,7 +50,7 @@ Table of contents
- `Getting the code`_
- `Documentation`_
- `Getting started`_
1. `API`_
@@ -52,6 +58,8 @@ Table of contents
3. `Examples`_
4. `Documentation`_
- `License`_
- `Contact`_
@@ -83,10 +91,12 @@ sendAudio Yes
sendDocument Yes
sendSticker Yes
sendVideo Yes
sendVoice Yes
sendLocation Yes
sendChatAction Yes
getUpdates Yes
getUserProfilePhotos Yes
getFile Yes
setWebhook Yes
========================= ============
@@ -101,6 +111,8 @@ Python Version *Supported?*
2.7 Yes
3.3 Yes
3.4 Yes
PyPy Yes
PyPy3 Yes
============== ============
=============
@@ -134,9 +146,9 @@ To see other options available, run:
$ make help
================
_`Documentation`
================
==================
_`Getting started`
==================
View the last release API documentation at: https://core.telegram.org/bots/api
@@ -180,6 +192,10 @@ To post a text message::
>>> bot.sendMessage(chat_id=chat_id, text="I'm sorry Dave I'm afraid I can't do that.")
To post a text message with markdown::
>>> bot.sendMessage(chat_id=chat_id, text="*bold* _italic_ [link](http://google.com).", parse_mode=telegram.ParseMode.MARKDOWN)
To post an Emoji (special thanks to `Tim Whitlock <http://apps.timwhitlock.info/emoji/tables/unicode>`_)::
>>> bot.sendMessage(chat_id=chat_id, text=telegram.Emoji.PILE_OF_POO)
@@ -188,9 +204,9 @@ 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')
To post an audio file::
To post a voice file::
>>> bot.sendAudio(chat_id=chat_id, audio=open('tests/telegram.ogg', 'rb'))
>>> bot.sendVoice(chat_id=chat_id, voice=open('tests/telegram.ogg', 'rb'))
To tell the user that something is happening on bot's side::
@@ -207,6 +223,12 @@ To hide `Custom Keyboards <https://core.telegram.org/bots#keyboards>`_::
>>> reply_markup = telegram.ReplyKeyboardHide()
>>> bot.sendMessage(chat_id=chat_id, text="I'm back.", reply_markup=reply_markup)
To download a file (you will need its file_id)::
>>> file_id = message.voice.file_id
>>> newFile = bot.getFile(file_id)
>>> newFile.download('voice.ogg')
There are many more API methods, to read the full API documentation::
$ pydoc telegram.Bot
@@ -239,6 +261,12 @@ Here follows some examples to help you to get your own Bot up to speed:
- `DevOps Reaction Bot <https://github.com/leandrotoledo/gae-devops-reaction-telegram-bot>`_ sends latest or random posts from `DevOps Reaction <http://devopsreactions.tumblr.com/>`_. Running on `Google App Engine <https://cloud.google.com/appengine>`_ (billing has to be enabled for fully Socket API support).
================
_`Documentation`
================
``python-telegram-bot``'s documentation lives at `Read the Docs <http://python-telegram-bot.readthedocs.org/en/latest/>`_.
==========
_`License`
==========
@@ -249,7 +277,9 @@ You may copy, distribute and modify the software provided that modifications are
_`Contact`
==========
Feel free to join to our `Telegram group <https://telegram.me/joinchat/00b9c0f802509b949c1563d56eb053b0>`_.
Feel free to join to our `Telegram group <https://telegram.me/joinchat/ALnA-AJQm5SEwuAzar3nvw>`_.
If you face trouble joining in the group please ping me `via Telegram <https://telegram.me/leandrotoledo>`_, I'll be glad to add you.
=======
_`TODO`
@@ -1,2 +1,3 @@
sphinx
sphinx_rtd_theme
sphinx-pypi-upload
+2 -2
View File
@@ -58,9 +58,9 @@ author = u'Leandro Toledo'
# built documents.
#
# The short X.Y version.
version = '2.5'
version = '2.9'
# The full version, including alpha/beta/rc tags.
release = '2.5.1'
release = '2.9'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
+1
View File
@@ -29,6 +29,7 @@ Submodules
telegram.user
telegram.userprofilephotos
telegram.video
telegram.voice
Module contents
---------------
+7
View File
@@ -0,0 +1,7 @@
telegram.voice module
=====================
.. automodule:: telegram.voice
:members:
:undoc-members:
:show-inheritance:
+11 -14
View File
@@ -19,7 +19,6 @@
import logging
import telegram
import time
LAST_UPDATE_ID = None
@@ -43,26 +42,24 @@ def main():
while True:
echo(bot)
time.sleep(3)
def echo(bot):
global LAST_UPDATE_ID
# Request updates from last updated_id
for update in bot.getUpdates(offset=LAST_UPDATE_ID):
if LAST_UPDATE_ID < update.update_id:
# chat_id is required to reply any message
chat_id = update.message.chat_id
message = update.message.text.encode('utf-8')
# Request updates after the last updated_id
for update in bot.getUpdates(offset=LAST_UPDATE_ID, timeout=10):
# chat_id is required to reply any message
chat_id = update.message.chat_id
reply_text = update.message.text
if (message):
# Reply the message
bot.sendMessage(chat_id=chat_id,
text=message)
if (reply_text):
# Reply the message
bot.sendMessage(chat_id=chat_id,
text=reply_text)
# Updates global offset to get the new updates
LAST_UPDATE_ID = update.update_id
# Updates global offset to get the new updates
LAST_UPDATE_ID = update.update_id + 1
if __name__ == '__main__':
+5 -7
View File
@@ -33,17 +33,15 @@ def main():
LAST_UPDATE_ID = bot.getUpdates()[-1].update_id # Get lastest update
while True:
for update in bot.getUpdates(offset=LAST_UPDATE_ID):
for update in bot.getUpdates(offset=LAST_UPDATE_ID, timeout=10):
text = update.message.text
chat_id = update.message.chat.id
update_id = update.update_id
if LAST_UPDATE_ID < update_id: # If newer than the initial
# LAST_UPDATE_ID
if text:
roboed = ed(text) # Ask something to Robô Ed
bot.sendMessage(chat_id=chat_id, text=roboed)
LAST_UPDATE_ID = update_id
if text:
roboed = ed(text) # Ask something to Robô Ed
bot.sendMessage(chat_id=chat_id, text=roboed)
LAST_UPDATE_ID = update_id + 1
def ed(text):
+1
View File
@@ -0,0 +1 @@
future
+6 -1
View File
@@ -1,5 +1,10 @@
[wheel]
universal = 1
[upload_docs]
[build_sphinx]
source-dir = docs/source
build-dir = docs/build
all_files = 1
[upload_sphinx]
upload-dir = docs/build/html
+2 -2
View File
@@ -15,12 +15,12 @@ def read(*paths):
setup(
name='python-telegram-bot',
version='2.5.2',
version='2.9',
author='Leandro Toledo',
author_email='leandrotoledodesouza@gmail.com',
license='LGPLv3',
url='https://github.com/leandrotoledo/python-telegram-bot',
keywords='telegram bot api',
keywords='python telegram bot api wrapper',
description='A Python wrapper around the Telegram Bot API',
long_description=(read('README.rst')),
packages=find_packages(exclude=['tests*']),
+11 -6
View File
@@ -16,17 +16,17 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""A library that provides a Python interface to the Telegram Bot API"""
__author__ = 'leandrotoledodesouza@gmail.com'
__version__ = '2.5.2'
__version__ = '2.8.7'
from .base import TelegramObject
from .user import User
from .message import Message
from .update import Update
from .groupchat import GroupChat
from .photosize import PhotoSize
from .audio import Audio
from .voice import Voice
from .document import Document
from .sticker import Sticker
from .video import Video
@@ -38,14 +38,19 @@ from .replymarkup import ReplyMarkup
from .replykeyboardmarkup import ReplyKeyboardMarkup
from .replykeyboardhide import ReplyKeyboardHide
from .forcereply import ForceReply
from .inputfile import InputFile
from .error import TelegramError
from .inputfile import InputFile
from .file import File
from .nullhandler import NullHandler
from .emoji import Emoji
from .parsemode import ParseMode
from .message import Message
from .update import Update
from .bot import Bot
__all__ = ['Bot', 'Emoji', 'TelegramError', 'InputFile', 'ReplyMarkup',
'ForceReply', 'ReplyKeyboardHide', 'ReplyKeyboardMarkup',
'UserProfilePhotos', 'ChatAction', 'Location', 'Contact',
'Video', 'Sticker', 'Document', 'Audio', 'PhotoSize', 'GroupChat',
'Update', 'Message', 'User', 'TelegramObject', 'NullHandler']
'Video', 'Sticker', 'Document', 'File', 'Audio', 'PhotoSize',
'GroupChat', 'Update', 'ParseMode', 'Message', 'User',
'TelegramObject', 'NullHandler', 'Voice']
+42 -18
View File
@@ -16,33 +16,57 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram Audio"""
from telegram import TelegramObject
class Audio(TelegramObject):
"""This object represents a Telegram Audio.
Attributes:
file_id (str):
duration (int):
performer (str):
title (str):
mime_type (str):
file_size (int):
Args:
file_id (str):
duration (int):
**kwargs: Arbitrary keyword arguments.
Keyword Args:
performer (Optional[str]):
title (Optional[str]):
mime_type (Optional[str]):
file_size (Optional[int]):
"""
def __init__(self,
file_id,
duration,
mime_type=None,
file_size=None):
self.file_id = file_id
self.duration = duration
self.mime_type = mime_type
self.file_size = file_size
**kwargs):
# Required
self.file_id = str(file_id)
self.duration = int(duration)
# Optionals
self.performer = kwargs.get('performer', '')
self.title = kwargs.get('title', '')
self.mime_type = str(kwargs.get('mime_type', ''))
self.file_size = int(kwargs.get('file_size', 0))
@staticmethod
def de_json(data):
return Audio(file_id=data.get('file_id', None),
duration=data.get('duration', None),
mime_type=data.get('mime_type', None),
file_size=data.get('file_size', None))
"""
Args:
data (str):
def to_dict(self):
data = {'file_id': self.file_id,
'duration': self.duration}
if self.mime_type:
data['mime_type'] = self.mime_type
if self.file_size:
data['file_size'] = self.file_size
return data
Returns:
telegram.Audio:
"""
if not data:
return None
return Audio(**data)
+28 -4
View File
@@ -16,13 +16,14 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""Base class for Telegram Objects"""
import json
from abc import ABCMeta, abstractmethod
from abc import ABCMeta
class TelegramObject(object):
"""Base class for most telegram object"""
"""Base class for most telegram objects"""
__metaclass__ = ABCMeta
@@ -34,11 +35,34 @@ class TelegramObject(object):
@staticmethod
def de_json(data):
"""
Args:
data (str):
Returns:
telegram.TelegramObject:
"""
raise NotImplementedError
def to_json(self):
"""
Returns:
str:
"""
return json.dumps(self.to_dict())
@abstractmethod
def to_dict(self):
return
"""
Returns:
dict:
"""
data = dict()
for key, value in self.__dict__.items():
if value:
if hasattr(value, 'to_dict'):
data[key] = value.to_dict()
else:
data[key] = value
return data
+234 -171
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python
# pylint: disable=E0611,E0213,E1102,C0103,E1101,W0613,R0913,R0904
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
@@ -16,28 +17,38 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram Bot"""
import json
try:
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 logging
from telegram import (User, Message, Update, UserProfilePhotos, TelegramError,
ReplyMarkup, InputFile, TelegramObject, NullHandler)
from telegram import (User, Message, Update, UserProfilePhotos, File,
TelegramError, ReplyMarkup, TelegramObject, NullHandler)
from telegram.utils import request
h = NullHandler()
logging.getLogger(__name__).addHandler(h)
H = NullHandler()
logging.getLogger(__name__).addHandler(H)
class Bot(TelegramObject):
"""This object represents a Telegram Bot.
Attributes:
id (int):
first_name (str):
last_name (str):
username (str):
name (str):
Args:
token (str):
**kwargs: Arbitrary keyword arguments.
Keyword Args:
base_url (Optional[str]):
"""
def __init__(self,
token,
base_url=None):
@@ -48,35 +59,73 @@ class Bot(TelegramObject):
else:
self.base_url = base_url + self.token
self.log = logging.getLogger(__name__)
self.base_file_url = 'https://api.telegram.org/file/bot%s' % self.token
try:
bot = self.getMe()
self.bot = None
self.id = bot.id
self.first_name = bot.first_name
self.last_name = bot.last_name
self.username = bot.username
self.logger = logging.getLogger(__name__)
self.__auth = True
def info(func):
"""
Returns:
"""
@functools.wraps(func)
def decorator(self, *args, **kwargs):
"""
decorator
"""
if not self.bot:
self.getMe()
self.log.info('Starting bot %s' % self.name)
except TelegramError:
raise TelegramError({'message': 'Bad token'})
result = func(self, *args, **kwargs)
return result
return decorator
@property
@info
def id(self):
"""int: """
return self.bot.id
@property
@info
def first_name(self):
"""str: """
return self.bot.first_name
@property
@info
def last_name(self):
"""str: """
return self.bot.last_name
@property
@info
def username(self):
"""str: """
return self.bot.username
@property
def name(self):
"""str: """
return '@%s' % self.username
def log(func):
"""
Returns:
A telegram.Message instance representing the message posted.
"""
logger = logging.getLogger(func.__module__)
@functools.wraps(func)
def decorator(self, *args, **kwargs):
logger.debug('Entering: %s' % func.__name__)
"""
decorator
"""
logger.debug('Entering: %s', func.__name__)
result = func(self, *args, **kwargs)
logger.debug(result)
logger.debug('Exiting: %s' % func.__name__)
logger.debug('Exiting: %s', func.__name__)
return result
return decorator
@@ -87,8 +136,14 @@ class Bot(TelegramObject):
"""
@functools.wraps(func)
def decorator(self, *args, **kwargs):
"""
decorator
"""
url, data = func(self, *args, **kwargs)
if not data.get('chat_id'):
raise TelegramError('Invalid chat_id')
if kwargs.get('reply_to_message_id'):
reply_to_message_id = kwargs.get('reply_to_message_id')
data['reply_to_message_id'] = reply_to_message_id
@@ -100,31 +155,14 @@ class Bot(TelegramObject):
else:
data['reply_markup'] = reply_markup
json_data = self._requestUrl(url, 'POST', data=data)
data = self._parseAndCheckTelegram(json_data)
result = request.post(url, data)
if data is True:
return data
if result is True:
return result
return Message.de_json(data)
return Message.de_json(result)
return decorator
def require_authentication(func):
@functools.wraps(func)
def decorator(self, *args, **kwargs):
if not self.__auth:
raise TelegramError({'message': "API must be authenticated."})
return func(self, *args, **kwargs)
return decorator
@log
@require_authentication
def clearCredentials(self):
"""Clear any credentials for this instance.
"""
self.__auth = False
@log
def getMe(self):
"""A simple method for testing your bot's auth token.
@@ -135,26 +173,30 @@ class Bot(TelegramObject):
"""
url = '%s/getMe' % self.base_url
json_data = self._requestUrl(url, 'GET')
data = self._parseAndCheckTelegram(json_data)
result = request.get(url)
return User.de_json(data)
self.bot = User.de_json(result)
return self.bot
@log
@message
@require_authentication
def sendMessage(self,
chat_id,
text,
parse_mode=None,
disable_web_page_preview=None,
reply_to_message_id=None,
reply_markup=None):
**kwargs):
"""Use this method to send text messages.
Args:
chat_id:
Unique identifier for the message recipient - telegram.User or
telegram.GroupChat id.
parse_mode:
Send Markdown, if you want Telegram apps to show bold, italic and
inline URLs in your bot's message. For the moment, only Telegram
for Android supports this. [Optional]
text:
Text of the message to be sent.
disable_web_page_preview:
@@ -175,6 +217,8 @@ class Bot(TelegramObject):
data = {'chat_id': chat_id,
'text': text}
if parse_mode:
data['parse_mode'] = parse_mode
if disable_web_page_preview:
data['disable_web_page_preview'] = disable_web_page_preview
@@ -182,7 +226,6 @@ class Bot(TelegramObject):
@log
@message
@require_authentication
def forwardMessage(self,
chat_id,
from_chat_id,
@@ -216,13 +259,11 @@ class Bot(TelegramObject):
@log
@message
@require_authentication
def sendPhoto(self,
chat_id,
photo,
caption=None,
reply_to_message_id=None,
reply_markup=None):
**kwargs):
"""Use this method to send photos.
Args:
@@ -258,16 +299,23 @@ class Bot(TelegramObject):
@log
@message
@require_authentication
def sendAudio(self,
chat_id,
audio,
reply_to_message_id=None,
reply_markup=None):
duration=None,
performer=None,
title=None,
**kwargs):
"""Use this method to send audio files, if you want Telegram clients to
display the file as a playable voice message. For this to work, your
audio must be in an .ogg file encoded with OPUS (other formats may be
sent as telegram.Document).
display them in the music player. Your audio must be in an .mp3 format.
On success, the sent Message is returned. Bots can currently send audio
files of up to 50 MB in size, this limit may be changed in the future.
For backward compatibility, when both fields title and description are
empty and mime-type of the sent file is not "audio/mpeg", file is sent
as playable voice message. In this case, your audio must be in an .ogg
file encoded with OPUS. This will be removed in the future. You need to
use sendVoice method instead.
Args:
chat_id:
@@ -276,6 +324,12 @@ class Bot(TelegramObject):
Audio file to send. You can either pass a file_id as String to
resend an audio that is already on the Telegram servers, or upload
a new audio file using multipart/form-data.
duration:
Duration of sent audio in seconds. [Optional]
performer:
Performer of sent audio. [Optional]
title:
Title of sent audio. [Optional]
reply_to_message_id:
If the message is a reply, ID of the original message. [Optional]
reply_markup:
@@ -292,16 +346,22 @@ class Bot(TelegramObject):
data = {'chat_id': chat_id,
'audio': audio}
if duration:
data['duration'] = duration
if performer:
data['performer'] = performer
if title:
data['title'] = title
return url, data
@log
@message
@require_authentication
def sendDocument(self,
chat_id,
document,
reply_to_message_id=None,
reply_markup=None):
filename=None,
**kwargs):
"""Use this method to send general files.
Args:
@@ -311,6 +371,9 @@ class Bot(TelegramObject):
File to send. You can either pass a file_id as String to resend a
file that is already on the Telegram servers, or upload a new file
using multipart/form-data.
filename:
File name that shows in telegram message (it is usefull when you
send file generated by temp module, for example). [Optional]
reply_to_message_id:
If the message is a reply, ID of the original message. [Optional]
reply_markup:
@@ -327,16 +390,17 @@ class Bot(TelegramObject):
data = {'chat_id': chat_id,
'document': document}
if filename:
data['filename'] = filename
return url, data
@log
@message
@require_authentication
def sendSticker(self,
chat_id,
sticker,
reply_to_message_id=None,
reply_markup=None):
**kwargs):
"""Use this method to send .webp stickers.
Args:
@@ -366,14 +430,12 @@ class Bot(TelegramObject):
@log
@message
@require_authentication
def sendVideo(self,
chat_id,
video,
duration=None,
caption=None,
reply_to_message_id=None,
reply_markup=None):
**kwargs):
"""Use this method to send video files, Telegram clients support mp4
videos (other formats may be sent as telegram.Document).
@@ -414,13 +476,55 @@ class Bot(TelegramObject):
@log
@message
@require_authentication
def sendVoice(self,
chat_id,
voice,
duration=None,
**kwargs):
"""Use this method to send audio files, if you want Telegram clients to
display the file as a playable voice message. For this to work, your
audio must be in an .ogg file encoded with OPUS (other formats may be
sent as Audio or Document). On success, the sent Message is returned.
Bots can currently send audio files of up to 50 MB in size, this limit
may be changed in the future.
Args:
chat_id:
Unique identifier for the message recipient - User or GroupChat id.
voice:
Audio file to send. You can either pass a file_id as String to
resend an audio that is already on the Telegram servers, or upload
a new audio file using multipart/form-data.
duration:
Duration of sent audio in seconds. [Optional]
reply_to_message_id:
If the message is a reply, ID of the original message. [Optional]
reply_markup:
Additional interface options. A JSON-serialized object for a
custom reply keyboard, instructions to hide keyboard or to force a
reply from the user. [Optional]
Returns:
A telegram.Message instance representing the message posted.
"""
url = '%s/sendVoice' % self.base_url
data = {'chat_id': chat_id,
'voice': voice}
if duration:
data['duration'] = duration
return url, data
@log
@message
def sendLocation(self,
chat_id,
latitude,
longitude,
reply_to_message_id=None,
reply_markup=None):
**kwargs):
"""Use this method to send point on the map.
Args:
@@ -451,7 +555,6 @@ class Bot(TelegramObject):
@log
@message
@require_authentication
def sendChatAction(self,
chat_id,
action):
@@ -468,8 +571,8 @@ class Bot(TelegramObject):
is about to receive:
- ChatAction.TYPING for text messages,
- ChatAction.UPLOAD_PHOTO for photos,
- ChatAction.UPLOAD_VIDEO or upload_video for videos,
- ChatAction.UPLOAD_AUDIO or upload_audio for audio files,
- ChatAction.UPLOAD_VIDEO for videos,
- ChatAction.UPLOAD_AUDIO for audio files,
- ChatAction.UPLOAD_DOCUMENT for general files,
- ChatAction.FIND_LOCATION for location data.
"""
@@ -482,7 +585,6 @@ class Bot(TelegramObject):
return url, data
@log
@require_authentication
def getUserProfilePhotos(self,
user_id,
offset=None,
@@ -512,13 +614,38 @@ class Bot(TelegramObject):
if limit:
data['limit'] = limit
json_data = self._requestUrl(url, 'POST', data=data)
data = self._parseAndCheckTelegram(json_data)
result = request.post(url, data)
return UserProfilePhotos.de_json(data)
return UserProfilePhotos.de_json(result)
@log
def getFile(self,
file_id):
"""Use this method to get basic info about a file and prepare it for
downloading. For the moment, bots can download files of up to 20MB in
size.
Args:
file_id:
File identifier to get info about.
Returns:
Returns a telegram.File object
"""
url = '%s/getFile' % self.base_url
data = {'file_id': file_id}
result = request.post(url, data)
if result.get('file_path'):
result['file_path'] = '%s/%s' % (self.base_file_url,
result['file_path'])
return File.de_json(result)
@log
@require_authentication
def getUpdates(self,
offset=None,
limit=100,
@@ -553,21 +680,20 @@ class Bot(TelegramObject):
if timeout:
data['timeout'] = timeout
json_data = self._requestUrl(url, 'POST', data=data)
data = self._parseAndCheckTelegram(json_data)
result = request.post(url, data)
if data:
self.log.info(
'Getting updates: %s' % [u['update_id'] for u in data])
if result:
self.logger.info(
'Getting updates: %s', [u['update_id'] for u in result])
else:
self.log.info('No new updates found.')
self.logger.info('No new updates found.')
return [Update.de_json(x) for x in data]
return [Update.de_json(x) for x in result]
@log
@require_authentication
def setWebhook(self,
webhook_url):
webhook_url=None,
certificate=None):
"""Use this method to specify a url and receive incoming updates via an
outgoing webhook. Whenever there is an update for the bot, we will send
an HTTPS POST request to the specified url, containing a
@@ -584,89 +710,25 @@ class Bot(TelegramObject):
"""
url = '%s/setWebhook' % self.base_url
data = {'url': webhook_url}
data = {}
if webhook_url:
data['url'] = webhook_url
if certificate:
data['certificate'] = certificate
json_data = self._requestUrl(url, 'POST', data=data)
data = self._parseAndCheckTelegram(json_data)
result = request.post(url, data)
return True
return result
def _requestUrl(self,
url,
method,
data=None):
"""Request an URL.
Args:
url:
The web location we want to retrieve.
method:
Either POST or GET.
data:
A dict of (str, unicode) key/value pairs.
Returns:
A JSON object.
"""
if method not in ('POST', 'GET'):
raise ValueError(
"Method '%s' is neither 'POST' nor 'GET'" % method)
if method == 'POST':
try:
if InputFile.is_inputfile(data):
data = InputFile(data)
request = Request(
url,
data=data.to_form(),
headers=data.headers
)
return urlopen(request).read()
else:
return urlopen(
url,
urlencode(data).encode()
).read()
except IOError as e:
raise TelegramError(str(e))
except HTTPError as e:
raise TelegramError(str(e))
except URLError as e:
raise TelegramError(str(e))
if method == 'GET':
try:
return urlopen(url).read()
except URLError as e:
raise TelegramError(str(e))
def _parseAndCheckTelegram(self,
json_data):
"""Try and parse the JSON returned from Telegram and return an empty
dictionary if there is any error.
Args:
json_data:
JSON results from Telegram Bot API.
Returns:
A JSON parsed as Python dict with results.
"""
try:
data = json.loads(json_data.decode())
if not data['ok']:
raise TelegramError(data['description'])
except ValueError:
if '<title>403 Forbidden</title>' in json_data:
raise TelegramError({'message': 'API must be authenticated'})
raise TelegramError({'message': 'JSON decoding'})
return data['result']
@staticmethod
def de_json(data):
pass
def to_dict(self):
"""
Returns:
dict:
"""
data = {'id': self.id,
'username': self.username,
'first_name': self.username}
@@ -675,4 +737,5 @@ class Bot(TelegramObject):
return data
def __reduce__(self):
return (self.__class__, (self.token, self.base_url))
return (self.__class__, (self.token,
self.base_url.replace(self.token, '')))
+9 -2
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python
# pylint: disable=R0903
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
@@ -16,11 +17,17 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram ChatAction"""
class ChatAction(object):
"""This object represents a Telegram ChatAction."""
TYPING = 'typing'
UPLOAD_PHOTO = 'upload_photo'
RECORD_VIDEO = 'upload_video'
RECORD_AUDIO = 'upload_audio'
RECORD_VIDEO = 'record_video'
UPLOAD_VIDEO = 'upload_video'
RECORD_AUDIO = 'record_audio'
UPLOAD_AUDIO = 'upload_audio'
UPLOAD_DOCUMENT = 'upload_document'
FIND_LOCATION = 'find_location'
+35 -17
View File
@@ -16,33 +16,51 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram Contact"""
from telegram import TelegramObject
class Contact(TelegramObject):
"""This object represents a Telegram Contact.
Attributes:
phone_number (str):
first_name (str):
last_name (str):
user_id (int):
Args:
phone_number (str):
first_name (str):
**kwargs: Arbitrary keyword arguments.
Keyword Args:
last_name (Optional[str]):
user_id (Optional[int]):
"""
def __init__(self,
phone_number,
first_name,
last_name=None,
user_id=None):
self.phone_number = phone_number
**kwargs):
# Required
self.phone_number = str(phone_number)
self.first_name = first_name
self.last_name = last_name
self.user_id = user_id
# Optionals
self.last_name = kwargs.get('last_name', '')
self.user_id = int(kwargs.get('user_id', 0))
@staticmethod
def de_json(data):
return Contact(phone_number=data.get('phone_number', None),
first_name=data.get('first_name', None),
last_name=data.get('last_name', None),
user_id=data.get('user_id', None))
"""
Args:
data (str):
def to_dict(self):
data = {'phone_number': self.phone_number,
'first_name': self.first_name}
if self.last_name:
data['last_name'] = self.last_name
if self.user_id:
data['user_id'] = self.user_id
return data
Returns:
telegram.Contact:
"""
if not data:
return None
return Contact(**data)
+41 -31
View File
@@ -16,45 +16,55 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram Document"""
from telegram import TelegramObject
from telegram import PhotoSize, TelegramObject
class Document(TelegramObject):
"""This object represents a Telegram Document.
Attributes:
file_id (str):
thumb (:class:`telegram.PhotoSize`):
file_name (str):
mime_type (str):
file_size (int):
Args:
file_id (str):
**kwargs: Arbitrary keyword arguments.
Keyword Args:
thumb (Optional[:class:`telegram.PhotoSize`]):
file_name (Optional[str]):
mime_type (Optional[str]):
file_size (Optional[int]):
"""
def __init__(self,
file_id,
thumb=None,
file_name=None,
mime_type=None,
file_size=None):
self.file_id = file_id
self.thumb = thumb
self.file_name = file_name
self.mime_type = mime_type
self.file_size = file_size
**kwargs):
# Required
self.file_id = str(file_id)
# Optionals
self.thumb = kwargs.get('thumb')
self.file_name = kwargs.get('file_name', '')
self.mime_type = str(kwargs.get('mime_type', ''))
self.file_size = int(kwargs.get('file_size', 0))
@staticmethod
def de_json(data):
if 'thumb' in data:
from telegram import PhotoSize
thumb = PhotoSize.de_json(data['thumb'])
else:
thumb = None
"""
Args:
data (str):
return Document(file_id=data.get('file_id', None),
thumb=thumb,
file_name=data.get('file_name', None),
mime_type=data.get('mime_type', None),
file_size=data.get('file_size', None))
Returns:
telegram.Document:
"""
if not data:
return None
def to_dict(self):
data = {'file_id': self.file_id}
if self.thumb:
data['thumb'] = self.thumb.to_dict()
if self.file_name:
data['file_name'] = self.file_name
if self.mime_type:
data['mime_type'] = self.mime_type
if self.file_size:
data['file_size'] = self.file_size
return data
data['thumb'] = PhotoSize.de_json(data.get('thumb'))
return Document(**data)
+859 -842
View File
File diff suppressed because it is too large Load Diff
+20 -5
View File
@@ -16,11 +16,26 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram Error"""
import re
class TelegramError(Exception):
"""Base class for Telegram errors."""
"""This object represents a Telegram Error."""
@property
def message(self):
'''Returns the first argument used to construct this error.'''
return self.args[0]
def __init__(self, message):
"""
Returns:
str:
"""
super(TelegramError, self).__init__()
api_error = re.match(r'^Error: (?P<message>.*)', message)
if api_error:
self.message = api_error.group('message').capitalize()
else:
self.message = message
def __str__(self):
return '%s' % (self.message)
+81
View File
@@ -0,0 +1,81 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram File"""
from os.path import basename
from telegram import TelegramObject
from telegram.utils.request import download as _download
class File(TelegramObject):
"""This object represents a Telegram File.
Attributes:
file_id (str):
file_size (str):
file_path (str):
Args:
file_id (str):
**kwargs: Arbitrary keyword arguments.
Keyword Args:
file_size (Optional[int]):
file_path (Optional[str]):
"""
def __init__(self,
file_id,
**kwargs):
# Required
self.file_id = str(file_id)
# Optionals
self.file_size = int(kwargs.get('file_size', 0))
self.file_path = str(kwargs.get('file_path', ''))
@staticmethod
def de_json(data):
"""
Args:
data (str):
Returns:
telegram.File:
"""
if not data:
return None
return File(**data)
def download(self,
custom_path=None):
"""
Args:
custom_path (str):
"""
url = self.file_path
if custom_path:
filename = basename(custom_path)
else:
filename = basename(url)
_download(url, filename)
+30 -10
View File
@@ -16,24 +16,44 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram ForceReply"""
from telegram import ReplyMarkup
class ForceReply(ReplyMarkup):
"""This object represents a Telegram ForceReply.
Attributes:
force_reply (bool):
selective (bool):
Args:
force_reply (bool):
**kwargs: Arbitrary keyword arguments.
Keyword Args:
selective (Optional[bool]):
"""
def __init__(self,
force_reply=True,
selective=None):
self.force_reply = force_reply
self.selective = selective
**kwargs):
# Required
self.force_reply = bool(force_reply)
# Optionals
self.selective = bool(kwargs.get('selective', False))
@staticmethod
def de_json(data):
return ForceReply(force_reply=data.get('force_reply', None),
selective=data.get('selective', None))
"""
Args:
data (str):
def to_dict(self):
data = {'force_reply': self.force_reply}
if self.selective:
data['selective'] = self.selective
return data
Returns:
telegram.ForceReply:
"""
if not data:
return None
return ForceReply(**data)
+34 -8
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python
# pylint: disable=C0103,W0622
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
@@ -16,23 +17,48 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram GroupChat"""
from telegram import TelegramObject
class GroupChat(TelegramObject):
"""This object represents a Telegram GroupChat.
Attributes:
id (int):
title (str):
type (str):
Args:
id (int):
title (str):
**kwargs: Arbitrary keyword arguments.
Keyword Args:
type (Optional[str]):
"""
def __init__(self,
id,
title):
self.id = id
title,
**kwargs):
# Required
self.id = int(id)
self.title = title
# Optionals
self.type = kwargs.get('type', '')
@staticmethod
def de_json(data):
return GroupChat(id=data.get('id', None),
title=data.get('title', None))
"""
Args:
data (str):
def to_dict(self):
data = {'id': self.id,
'title': self.title}
return data
Returns:
telegram.GroupChat:
"""
if not data:
return None
return GroupChat(**data)
+49 -27
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python
# pylint: disable=W0622,E0611
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
@@ -16,6 +17,7 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram InputFile"""
try:
from email.generator import _make_boundary as choose_boundary
@@ -26,10 +28,10 @@ except ImportError:
from urllib2 import urlopen
import mimetypes
import os
import re
import sys
import imghdr
from .error import TelegramError
from telegram import TelegramError
DEFAULT_MIME_TYPE = 'application/octet-stream'
USER_AGENT = 'Python Telegram Bot' \
@@ -37,6 +39,8 @@ USER_AGENT = 'Python Telegram Bot' \
class InputFile(object):
"""This object represents a Telegram InputFile."""
def __init__(self,
data):
self.data = data
@@ -51,13 +55,25 @@ class InputFile(object):
if 'photo' in data:
self.input_name = 'photo'
self.input_file = data.pop('photo')
if 'sticker' in data:
self.input_name = 'sticker'
self.input_file = data.pop('sticker')
if 'video' in data:
self.input_name = 'video'
self.input_file = data.pop('video')
if 'voice' in data:
self.input_name = 'voice'
self.input_file = data.pop('voice')
if 'certificate' in data:
self.input_name = 'certificate'
self.input_file = data.pop('certificate')
if isinstance(self.input_file, file):
self.input_file_content = self.input_file.read()
self.filename = os.path.basename(self.input_file.name)
if 'filename' in data:
self.filename = self.data.pop('filename')
else:
self.filename = os.path.basename(self.input_file.name)
self.mimetype = mimetypes.guess_type(self.filename)[0] or \
DEFAULT_MIME_TYPE
@@ -68,14 +84,26 @@ class InputFile(object):
@property
def headers(self):
"""
Returns:
str:
"""
return {'User-agent': USER_AGENT,
'Content-type': self.content_type}
@property
def content_type(self):
"""
Returns:
str:
"""
return 'multipart/form-data; boundary=%s' % self.boundary
def to_form(self):
"""
Returns:
str:
"""
form = []
form_boundary = '--' + self.boundary
@@ -102,9 +130,14 @@ class InputFile(object):
form.append('--' + self.boundary + '--')
form.append('')
return self._parse(form)
return InputFile._parse(form)
def _parse(self, form):
@staticmethod
def _parse(form):
"""
Returns:
str:
"""
if sys.version_info > (3,):
# on Python 3 form needs to be byte encoded
encoded_form = []
@@ -122,41 +155,30 @@ class InputFile(object):
"""Check if the content file is an image by analyzing its headers.
Args:
stream:
A str representing the content of a file.
stream (str): A str representing the content of a file.
Returns:
The str mimetype of an image.
str: The str mimetype of an image.
"""
try:
header = stream[:10]
image = imghdr.what(None, stream)
if image:
return 'image/%s' % image
if re.match(b'GIF8', header):
return 'image/gif'
if re.match(b'\x89PNG', header):
return 'image/png'
if re.match(b'\xff\xd8\xff\xe0\x00\x10JFIF', header) or \
re.match(b'\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'})
raise TelegramError('Could not parse file content')
@staticmethod
def is_inputfile(data):
"""Check if the request is a file request
"""Check if the request is a file request.
Args:
data:
A dict of (str, unicode) key/value pairs
data (str): A dict of (str, unicode) key/value pairs
Returns:
bool
"""
if data:
file_types = ['audio', 'document', 'photo', 'video']
file_types = ['audio', 'document', 'photo', 'sticker', 'video',
'voice', 'certificate']
file_type = [i for i in list(data.keys()) if i in file_types]
if file_type:
+25 -8
View File
@@ -16,23 +16,40 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram Location"""
from telegram import TelegramObject
class Location(TelegramObject):
"""This object represents a Telegram Sticker.
Attributes:
longitude (float):
latitude (float):
Args:
longitude (float):
latitude (float):
"""
def __init__(self,
longitude,
latitude):
self.longitude = longitude
self.latitude = latitude
# Required
self.longitude = float(longitude)
self.latitude = float(latitude)
@staticmethod
def de_json(data):
return Location(longitude=data.get('longitude', None),
latitude=data.get('latitude', None))
"""
Args:
data (str):
def to_dict(self):
data = {'longitude': self.longitude,
'latitude': self.latitude}
return data
Returns:
telegram.Location:
"""
if not data:
return None
return Location(**data)
+183 -173
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python
# pylint: disable=R0902,R0912,R0913
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
@@ -16,206 +17,215 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram Message"""
from telegram import TelegramObject
from datetime import datetime
from time import mktime
from telegram import (Audio, Contact, Document, GroupChat, Location, PhotoSize,
Sticker, TelegramObject, User, Video, Voice)
class Message(TelegramObject):
"""This object represents a Telegram Message.
Note:
* In Python `from` is a reserved word, use `from_user` instead.
Attributes:
message_id (int):
from_user (:class:`telegram.User`):
date (:class:`datetime.datetime`):
forward_from (:class:`telegram.User`):
forward_date (:class:`datetime.datetime`):
reply_to_message (:class:`telegram.Message`):
text (str):
audio (:class:`telegram.Audio`):
document (:class:`telegram.Document`):
photo (List[:class:`telegram.PhotoSize`]):
sticker (:class:`telegram.Sticker`):
video (:class:`telegram.Video`):
voice (:class:`telegram.Voice`):
caption (str):
contact (:class:`telegram.Contact`):
location (:class:`telegram.Location`):
new_chat_participant (:class:`telegram.User`):
left_chat_participant (:class:`telegram.User`):
new_chat_title (str):
new_chat_photo (List[:class:`telegram.PhotoSize`]):
delete_chat_photo (bool):
group_chat_created (bool):
Args:
message_id (int):
from_user (:class:`telegram.User`):
date (:class:`datetime.datetime`):
chat (:class:`telegram.User` or :class:`telegram.GroupChat`):
**kwargs: Arbitrary keyword arguments.
Keyword Args:
forward_from (Optional[:class:`telegram.User`]):
forward_date (Optional[:class:`datetime.datetime`]):
reply_to_message (Optional[:class:`telegram.Message`]):
text (Optional[str]):
audio (Optional[:class:`telegram.Audio`]):
document (Optional[:class:`telegram.Document`]):
photo (Optional[List[:class:`telegram.PhotoSize`]]):
sticker (Optional[:class:`telegram.Sticker`]):
video (Optional[:class:`telegram.Video`]):
voice (Optional[:class:`telegram.Voice`]):
caption (Optional[str]):
contact (Optional[:class:`telegram.Contact`]):
location (Optional[:class:`telegram.Location`]):
new_chat_participant (Optional[:class:`telegram.User`]):
left_chat_participant (Optional[:class:`telegram.User`]):
new_chat_title (Optional[str]):
new_chat_photo (Optional[List[:class:`telegram.PhotoSize`]):
delete_chat_photo (Optional[bool]):
group_chat_created (Optional[bool]):
"""
def __init__(self,
message_id,
from_user,
date,
chat,
forward_from=None,
forward_date=None,
reply_to_message=None,
text=None,
audio=None,
document=None,
photo=None,
sticker=None,
video=None,
caption=None,
contact=None,
location=None,
new_chat_participant=None,
left_chat_participant=None,
new_chat_title=None,
new_chat_photo=None,
delete_chat_photo=None,
group_chat_created=None):
self.message_id = message_id
**kwargs):
# Required
self.message_id = int(message_id)
self.from_user = from_user
self.date = date
self.chat = chat
self.forward_from = forward_from
self.forward_date = forward_date
self.reply_to_message = reply_to_message
self.text = text
self.audio = audio
self.document = document
self.photo = photo
self.sticker = sticker
self.video = video
self.caption = caption
self.contact = contact
self.location = location
self.new_chat_participant = new_chat_participant
self.left_chat_participant = left_chat_participant
self.new_chat_title = new_chat_title
self.new_chat_photo = new_chat_photo
self.delete_chat_photo = delete_chat_photo
self.group_chat_created = group_chat_created
# Optionals
self.forward_from = kwargs.get('forward_from')
self.forward_date = kwargs.get('forward_date')
self.reply_to_message = kwargs.get('reply_to_message')
self.text = kwargs.get('text', '')
self.audio = kwargs.get('audio')
self.document = kwargs.get('document')
self.photo = kwargs.get('photo')
self.sticker = kwargs.get('sticker')
self.video = kwargs.get('video')
self.voice = kwargs.get('voice')
self.caption = kwargs.get('caption', '')
self.contact = kwargs.get('contact')
self.location = kwargs.get('location')
self.new_chat_participant = kwargs.get('new_chat_participant')
self.left_chat_participant = kwargs.get('left_chat_participant')
self.new_chat_title = kwargs.get('new_chat_title', '')
self.new_chat_photo = kwargs.get('new_chat_photo')
self.delete_chat_photo = bool(kwargs.get('delete_chat_photo', False))
self.group_chat_created = bool(kwargs.get('group_chat_created', False))
@property
def chat_id(self):
"""int: Short for :attr:`Message.chat.id`"""
return self.chat.id
@staticmethod
def de_json(data):
if 'from' in data: # from is a reserved word, use from_user instead.
from telegram import User
from_user = User.de_json(data['from'])
else:
from_user = None
"""
Args:
data (str):
if 'chat' in data:
if 'first_name' in data['chat']:
from telegram import User
chat = User.de_json(data['chat'])
if 'title' in data['chat']:
from telegram import GroupChat
chat = GroupChat.de_json(data['chat'])
else:
chat = None
Returns:
telegram.Message:
"""
if not data:
return None
if 'forward_from' in data:
from telegram import User
forward_from = User.de_json(data['forward_from'])
else:
forward_from = None
data['from_user'] = User.de_json(data.get('from'))
data['date'] = datetime.fromtimestamp(data['date'])
if 'first_name' in data.get('chat', ''):
data['chat'] = User.de_json(data.get('chat'))
elif 'title' in data.get('chat', ''):
data['chat'] = GroupChat.de_json(data.get('chat'))
data['forward_from'] = \
User.de_json(data.get('forward_from'))
data['forward_date'] = \
Message._fromtimestamp(data.get('forward_date'))
data['reply_to_message'] = \
Message.de_json(data.get('reply_to_message'))
data['audio'] = \
Audio.de_json(data.get('audio'))
data['document'] = \
Document.de_json(data.get('document'))
data['photo'] = \
PhotoSize.de_list(data.get('photo'))
data['sticker'] = \
Sticker.de_json(data.get('sticker'))
data['video'] = \
Video.de_json(data.get('video'))
data['voice'] = \
Voice.de_json(data.get('voice'))
data['contact'] = \
Contact.de_json(data.get('contact'))
data['location'] = \
Location.de_json(data.get('location'))
data['new_chat_participant'] = \
User.de_json(data.get('new_chat_participant'))
data['left_chat_participant'] = \
User.de_json(data.get('left_chat_participant'))
data['new_chat_photo'] = \
PhotoSize.de_list(data.get('new_chat_photo'))
if 'reply_to_message' in data:
reply_to_message = Message.de_json(data['reply_to_message'])
else:
reply_to_message = None
return Message(**data)
if 'audio' in data:
from telegram import Audio
audio = Audio.de_json(data['audio'])
else:
audio = None
if 'document' in data:
from telegram import Document
document = Document.de_json(data['document'])
else:
document = None
if 'photo' in data:
from telegram import PhotoSize
photo = [PhotoSize.de_json(x) for x in data['photo']]
else:
photo = None
if 'sticker' in data:
from telegram import Sticker
sticker = Sticker.de_json(data['sticker'])
else:
sticker = None
if 'video' in data:
from telegram import Video
video = Video.de_json(data['video'])
else:
video = None
if 'contact' in data:
from telegram import Contact
contact = Contact.de_json(data['contact'])
else:
contact = None
if 'location' in data:
from telegram import Location
location = Location.de_json(data['location'])
else:
location = None
if 'new_chat_participant' in data:
from telegram import User
new_chat_participant = User.de_json(data['new_chat_participant'])
else:
new_chat_participant = None
if 'left_chat_participant' in data:
from telegram import User
left_chat_participant = User.de_json(data['left_chat_participant'])
else:
left_chat_participant = None
return Message(message_id=data.get('message_id', None),
from_user=from_user,
date=data.get('date', None),
chat=chat,
forward_from=forward_from,
forward_date=data.get('forward_date', None),
reply_to_message=reply_to_message,
text=data.get('text', ''),
audio=audio,
document=document,
photo=photo,
sticker=sticker,
video=video,
caption=data.get('caption', ''),
contact=contact,
location=location,
new_chat_participant=new_chat_participant,
left_chat_participant=left_chat_participant,
new_chat_title=data.get('new_chat_title', None),
new_chat_photo=data.get('new_chat_photo', None),
delete_chat_photo=data.get('delete_chat_photo', None),
group_chat_created=data.get('group_chat_created', None))
def __getitem__(self, item):
if item in self.__dict__.keys():
return self.__dict__[item]
elif item == 'chat_id':
return self.chat.id
def to_dict(self):
data = {'message_id': self.message_id,
'from': self.from_user.to_dict(),
'date': self.date,
'chat': self.chat.to_dict()}
if self.forward_from:
data['forward_from'] = self.forward_from
"""
Returns:
dict:
"""
data = super(Message, self).to_dict()
# Required
data['from'] = data.pop('from_user', None)
data['date'] = self._totimestamp(self.date)
# Optionals
if self.forward_date:
data['forward_date'] = self.forward_date
if self.reply_to_message:
data['reply_to_message'] = self.reply_to_message
if self.text:
data['text'] = self.text
if self.audio:
data['audio'] = self.audio.to_dict()
if self.document:
data['document'] = self.document.to_dict()
data['forward_date'] = self._totimestamp(self.forward_date)
if self.photo:
data['photo'] = [p.to_dict() for p in self.photo]
if self.sticker:
data['sticker'] = self.sticker.to_dict()
if self.video:
data['video'] = self.video.to_dict()
if self.caption:
data['caption'] = self.caption
if self.contact:
data['contact'] = self.contact.to_dict()
if self.location:
data['location'] = self.location.to_dict()
if self.new_chat_participant:
data['new_chat_participant'] = self.new_chat_participant
if self.left_chat_participant:
data['left_chat_participant'] = self.left_chat_participant
if self.new_chat_title:
data['new_chat_title'] = self.new_chat_title
if self.new_chat_photo:
data['new_chat_photo'] = self.new_chat_photo
if self.delete_chat_photo:
data['delete_chat_photo'] = self.delete_chat_photo
if self.group_chat_created:
data['group_chat_created'] = self.group_chat_created
data['new_chat_photo'] = [p.to_dict() for p in self.new_chat_photo]
return data
@staticmethod
def _fromtimestamp(unixtime):
"""
Args:
unixtime (int):
Returns:
datetime.datetime:
"""
if not unixtime:
return None
return datetime.fromtimestamp(unixtime)
@staticmethod
def _totimestamp(dt_obj):
"""
Args:
dt_obj (:class:`datetime.datetime`):
Returns:
int:
"""
if not dt_obj:
return None
try:
# Python 3.3+
return int(dt_obj.timestamp())
except AttributeError:
# Python 3 (< 3.3) and Python 2
return int(mktime(dt_obj.timetuple()))
+7
View File
@@ -16,10 +16,17 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a logging NullHandler"""
import logging
class NullHandler(logging.Handler):
"""This object represents a logging NullHandler."""
def emit(self, record):
"""
Args:
record (str):
"""
pass
+7 -10
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python
# pylint: disable=R0903
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
@@ -16,15 +17,11 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram
Message Parse Modes"""
import logging
import unittest
from tests.test_bot import BotTest
if __name__ == '__main__':
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
testsuite = unittest.TestLoader().loadTestsFromTestCase(BotTest)
unittest.TextTestRunner(verbosity=1).run(testsuite)
class ParseMode(object):
"""This object represents a Telegram Message Parse Modes."""
MARKDOWN = 'Markdown'
+53 -15
View File
@@ -16,32 +16,70 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram PhotoSize"""
from telegram import TelegramObject
class PhotoSize(TelegramObject):
"""This object represents a Telegram PhotoSize.
Attributes:
file_id (str):
width (int):
height (int):
file_size (int):
Args:
file_id (str):
width (int):
height (int):
**kwargs: Arbitrary keyword arguments.
Keyword Args:
file_size (Optional[int]):
"""
def __init__(self,
file_id,
width,
height,
file_size=None):
**kwargs):
# Required
self.file_id = file_id
self.width = width
self.height = height
self.file_size = file_size
self.width = int(width)
self.height = int(height)
# Optionals
self.file_size = int(kwargs.get('file_size', 0))
@staticmethod
def de_json(data):
return PhotoSize(file_id=data.get('file_id', None),
width=data.get('width', None),
height=data.get('height', None),
file_size=data.get('file_size', None))
"""
Args:
data (str):
def to_dict(self):
data = {'file_id': self.file_id,
'width': self.width,
'height': self.height}
if self.file_size:
data['file_size'] = self.file_size
return data
Returns:
telegram.PhotoSize:
"""
if not data:
return None
return PhotoSize(**data)
@staticmethod
def de_list(data):
"""
Args:
data (list):
Returns:
List<telegram.PhotoSize>:
"""
if not data:
return []
photos = list()
for photo in data:
photos.append(PhotoSize.de_json(photo))
return photos
+31 -10
View File
@@ -16,24 +16,45 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram
ReplyKeyboardHide"""
from telegram import ReplyMarkup
class ReplyKeyboardHide(ReplyMarkup):
"""This object represents a Telegram ReplyKeyboardHide.
Attributes:
hide_keyboard (bool):
selective (bool):
Args:
hide_keyboard (bool):
**kwargs: Arbitrary keyword arguments.
Keyword Args:
selective (Optional[bool]):
"""
def __init__(self,
hide_keyboard=True,
selective=None):
self.hide_keyboard = hide_keyboard
self.selective = selective
**kwargs):
# Required
self.hide_keyboard = bool(hide_keyboard)
# Optionals
self.selective = bool(kwargs.get('selective', False))
@staticmethod
def de_json(data):
return ReplyKeyboardHide(hide_keyboard=data.get('hide_keyboard', None),
selective=data.get('selective', None))
"""
Args:
data (str):
def to_dict(self):
data = {'hide_keyboard': self.hide_keyboard}
if self.selective:
data['selective'] = self.selective
return data
Returns:
telegram.ReplyKeyboardHide:
"""
if not data:
return None
return ReplyKeyboardHide(**data)
+36 -23
View File
@@ -16,38 +16,51 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram
ReplyKeyboardMarkup"""
from telegram import ReplyMarkup
class ReplyKeyboardMarkup(ReplyMarkup):
"""This object represents a Telegram ReplyKeyboardMarkup.
Attributes:
keyboard (List[List[str]]):
resize_keyboard (bool):
one_time_keyboard (bool):
selective (bool):
Args:
keyboard (List[List[str]]):
**kwargs: Arbitrary keyword arguments.
Keyword Args:
resize_keyboard (Optional[bool]):
one_time_keyboard (Optional[bool]):
selective (Optional[bool]):
"""
def __init__(self,
keyboard,
resize_keyboard=None,
one_time_keyboard=None,
selective=None):
**kwargs):
# Required
self.keyboard = keyboard
self.resize_keyboard = resize_keyboard
self.one_time_keyboard = one_time_keyboard
self.selective = selective
# Optionals
self.resize_keyboard = bool(kwargs.get('resize_keyboard', False))
self.one_time_keyboard = bool(kwargs.get('one_time_keyboard', False))
self.selective = bool(kwargs.get('selective', False))
@staticmethod
def de_json(data):
return ReplyKeyboardMarkup(keyboard=data.get('keyboard', None),
resize_keyboard=data.get(
'resize_keyboard', None
),
one_time_keyboard=data.get(
'one_time_keyboard', None
),
selective=data.get('selective', None))
"""
Args:
data (str):
def to_dict(self):
data = {'keyboard': self.keyboard}
if self.resize_keyboard:
data['resize_keyboard'] = self.resize_keyboard
if self.one_time_keyboard:
data['one_time_keyboard'] = self.one_time_keyboard
if self.selective:
data['selective'] = self.selective
return data
Returns:
telegram.ReplyKeyboardMarkup:
"""
if not data:
return None
return ReplyKeyboardMarkup(**data)
+6 -1
View File
@@ -16,9 +16,14 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""Base class for Telegram ReplyMarkup Objects"""
from telegram import TelegramObject
class ReplyMarkup(TelegramObject):
pass
"""Base class for Telegram ReplyMarkup Objects"""
@staticmethod
def de_json(data):
pass
+41 -26
View File
@@ -16,42 +16,57 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram Sticker"""
from telegram import TelegramObject
from telegram import PhotoSize, TelegramObject
class Sticker(TelegramObject):
"""This object represents a Telegram Sticker.
Attributes:
file_id (str):
width (int):
height (int):
thumb (:class:`telegram.PhotoSize`):
file_size (int):
Args:
file_id (str):
width (int):
height (int):
**kwargs: Arbitrary keyword arguments.
Keyword Args:
thumb (Optional[:class:`telegram.PhotoSize`]):
file_size (Optional[int]):
"""
def __init__(self,
file_id,
width,
height,
thumb=None,
file_size=None):
self.file_id = file_id
self.width = width
self.height = height
self.thumb = thumb
self.file_size = file_size
**kwargs):
# Required
self.file_id = str(file_id)
self.width = int(width)
self.height = int(height)
# Optionals
self.thumb = kwargs.get('thumb')
self.file_size = int(kwargs.get('file_size', 0))
@staticmethod
def de_json(data):
if 'thumb' in data:
from telegram import PhotoSize
thumb = PhotoSize.de_json(data['thumb'])
else:
thumb = None
"""
Args:
data (str):
return Sticker(file_id=data.get('file_id', None),
width=data.get('width', None),
height=data.get('height', None),
thumb=thumb,
file_size=data.get('file_size', None))
Returns:
telegram.Sticker:
"""
if not data:
return None
def to_dict(self):
data = {'file_id': self.file_id,
'width': self.width,
'height': self.height,
'thumb': self.thumb.to_dict()}
if self.file_size:
data['file_size'] = self.file_size
return data
data['thumb'] = PhotoSize.de_json(data.get('thumb'))
return Sticker(**data)
+31 -16
View File
@@ -16,30 +16,45 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram Update"""
from telegram import TelegramObject
from telegram import Message, TelegramObject
class Update(TelegramObject):
"""This object represents a Telegram Update.
Attributes:
update_id (int):
message (:class:`telegram.Message`):
Args:
update_id (int):
**kwargs: Arbitrary keyword arguments.
Keyword Args:
message (Optional[:class:`telegram.Message`]):
"""
def __init__(self,
update_id,
message=None):
self.update_id = update_id
self.message = message
**kwargs):
# Required
self.update_id = int(update_id)
# Optionals
self.message = kwargs.get('message')
@staticmethod
def de_json(data):
if 'message' in data:
from telegram import Message
message = Message.de_json(data['message'])
else:
message = None
"""
Args:
data (str):
return Update(update_id=data.get('update_id', None),
message=message)
Returns:
telegram.Update:
"""
if not data:
return None
def to_dict(self):
data = {'update_id': self.update_id}
if self.message:
data['message'] = self.message.to_dict()
return data
data['message'] = Message.de_json(data['message'])
return Update(**data)
+40 -17
View File
@@ -1,4 +1,5 @@
#!/usr/bin/env python
# pylint: disable=C0103,W0622
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
@@ -16,23 +17,47 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram User"""
from telegram import TelegramObject
class User(TelegramObject):
"""This object represents a Telegram User.
Attributes:
id (int):
first_name (str):
last_name (str):
username (str):
type (str):
Args:
id (int):
first_name (str):
**kwargs: Arbitrary keyword arguments.
Keyword Args:
type (Optional[str]):
last_name (Optional[str]):
username (Optional[str]):
"""
def __init__(self,
id,
first_name,
last_name=None,
username=None):
self.id = id
**kwargs):
# Required
self.id = int(id)
self.first_name = first_name
self.last_name = last_name
self.username = username
# Optionals
self.type = kwargs.get('type', '')
self.last_name = kwargs.get('last_name', '')
self.username = kwargs.get('username', '')
@property
def name(self):
"""str: """
if self.username:
return '@%s' % self.username
if self.last_name:
@@ -41,16 +66,14 @@ class User(TelegramObject):
@staticmethod
def de_json(data):
return User(id=data.get('id', None),
first_name=data.get('first_name', None),
last_name=data.get('last_name', None),
username=data.get('username', None))
"""
Args:
data (str):
def to_dict(self):
data = {'id': self.id,
'first_name': self.first_name}
if self.last_name:
data['last_name'] = self.last_name
if self.username:
data['username'] = self.username
return data
Returns:
telegram.User:
"""
if not data:
return None
return User(**data)
+38 -18
View File
@@ -16,36 +16,56 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram
UserProfilePhotos"""
from telegram import TelegramObject
from telegram import PhotoSize, TelegramObject
class UserProfilePhotos(TelegramObject):
"""This object represents a Telegram UserProfilePhotos.
Attributes:
total_count (int):
photos (List[List[:class:`telegram.PhotoSize`]]):
Args:
total_count (int):
photos (List[List[:class:`telegram.PhotoSize`]]):
"""
def __init__(self,
total_count,
photos):
self.total_count = total_count
# Required
self.total_count = int(total_count)
self.photos = photos
@staticmethod
def de_json(data):
if 'photos' in data:
from telegram import PhotoSize
photos = []
for photo in data['photos']:
photos.append([PhotoSize.de_json(x) for x in photo])
else:
photos = None
"""
Args:
data (str):
return UserProfilePhotos(total_count=data.get('total_count', None),
photos=photos)
Returns:
telegram.UserProfilePhotos:
"""
if not data:
return None
data['photos'] = [PhotoSize.de_list(photo) for photo in data['photos']]
return UserProfilePhotos(**data)
def to_dict(self):
data = {}
if self.total_count:
data['total_count'] = self.total_count
if self.photos:
data['photos'] = []
for photo in self.photos:
data['photos'].append([x.to_dict() for x in photo])
"""
Returns:
dict:
"""
data = super(UserProfilePhotos, self).to_dict()
data['photos'] = []
for photo in self.photos:
data['photos'].append([x.to_dict() for x in photo])
return data
View File
+129
View File
@@ -0,0 +1,129 @@
#!/usr/bin/env python
# pylint: disable=no-name-in-module,unused-import
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains methods to make POST and GET requests"""
import json
from ssl import SSLError
try:
from urllib.request import urlopen, urlretrieve, Request
from urllib.error import HTTPError
except ImportError:
from urllib import urlretrieve
from urllib2 import urlopen, Request
from urllib2 import HTTPError
from telegram import (InputFile, TelegramError)
def _parse(json_data):
"""Try and parse the JSON returned from Telegram and return an empty
dictionary if there is any error.
Args:
url:
urllib.urlopen object
Returns:
A JSON parsed as Python dict with results.
"""
data = json.loads(json_data.decode())
if not data.get('ok') and data.get('description'):
return data['description']
return data['result']
def get(url):
"""Request an URL.
Args:
url:
The web location we want to retrieve.
Returns:
A JSON object.
"""
result = urlopen(url).read()
return _parse(result)
def post(url,
data):
"""Request an URL.
Args:
url:
The web location we want to retrieve.
data:
A dict of (str, unicode) key/value pairs.
Returns:
A JSON object.
"""
# Add one second to the timeout of urlopen to allow data to be transferred
# over the network.
if 'timeout' in data:
timeout = data['timeout'] + 1.
else:
timeout = None
try:
if InputFile.is_inputfile(data):
data = InputFile(data)
request = Request(url,
data=data.to_form(),
headers=data.headers)
else:
data = json.dumps(data)
request = Request(url,
data=data.encode(),
headers={'Content-Type': 'application/json'})
result = urlopen(request, timeout=timeout).read()
except HTTPError as error:
if error.getcode() == 403:
raise TelegramError('Unauthorized')
if error.getcode() == 502:
raise TelegramError('Bad Gateway')
message = _parse(error.read())
raise TelegramError(message)
except SSLError as error:
if "The read operation timed out" == error.message:
raise TelegramError("Timed out")
raise TelegramError(error.message)
return _parse(result)
def download(url,
filename):
"""Download a file by its URL.
Args:
url:
The web location we want to retrieve.
filename:
The filename wihtin the path to download the file.
"""
urlretrieve(url, filename)
+47 -35
View File
@@ -16,52 +16,64 @@
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram Video"""
from telegram import TelegramObject
from telegram import PhotoSize, TelegramObject
class Video(TelegramObject):
"""This object represents a Telegram Video.
Attributes:
file_id (str):
width (int):
height (int):
duration (int):
thumb (:class:`telegram.PhotoSize`):
mime_type (str):
file_size (int):
Args:
file_id (str):
width (int):
height (int):
duration (int):
**kwargs: Arbitrary keyword arguments.
Keyword Args:
thumb (Optional[:class:`telegram.PhotoSize`]):
mime_type (Optional[str]):
file_size (Optional[int]):
"""
def __init__(self,
file_id,
width,
height,
duration,
thumb=None,
mime_type=None,
file_size=None):
self.file_id = file_id
self.width = width
self.height = height
self.duration = duration
self.thumb = thumb
self.mime_type = mime_type
self.file_size = file_size
**kwargs):
# Required
self.file_id = str(file_id)
self.width = int(width)
self.height = int(height)
self.duration = int(duration)
# Optionals
self.thumb = kwargs.get('thumb')
self.mime_type = str(kwargs.get('mime_type', ''))
self.file_size = int(kwargs.get('file_size', 0))
@staticmethod
def de_json(data):
if 'thumb' in data:
from telegram import PhotoSize
thumb = PhotoSize.de_json(data['thumb'])
else:
thumb = None
"""
Args:
data (str):
return Video(file_id=data.get('file_id', None),
width=data.get('width', None),
height=data.get('height', None),
duration=data.get('duration', None),
thumb=thumb,
mime_type=data.get('mime_type', None),
file_size=data.get('file_size', None))
Returns:
telegram.Video:
"""
if not data:
return None
def to_dict(self):
data = {'file_id': self.file_id,
'width': self.width,
'height': self.height,
'duration': self.duration}
if self.thumb:
data['thumb'] = self.thumb.to_dict()
if self.mime_type:
data['mime_type'] = self.mime_type
if self.file_size:
data['file_size'] = self.file_size
return data
data['thumb'] = PhotoSize.de_json(data.get('thumb'))
return Video(**data)
+65
View File
@@ -0,0 +1,65 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Telegram Voice"""
from telegram import TelegramObject
class Voice(TelegramObject):
"""This object represents a Telegram Voice.
Attributes:
file_id (str):
duration (int):
mime_type (str):
file_size (int):
Args:
file_id (str):
**kwargs: Arbitrary keyword arguments.
Keyword Args:
duration (Optional[int]):
mime_type (Optional[str]):
file_size (Optional[int]):
"""
def __init__(self,
file_id,
**kwargs):
# Required
self.file_id = str(file_id)
# Optionals
self.duration = int(kwargs.get('duration', 0))
self.mime_type = str(kwargs.get('mime_type', ''))
self.file_size = int(kwargs.get('file_size', 0))
@staticmethod
def de_json(data):
"""
Args:
data (str):
Returns:
telegram.Voice:
"""
if not data:
return None
return Voice(**data)
+55
View File
@@ -0,0 +1,55 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents a Base class for tests"""
import os
import sys
sys.path.append('.')
import json
import telegram
class BaseTest(object):
"""This object represents a Base test and its sets of functions."""
def __init__(self, *args, **kwargs):
super(BaseTest, self).__init__(*args, **kwargs)
bot = telegram.Bot(os.environ.get('TOKEN'))
chat_id = os.environ.get('CHAT_ID')
self._bot = bot
self._chat_id = chat_id
@staticmethod
def is_json(string):
try:
json.loads(string)
except ValueError:
return False
return True
@staticmethod
def is_dict(dictionary):
if isinstance(dictionary, dict):
return True
return False
Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

+221
View File
@@ -0,0 +1,221 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram Audio"""
import os
import unittest
import sys
sys.path.append('.')
import telegram
from tests.base import BaseTest
class AudioTest(BaseTest, unittest.TestCase):
"""This object represents Tests for Telegram Audio."""
def setUp(self):
self.audio_file = open('tests/data/telegram.mp3', 'rb')
self.audio_file_id = 'BQADAQADDwADHyP1B6PSPq2HjX8kAg'
self.duration = 4
self.performer = 'Leandro Toledo'
self.title = 'Teste'
self.mime_type = 'audio/mpeg'
self.file_size = 28232
self.json_dict = {
'file_id': self.audio_file_id,
'duration': self.duration,
'performer': self.performer,
'title': self.title,
'mime_type': self.mime_type,
'file_size': self.file_size
}
def test_send_audio_required_args_only(self):
"""Test telegram.Bot sendAudio method"""
print('Testing bot.sendAudio - With required arguments only')
message = self._bot.sendAudio(self._chat_id,
self.audio_file)
audio = message.audio
self.assertTrue(isinstance(audio.file_id, str))
self.assertNotEqual(audio.file_id, '')
self.assertEqual(audio.duration, 4)
self.assertEqual(audio.performer, '')
self.assertEqual(audio.title, '')
self.assertEqual(audio.mime_type, self.mime_type)
self.assertEqual(audio.file_size, self.file_size)
def test_send_audio_all_args(self):
"""Test telegram.Bot sendAudio method"""
print('Testing bot.sendAudio - With all arguments')
message = self._bot.sendAudio(self._chat_id,
self.audio_file,
duration=self.duration,
performer=self.performer,
title=self.title,
mime_type=self.mime_type,
file_size=self.file_size)
audio = message.audio
self.assertTrue(isinstance(audio.file_id, str))
self.assertNotEqual(audio.file_id, '')
self.assertEqual(audio.duration, self.duration)
self.assertEqual(audio.performer, self.performer)
self.assertEqual(audio.title, self.title)
self.assertEqual(audio.mime_type, self.mime_type)
self.assertEqual(audio.file_size, self.file_size)
def test_send_audio_mp3_file(self):
"""Test telegram.Bot sendAudio method"""
print('Testing bot.sendAudio - MP3 File')
message = self._bot.sendAudio(chat_id=self._chat_id,
audio=self.audio_file,
duration=self.duration,
performer=self.performer,
title=self.title)
audio = message.audio
self.assertTrue(isinstance(audio.file_id, str))
self.assertNotEqual(audio.file_id, '')
self.assertEqual(audio.duration, self.duration)
self.assertEqual(audio.performer, self.performer)
self.assertEqual(audio.title, self.title)
self.assertEqual(audio.mime_type, self.mime_type)
self.assertEqual(audio.file_size, self.file_size)
def test_send_audio_mp3_file_custom_filename(self):
"""Test telegram.Bot sendAudio method"""
print('Testing bot.sendAudio - MP3 File with custom filename')
message = self._bot.sendAudio(chat_id=self._chat_id,
audio=self.audio_file,
duration=self.duration,
performer=self.performer,
title=self.title,
filename='telegram_custom.mp3')
audio = message.audio
self.assertTrue(isinstance(audio.file_id, str))
self.assertNotEqual(audio.file_id, '')
self.assertEqual(audio.duration, self.duration)
self.assertEqual(audio.performer, self.performer)
self.assertEqual(audio.title, self.title)
self.assertEqual(audio.mime_type, self.mime_type)
self.assertEqual(audio.file_size, self.file_size)
def test_send_audio_resend(self):
"""Test telegram.Bot sendAudio method"""
print('Testing bot.sendAudio - Resend by file_id')
message = self._bot.sendAudio(chat_id=self._chat_id,
audio=self.audio_file_id,
duration=self.duration,
performer=self.performer,
title=self.title)
audio = message.audio
self.assertEqual(audio.file_id, self.audio_file_id)
self.assertEqual(audio.duration, self.duration)
self.assertEqual(audio.performer, self.performer)
self.assertEqual(audio.title, self.title)
self.assertEqual(audio.mime_type, self.mime_type)
def test_audio_de_json(self):
"""Test Audio.de_json() method"""
print('Testing Audio.de_json()')
audio = telegram.Audio.de_json(self.json_dict)
self.assertEqual(audio.file_id, self.audio_file_id)
self.assertEqual(audio.duration, self.duration)
self.assertEqual(audio.performer, self.performer)
self.assertEqual(audio.title, self.title)
self.assertEqual(audio.mime_type, self.mime_type)
self.assertEqual(audio.file_size, self.file_size)
def test_audio_to_json(self):
"""Test Audio.to_json() method"""
print('Testing Audio.to_json()')
audio = telegram.Audio.de_json(self.json_dict)
self.assertTrue(self.is_json(audio.to_json()))
def test_audio_to_dict(self):
"""Test Audio.to_dict() method"""
print('Testing Audio.to_dict()')
audio = telegram.Audio.de_json(self.json_dict)
self.assertTrue(self.is_dict(audio.to_dict()))
self.assertEqual(audio['file_id'], self.audio_file_id)
self.assertEqual(audio['duration'], self.duration)
self.assertEqual(audio['performer'], self.performer)
self.assertEqual(audio['title'], self.title)
self.assertEqual(audio['mime_type'], self.mime_type)
self.assertEqual(audio['file_size'], self.file_size)
def test_error_send_audio_empty_file(self):
print('Testing bot.sendAudio - Null file')
json_dict = self.json_dict
del(json_dict['file_id'])
json_dict['audio'] = open(os.devnull, 'rb')
self.assertRaises(telegram.TelegramError,
lambda: self._bot.sendAudio(chat_id=self._chat_id,
**json_dict))
def test_error_send_audio_empty_file_id(self):
print('Testing bot.sendAudio - Empty file_id')
json_dict = self.json_dict
del(json_dict['file_id'])
json_dict['audio'] = ''
self.assertRaises(telegram.TelegramError,
lambda: self._bot.sendAudio(chat_id=self._chat_id,
**json_dict))
def test_error_audio_without_required_args(self):
print('Testing bot.sendAudio - Without required arguments')
json_dict = self.json_dict
del(json_dict['file_id'])
del(json_dict['duration'])
self.assertRaises(TypeError,
lambda: self._bot.sendAudio(chat_id=self._chat_id,
**json_dict))
if __name__ == '__main__':
unittest.main()
+73 -88
View File
@@ -17,140 +17,125 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram Bot"""
import os
import telegram
import unittest
from datetime import datetime
import sys
sys.path.append('.')
import telegram
from tests.base import BaseTest
class BotTest(unittest.TestCase):
def setUp(self):
bot = telegram.Bot(token=os.environ.get('TOKEN'))
self._bot = bot
print('Testing the Bot API class')
class BotTest(BaseTest, unittest.TestCase):
"""This object represents Tests for Telegram Bot."""
def testGetMe(self):
'''Test the telegram.Bot getMe method'''
print('Testing getMe')
bot = self._bot.getMe()
self.assertEqual(120405045, bot.id)
self.assertEqual('Toledo\'s Palace Bot', bot.first_name)
self.assertEqual(None, bot.last_name)
self.assertEqual('ToledosPalaceBot', bot.username)
self.assertTrue(self.is_json(bot.to_json()))
self.assertEqual(bot.id, 133505823)
self.assertEqual(bot.first_name, 'PythonTelegramBot')
self.assertEqual(bot.last_name, '')
self.assertEqual(bot.username, 'PythonTelegramBot')
self.assertEqual(bot.name, '@PythonTelegramBot')
def testSendMessage(self):
'''Test the telegram.Bot sendMessage method'''
print('Testing sendMessage')
message = self._bot.sendMessage(chat_id=12173560,
message = self._bot.sendMessage(chat_id=self._chat_id,
text='Моё судно на воздушной подушке полно угрей')
self.assertEqual(u'Моё судно на воздушной подушке полно угрей', message.text)
self.assertTrue(self.is_json(message.to_json()))
self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей')
self.assertTrue(isinstance(message.date, datetime))
def testGetUpdates(self):
'''Test the telegram.Bot getUpdates method'''
print('Testing getUpdates')
updates = self._bot.getUpdates()
self.assertIsInstance(updates[0], telegram.Update)
if updates:
self.assertTrue(self.is_json(updates[0].to_json()))
self.assertTrue(isinstance(updates[0], telegram.Update))
def testForwardMessage(self):
'''Test the telegram.Bot forwardMessage method'''
print('Testing forwardMessage')
message = self._bot.forwardMessage(chat_id=12173560,
from_chat_id=12173560,
message_id=138)
self.assertEqual('Oi', message.text)
self.assertEqual('leandrotoledo', message.forward_from.username)
message = self._bot.forwardMessage(chat_id=self._chat_id,
from_chat_id=self._chat_id,
message_id=2398)
self.assertTrue(self.is_json(message.to_json()))
self.assertEqual(message.text, 'teste')
self.assertEqual(message.forward_from.username, 'leandrotoledo')
self.assertTrue(isinstance(message.forward_date, datetime))
def testSendPhoto(self):
'''Test the telegram.Bot sendPhoto method'''
print('Testing sendPhoto - File')
message = self._bot.sendPhoto(photo=open('tests/telegram.png', 'rb'),
message = self._bot.sendPhoto(photo=open('tests/data/telegram.png', 'rb'),
caption='testSendPhoto',
chat_id=12173560)
self.assertEqual(1451, message.photo[0].file_size)
self.assertEqual('testSendPhoto', message.caption)
chat_id=self._chat_id)
self.assertTrue(self.is_json(message.to_json()))
self.assertEqual(message.photo[0].file_size, 1451)
self.assertEqual(message.caption, 'testSendPhoto')
def testResendPhoto(self):
'''Test the telegram.Bot sendPhoto method'''
print('Testing sendPhoto - Resend')
message = self._bot.sendPhoto(photo=str('AgADAQADr6cxGzU8LQe6q0dMJD2rHYkP2ykABFymiQqJgjxRGGMAAgI'),
chat_id=12173560)
self.assertEqual('AgADAQADr6cxGzU8LQe6q0dMJD2rHYkP2ykABFymiQqJgjxRGGMAAgI', message.photo[0].file_id)
message = self._bot.sendPhoto(photo='AgADAQADyKcxGx8j9Qdp6d-gpUsw4Gja1i8ABEVJsVqQk8LfJ3wAAgI',
chat_id=self._chat_id)
def testSendURLPhoto(self):
self.assertTrue(self.is_json(message.to_json()))
self.assertEqual(message.photo[0].file_id, 'AgADAQADyKcxGx8j9Qdp6d-gpUsw4Gja1i8ABEVJsVqQk8LfJ3wAAgI')
def testSendJPGURLPhoto(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)
print('Testing testSendJPGURLPhoto - URL')
message = self._bot.sendPhoto(photo='http://dummyimage.com/600x400/000/fff.jpg&text=telegram',
chat_id=self._chat_id)
def testSendAudio(self):
'''Test the telegram.Bot sendAudio method'''
print('Testing sendAudio - File')
message = self._bot.sendAudio(audio=open('tests/telegram.ogg', 'rb'),
chat_id=12173560)
self.assertEqual(9199, message.audio.file_size)
self.assertTrue(self.is_json(message.to_json()))
self.assertEqual(message.photo[0].file_size, 822)
def testResendAudio(self):
'''Test the telegram.Bot sendAudio method'''
print('Testing sendAudio - Resend')
message = self._bot.sendAudio(audio=str('AwADAQADIQEAAvjAuQABSAXg_GhkhZcC'),
chat_id=12173560)
self.assertEqual('AwADAQADIQEAAvjAuQABSAXg_GhkhZcC', message.audio.file_id)
def testSendPNGURLPhoto(self):
'''Test the telegram.Bot sendPhoto method'''
print('Testing testSendPNGURLPhoto - URL')
message = self._bot.sendPhoto(photo='http://dummyimage.com/600x400/000/fff.png&text=telegram',
chat_id=self._chat_id)
def testSendDocument(self):
'''Test the telegram.Bot sendDocument method'''
print('Testing sendDocument - File')
message = self._bot.sendDocument(document=open('tests/telegram.png', 'rb'),
chat_id=12173560)
self.assertEqual(12948, message.document.file_size)
self.assertTrue(self.is_json(message.to_json()))
self.assertEqual(message.photo[0].file_size, 684)
def testResendDocument(self):
'''Test the telegram.Bot sendDocument method'''
print('Testing sendDocument - Resend')
message = self._bot.sendDocument(document=str('BQADAQADHAADNTwtBxZxUGKyxYbYAg'),
chat_id=12173560)
self.assertEqual('BQADAQADHAADNTwtBxZxUGKyxYbYAg', message.document.file_id)
def testSendGIFURLPhoto(self):
'''Test the telegram.Bot sendPhoto method'''
print('Testing testSendGIFURLPhoto - URL')
message = self._bot.sendPhoto(photo='http://dummyimage.com/600x400/000/fff.gif&text=telegram',
chat_id=self._chat_id)
def testSendVideo(self):
'''Test the telegram.Bot sendVideo method'''
print('Testing sendVideo - File')
message = self._bot.sendVideo(video=open('tests/telegram.mp4', 'rb'),
caption='testSendVideo',
chat_id=12173560)
self.assertEqual(326534, message.video.file_size)
self.assertEqual('testSendVideo', message.caption)
def testResendVideo(self):
'''Test the telegram.Bot sendVideo method'''
print('Testing sendVideo - Resend')
message = self._bot.sendVideo(video=str('BAADAQADIgEAAvjAuQABOuTB937fPTgC'),
chat_id=12173560)
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):
'''Test the telegram.Bot sendLocation method'''
print('Testing sendLocation')
message = self._bot.sendLocation(latitude=-23.558873,
longitude=-46.659732,
chat_id=12173560)
self.assertEqual(-23.558873, message.location.latitude)
self.assertEqual(-46.659732, message.location.longitude)
self.assertTrue(self.is_json(message.to_json()))
self.assertEqual(message.photo[0].file_size, 684)
def testSendChatAction(self):
'''Test the telegram.Bot sendChatAction method'''
print('Testing sendChatAction - ChatAction.TYPING')
self._bot.sendChatAction(action=telegram.ChatAction.TYPING,
chat_id=12173560)
chat_id=self._chat_id)
def testGetUserProfilePhotos(self):
'''Test the telegram.Bot getUserProfilePhotos method'''
print('Testing getUserProfilePhotos')
upf = self._bot.getUserProfilePhotos(user_id=12173560)
self.assertEqual(6547, upf.photos[0][0].file_size)
upf = self._bot.getUserProfilePhotos(user_id=self._chat_id)
self.assertTrue(self.is_json(upf.to_json()))
self.assertEqual(upf.photos[0][0].file_size, 6547)
if __name__ == '__main__':
unittest.main()
+78
View File
@@ -0,0 +1,78 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram Contact"""
import os
import unittest
import sys
sys.path.append('.')
import telegram
from tests.base import BaseTest
class ContactTest(BaseTest, unittest.TestCase):
"""This object represents Tests for Telegram Contact."""
def setUp(self):
self.phone_number = '+11234567890'
self.first_name = 'Leandro Toledo'
self.last_name = ''
self.user_id = 0
self.json_dict = {
'phone_number': self.phone_number,
'first_name': self.first_name,
'last_name': self.last_name,
'user_id': self.user_id
}
def test_contact_de_json(self):
"""Test Contact.de_json() method"""
print('Testing Contact.de_json()')
contact = telegram.Contact.de_json(self.json_dict)
self.assertEqual(contact.phone_number, self.phone_number)
self.assertEqual(contact.first_name, self.first_name)
self.assertEqual(contact.last_name, self.last_name)
self.assertEqual(contact.user_id, self.user_id)
def test_contact_to_json(self):
"""Test Contact.to_json() method"""
print('Testing Contact.to_json()')
contact = telegram.Contact.de_json(self.json_dict)
self.assertTrue(self.is_json(contact.to_json()))
def test_contact_to_dict(self):
"""Test Contact.to_dict() method"""
print('Testing Contact.to_dict()')
contact = telegram.Contact.de_json(self.json_dict)
self.assertTrue(self.is_dict(contact.to_dict()))
self.assertEqual(contact['phone_number'], self.phone_number)
self.assertEqual(contact['first_name'], self.first_name)
self.assertEqual(contact['last_name'], self.last_name)
self.assertEqual(contact['user_id'], self.user_id)
if __name__ == '__main__':
unittest.main()
+185
View File
@@ -0,0 +1,185 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram Document"""
import os
import unittest
import sys
sys.path.append('.')
import telegram
from tests.base import BaseTest
class DocumentTest(BaseTest, unittest.TestCase):
"""This object represents Tests for Telegram Document."""
def setUp(self):
self.document_file = open('tests/data/telegram.png', 'rb')
self.document_file_id = 'BQADAQADpAADHyP1B04ipZxJTe2BAg'
self.document_file_url = 'http://dummyimage.com/600x400/000/fff.gif&text=telegram'
self.thumb = {'width': 90,
'height': 90,
'file_id': 'BQADAQADoQADHyP1B0mzJMVyzcB0Ag',
'file_size': 2364}
self.file_name = 'telegram.png'
self.mime_type = 'image/png'
self.file_size = 12948
self.json_dict = {
'file_id': self.document_file_id,
'thumb': self.thumb,
'file_name': self.file_name,
'mime_type': self.mime_type,
'file_size': self.file_size
}
def test_send_document_png_file(self):
"""Test telegram.Bot sendDocument method"""
print('Testing bot.sendDocument - PNG File')
message = self._bot.sendDocument(self._chat_id,
self.document_file)
document = message.document
self.assertTrue(isinstance(document.file_id, str))
self.assertNotEqual(document.file_id, '')
self.assertTrue(isinstance(document.thumb, telegram.PhotoSize))
self.assertEqual(document.file_name, self.file_name)
self.assertEqual(document.mime_type, self.mime_type)
self.assertEqual(document.file_size, self.file_size)
def test_send_document_png_file_with_custom_file_name(self):
"""Test telegram.Bot sendDocument method"""
print('Testing bot.sendDocument - PNG File with custom filename')
message = self._bot.sendDocument(self._chat_id,
self.document_file,
filename='telegram_custom.png')
document = message.document
self.assertTrue(isinstance(document.file_id, str))
self.assertNotEqual(document.file_id, '')
self.assertTrue(isinstance(document.thumb, telegram.PhotoSize))
self.assertEqual(document.file_name, 'telegram_custom.png')
self.assertEqual(document.mime_type, self.mime_type)
self.assertEqual(document.file_size, self.file_size)
def test_send_document_url_gif_file(self):
"""Test telegram.Bot sendDocument method"""
print('Testing bot.sendDocument - GIF File by URL')
message = self._bot.sendDocument(self._chat_id,
self.document_file_url)
document = message.document
self.assertTrue(isinstance(document.file_id, str))
self.assertNotEqual(document.file_id, '')
self.assertTrue(isinstance(document.thumb, telegram.PhotoSize))
self.assertEqual(document.file_name, 'image.gif')
self.assertEqual(document.mime_type, 'image/gif')
self.assertEqual(document.file_size, 3878)
def test_send_document_resend(self):
"""Test telegram.Bot sendDocument method"""
print('Testing bot.sendDocument - Resend by file_id')
message = self._bot.sendDocument(chat_id=self._chat_id,
document=self.document_file_id)
document = message.document
self.assertEqual(document.file_id, self.document_file_id)
self.assertTrue(isinstance(document.thumb, telegram.PhotoSize))
self.assertEqual(document.file_name, self.file_name)
self.assertEqual(document.mime_type, self.mime_type)
def test_document_de_json(self):
"""Test Document.de_json() method"""
print('Testing Document.de_json()')
document = telegram.Document.de_json(self.json_dict)
self.assertEqual(document.file_id, self.document_file_id)
self.assertTrue(isinstance(document.thumb, telegram.PhotoSize))
self.assertEqual(document.file_name, self.file_name)
self.assertEqual(document.mime_type, self.mime_type)
self.assertEqual(document.file_size, self.file_size)
def test_document_to_json(self):
"""Test Document.to_json() method"""
print('Testing Document.to_json()')
document = telegram.Document.de_json(self.json_dict)
self.assertTrue(self.is_json(document.to_json()))
def test_document_to_dict(self):
"""Test Document.to_dict() method"""
print('Testing Document.to_dict()')
document = telegram.Document.de_json(self.json_dict)
self.assertTrue(self.is_dict(document.to_dict()))
self.assertEqual(document['file_id'], self.document_file_id)
self.assertTrue(isinstance(document['thumb'], telegram.PhotoSize))
self.assertEqual(document['file_name'], self.file_name)
self.assertEqual(document['mime_type'], self.mime_type)
self.assertEqual(document['file_size'], self.file_size)
def test_error_send_document_empty_file(self):
print('Testing bot.sendDocument - Null file')
json_dict = self.json_dict
del(json_dict['file_id'])
json_dict['document'] = open(os.devnull, 'rb')
self.assertRaises(telegram.TelegramError,
lambda: self._bot.sendDocument(chat_id=self._chat_id,
**json_dict))
def test_error_send_document_empty_file_id(self):
print('Testing bot.sendDocument - Empty file_id')
json_dict = self.json_dict
del(json_dict['file_id'])
json_dict['document'] = ''
self.assertRaises(telegram.TelegramError,
lambda: self._bot.sendDocument(chat_id=self._chat_id,
**json_dict))
def test_error_document_without_required_args(self):
print('Testing bot.sendDocument - Without required arguments')
json_dict = self.json_dict
del(json_dict['file_id'])
self.assertRaises(TypeError,
lambda: self._bot.sendDocument(chat_id=self._chat_id,
**json_dict))
if __name__ == '__main__':
unittest.main()
+44
View File
@@ -0,0 +1,44 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram Emoji"""
import os
import unittest
import sys
sys.path.append('.')
import telegram
from telegram.emoji import Emoji
from tests.base import BaseTest
class EmojiTest(BaseTest, unittest.TestCase):
"""This object represents Tests for Telegram Emoji."""
def test_emoji(self):
"""Test Emoji class"""
print('Testing Emoji class')
for attr in dir(Emoji):
if attr[0] != '_': # TODO: dirty way to filter out functions
self.assertTrue(type(getattr(Emoji, attr)) is str)
if __name__ == '__main__':
unittest.main()
+171
View File
@@ -0,0 +1,171 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram File"""
import os
import unittest
import sys
sys.path.append('.')
import telegram
from tests.base import BaseTest
class FileTest(BaseTest, unittest.TestCase):
"""This object represents Tests for Telegram File."""
def setUp(self):
self.audio_file_id = 'BQADAQADDwADHyP1B6PSPq2HjX8kAg'
self.document_file_id = 'BQADAQADpAADHyP1B04ipZxJTe2BAg'
self.sticker_file_id = 'BQADAQADHAADyIsGAAFZfq1bphjqlgI'
self.video_file_id = 'BAADAQADXwADHyP1BwJFTcmY2RYCAg'
self.voice_file_id = 'AwADAQADTgADHyP1B_mbw34svXPHAg'
self.json_dict = {
'file_id': self.audio_file_id,
'file_path': 'https://api.telegram.org/file/bot133505823:AAHZFMHno3mzVLErU5b5jJvaeG--qUyLyG0/document/file_3',
'file_size': 28232
}
def test_get_and_download_file_audio(self):
"""Test telegram.Bot getFile method - Audio"""
print('Testing bot.getFile - With Audio.file_id')
newFile = self._bot.getFile(self.audio_file_id)
self.assertEqual(newFile.file_size, 28232)
self.assertEqual(newFile.file_id, self.audio_file_id)
self.assertTrue(newFile.file_path.startswith('https://'))
newFile.download('telegram.mp3')
self.assertTrue(os.path.isfile('telegram.mp3'))
def test_get_and_download_file_document(self):
"""Test telegram.Bot getFile method - Document"""
print('Testing bot.getFile - With Document.file_id')
newFile = self._bot.getFile(self.document_file_id)
self.assertEqual(newFile.file_size, 12948)
self.assertEqual(newFile.file_id, self.document_file_id)
self.assertTrue(newFile.file_path.startswith('https://'))
newFile.download('telegram.png')
self.assertTrue(os.path.isfile('telegram.png'))
def test_get_and_download_file_sticker(self):
"""Test telegram.Bot getFile method - Sticker"""
print('Testing bot.getFile - With Sticker.file_id')
newFile = self._bot.getFile(self.sticker_file_id)
self.assertEqual(newFile.file_size, 39518)
self.assertEqual(newFile.file_id, self.sticker_file_id)
self.assertTrue(newFile.file_path.startswith('https://'))
newFile.download('telegram.webp')
self.assertTrue(os.path.isfile('telegram.webp'))
def test_get_and_download_file_video(self):
"""Test telegram.Bot getFile method - Video"""
print('Testing bot.getFile - With Video.file_id')
newFile = self._bot.getFile(self.video_file_id)
self.assertEqual(newFile.file_size, 326534)
self.assertEqual(newFile.file_id, self.video_file_id)
self.assertTrue(newFile.file_path.startswith('https://'))
newFile.download('telegram.mp4')
self.assertTrue(os.path.isfile('telegram.mp4'))
def test_get_and_download_file_voice(self):
"""Test telegram.Bot getFile method - Voice"""
print('Testing bot.getFile - With Voice.file_id')
newFile = self._bot.getFile(self.voice_file_id)
self.assertEqual(newFile.file_size, 9199)
self.assertEqual(newFile.file_id, self.voice_file_id)
self.assertTrue(newFile.file_path.startswith('https://'))
newFile.download('telegram.ogg')
self.assertTrue(os.path.isfile('telegram.ogg'))
def test_file_de_json(self):
"""Test File.de_json() method"""
print('Testing File.de_json()')
newFile = telegram.File.de_json(self.json_dict)
self.assertEqual(newFile.file_id, self.json_dict['file_id'])
self.assertEqual(newFile.file_path, self.json_dict['file_path'])
self.assertEqual(newFile.file_size, self.json_dict['file_size'])
def test_file_to_json(self):
"""Test File.to_json() method"""
print('Testing File.to_json()')
newFile = telegram.File.de_json(self.json_dict)
self.assertTrue(self.is_json(newFile.to_json()))
def test_file_to_dict(self):
"""Test File.to_dict() method"""
print('Testing File.to_dict()')
newFile = telegram.File.de_json(self.json_dict)
self.assertTrue(self.is_dict(newFile.to_dict()))
self.assertEqual(newFile['file_id'], self.json_dict['file_id'])
self.assertEqual(newFile['file_path'], self.json_dict['file_path'])
self.assertEqual(newFile['file_size'], self.json_dict['file_size'])
def test_error_get_empty_file_id(self):
print('Testing bot.getFile - Null file_id')
json_dict = self.json_dict
json_dict['file_id'] = ''
del(json_dict['file_path'])
del(json_dict['file_size'])
self.assertRaises(telegram.TelegramError,
lambda: self._bot.getFile(**json_dict))
def test_error_file_without_required_args(self):
print('Testing bot.getFile - Without required arguments')
json_dict = self.json_dict
del(json_dict['file_id'])
del(json_dict['file_path'])
del(json_dict['file_size'])
self.assertRaises(TypeError,
lambda: self._bot.getFile(**json_dict))
if __name__ == '__main__':
unittest.main()
+82
View File
@@ -0,0 +1,82 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram GroupChat"""
import os
import unittest
import sys
sys.path.append('.')
import telegram
from tests.base import BaseTest
class GroupChatTest(BaseTest, unittest.TestCase):
"""This object represents Tests for Telegram GroupChat."""
def setUp(self):
self.id = -28767330
self.title = 'ToledosPalaceBot - Group'
self.type = 'group'
self.json_dict = {
'id': self.id,
'title': self.title,
'type': self.type
}
def test_group_chat_de_json_empty_json(self):
"""Test GroupChat.de_json() method"""
print('Testing GroupChat.de_json() - Empty JSON')
group_chat = telegram.GroupChat.de_json({})
self.assertEqual(group_chat, None)
def test_group_chat_de_json(self):
"""Test GroupChat.de_json() method"""
print('Testing GroupChat.de_json()')
group_chat = telegram.GroupChat.de_json(self.json_dict)
self.assertEqual(group_chat.id, self.id)
self.assertEqual(group_chat.title, self.title)
self.assertEqual(group_chat.type, self.type)
def test_group_chat_to_json(self):
"""Test GroupChat.to_json() method"""
print('Testing GroupChat.to_json()')
group_chat = telegram.GroupChat.de_json(self.json_dict)
self.assertTrue(self.is_json(group_chat.to_json()))
def test_group_chat_to_dict(self):
"""Test GroupChat.to_dict() method"""
print('Testing GroupChat.to_dict()')
group_chat = telegram.GroupChat.de_json(self.json_dict)
self.assertTrue(self.is_dict(group_chat.to_dict()))
self.assertEqual(group_chat['id'], self.id)
self.assertEqual(group_chat['title'], self.title)
self.assertEqual(group_chat['type'], self.type)
if __name__ == '__main__':
unittest.main()
+119
View File
@@ -0,0 +1,119 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram Location"""
import os
import unittest
import sys
sys.path.append('.')
import telegram
from tests.base import BaseTest
class LocationTest(BaseTest, unittest.TestCase):
"""This object represents Tests for Telegram Location."""
def setUp(self):
self.latitude = -23.691288
self.longitude = -46.788279
self.json_dict = {
'latitude': self.latitude,
'longitude': self.longitude
}
def test_send_location_implicit_args(self):
"""Test telegram.Bot sendLocation method"""
print('Testing bot.sendLocation - Implicit arguments')
message = self._bot.sendLocation(self._chat_id,
self.latitude,
self.longitude)
location = message.location
self.assertEqual(location.latitude, self.latitude)
self.assertEqual(location.longitude, self.longitude)
def test_send_location_explicit_args(self):
"""Test telegram.Bot sendLocation method"""
print('Testing bot.sendLocation - Explicit arguments')
message = self._bot.sendLocation(chat_id=self._chat_id,
latitude=self.latitude,
longitude=self.longitude)
location = message.location
self.assertEqual(location.latitude, self.latitude)
self.assertEqual(location.longitude, self.longitude)
def test_location_de_json(self):
"""Test Location.de_json() method"""
print('Testing Location.de_json()')
location = telegram.Location.de_json(self.json_dict)
self.assertEqual(location.latitude, self.latitude)
self.assertEqual(location.longitude, self.longitude)
def test_location_to_json(self):
"""Test Location.to_json() method"""
print('Testing Location.to_json()')
location = telegram.Location.de_json(self.json_dict)
self.assertTrue(self.is_json(location.to_json()))
def test_location_to_dict(self):
"""Test Location.to_dict() method"""
print('Testing Location.to_dict()')
location = telegram.Location.de_json(self.json_dict)
self.assertEqual(location['latitude'], self.latitude)
self.assertEqual(location['longitude'], self.longitude)
def test_error_send_location_empty_args(self):
print('Testing bot.sendLocation - Empty arguments')
json_dict = self.json_dict
json_dict['latitude'] = ''
json_dict['longitude'] = ''
self.assertRaises(telegram.TelegramError,
lambda: self._bot.sendLocation(chat_id=self._chat_id,
**json_dict))
def test_error_location_without_required_args(self):
print('Testing bot.sendLocation - Without required arguments')
json_dict = self.json_dict
del(json_dict['latitude'])
del(json_dict['longitude'])
self.assertRaises(TypeError,
lambda: self._bot.sendLocation(chat_id=self._chat_id,
**json_dict))
if __name__ == '__main__':
unittest.main()
+137
View File
@@ -0,0 +1,137 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram Sticker"""
import os
import unittest
import sys
sys.path.append('.')
import telegram
from tests.base import BaseTest
class StickerTest(BaseTest, unittest.TestCase):
"""This object represents Tests for Telegram Sticker."""
def setUp(self):
self.sticker_file_id = 'BQADAQADHAADyIsGAAFZfq1bphjqlgI'
self.width = 510
self.height = 512
self.thumb = {'width': 90,
'height': 90,
'file_id': 'BQADAQADoQADHyP1B0mzJMVyzcB0Ag',
'file_size': 2364}
self.file_size = 39518
self.json_dict = {
'file_id': self.sticker_file_id,
'width': self.width,
'height': self.height,
'thumb': self.thumb,
'file_size': self.file_size
}
def test_send_sticker_file(self):
pass
def test_send_sticker_resend(self):
"""Test telegram.Bot sendSticker method"""
print('Testing bot.sendSticker - Resend by file_id')
message = self._bot.sendSticker(chat_id=self._chat_id,
sticker=self.sticker_file_id)
sticker = message.sticker
self.assertEqual(sticker.file_id, self.sticker_file_id)
self.assertEqual(sticker.width, self.width)
self.assertEqual(sticker.height, self.height)
self.assertTrue(isinstance(sticker.thumb, telegram.PhotoSize))
self.assertEqual(sticker.file_size, self.file_size)
def test_sticker_de_json(self):
"""Test Sticker.de_json() method"""
print('Testing Sticker.de_json()')
sticker = telegram.Sticker.de_json(self.json_dict)
self.assertEqual(sticker.file_id, self.sticker_file_id)
self.assertEqual(sticker.width, self.width)
self.assertEqual(sticker.height, self.height)
self.assertTrue(isinstance(sticker.thumb, telegram.PhotoSize))
self.assertEqual(sticker.file_size, self.file_size)
def test_sticker_to_json(self):
"""Test Sticker.to_json() method"""
print('Testing Sticker.to_json()')
sticker = telegram.Sticker.de_json(self.json_dict)
self.assertTrue(self.is_json(sticker.to_json()))
def test_sticker_to_dict(self):
"""Test Sticker.to_dict() method"""
print('Testing Sticker.to_dict()')
sticker = telegram.Sticker.de_json(self.json_dict)
self.assertEqual(sticker['file_id'], self.sticker_file_id)
self.assertEqual(sticker['width'], self.width)
self.assertEqual(sticker['height'], self.height)
self.assertTrue(isinstance(sticker['thumb'], telegram.PhotoSize))
self.assertEqual(sticker['file_size'], self.file_size)
def test_error_send_sticker_empty_file(self):
print('Testing bot.sendSticker - Null file')
json_dict = self.json_dict
del(json_dict['file_id'])
json_dict['sticker'] = open(os.devnull, 'rb')
self.assertRaises(telegram.TelegramError,
lambda: self._bot.sendSticker(chat_id=self._chat_id,
**json_dict))
def test_error_send_sticker_empty_file_id(self):
print('Testing bot.sendSticker - Empty file_id')
json_dict = self.json_dict
del(json_dict['file_id'])
json_dict['sticker'] = ''
self.assertRaises(telegram.TelegramError,
lambda: self._bot.sendSticker(chat_id=self._chat_id,
**json_dict))
def test_error_sticker_without_required_args(self):
print('Testing bot.sendSticker - Without required arguments')
json_dict = self.json_dict
del(json_dict['file_id'])
self.assertRaises(TypeError,
lambda: self._bot.sendSticker(chat_id=self._chat_id,
**json_dict))
if __name__ == '__main__':
unittest.main()
+80
View File
@@ -0,0 +1,80 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram Update"""
import os
import unittest
import sys
sys.path.append('.')
import telegram
from tests.base import BaseTest
class UpdateTest(BaseTest, unittest.TestCase):
"""This object represents Tests for Telegram Update."""
def setUp(self):
self.update_id = 868573637
self.message = {'message_id': 319,
'from': {'id': 12173560,
'first_name': "Leandro",
'last_name': "S.",
'username': "leandrotoledo"},
'chat': {'id': 12173560,
'first_name': "Leandro",
'last_name': "S.",
'username': "leandrotoledo"},
'date': 1441644592,
'text': "Update Test"}
self.json_dict = {
'update_id': self.update_id,
'message': self.message
}
def test_update_de_json(self):
"""Test Update.de_json() method"""
print('Testing Update.de_json()')
update = telegram.Update.de_json(self.json_dict)
self.assertEqual(update.update_id, self.update_id)
self.assertTrue(isinstance(update.message, telegram.Message))
def test_update_to_json(self):
"""Test Update.to_json() method"""
print('Testing Update.to_json()')
update = telegram.Update.de_json(self.json_dict)
self.assertTrue(self.is_json(update.to_json()))
def test_update_to_dict(self):
"""Test Update.to_dict() method"""
print('Testing Update.to_dict()')
update = telegram.Update.de_json(self.json_dict)
self.assertTrue(self.is_dict(update.to_dict()))
self.assertEqual(update['update_id'], self.update_id)
self.assertTrue(isinstance(update['message'], telegram.Message))
if __name__ == '__main__':
unittest.main()
+118
View File
@@ -0,0 +1,118 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram User"""
import os
import unittest
import sys
sys.path.append('.')
import telegram
from tests.base import BaseTest
class UserTest(BaseTest, unittest.TestCase):
"""This object represents Tests for Telegram User."""
def setUp(self):
self.id = 12173560
self.first_name = "Leandro"
self.last_name = "S."
self.username = "leandrotoledo"
self.type = "private"
self.json_dict = {
'id': self.id,
'first_name': self.first_name,
'last_name': self.last_name,
'username': self.username,
'type': self.type
}
def test_user_de_json(self):
"""Test User.de_json() method"""
print('Testing User.de_json()')
user = telegram.User.de_json(self.json_dict)
self.assertEqual(user.id, self.id)
self.assertEqual(user.first_name, self.first_name)
self.assertEqual(user.last_name, self.last_name)
self.assertEqual(user.username, self.username)
self.assertEqual(user.type, self.type)
self.assertEqual(user.name, '@leandrotoledo')
def test_user_de_json_without_username(self):
"""Test User.de_json() method"""
print('Testing User.de_json() - Without username')
json_dict = self.json_dict
del(json_dict['username'])
user = telegram.User.de_json(self.json_dict)
self.assertEqual(user.id, self.id)
self.assertEqual(user.first_name, self.first_name)
self.assertEqual(user.last_name, self.last_name)
self.assertEqual(user.type, self.type)
self.assertEqual(user.name, '%s %s' % (self.first_name, self.last_name))
def test_user_de_json_without_username_and_lastname(self):
"""Test User.de_json() method"""
print('Testing User.de_json() - Without username and last_name')
json_dict = self.json_dict
del(json_dict['username'])
del(json_dict['last_name'])
user = telegram.User.de_json(self.json_dict)
self.assertEqual(user.id, self.id)
self.assertEqual(user.first_name, self.first_name)
self.assertEqual(user.name, self.first_name)
def test_user_to_json(self):
"""Test User.to_json() method"""
print('Testing User.to_json()')
user = telegram.User.de_json(self.json_dict)
self.assertTrue(self.is_json(user.to_json()))
def test_user_to_dict(self):
"""Test User.to_dict() method"""
print('Testing User.to_dict()')
user = telegram.User.de_json(self.json_dict)
self.assertTrue(self.is_dict(user.to_dict()))
self.assertEqual(user['id'], self.id)
self.assertEqual(user['first_name'], self.first_name)
self.assertEqual(user['last_name'], self.last_name)
self.assertEqual(user['username'], self.username)
self.assertEqual(user['type'], self.type)
if __name__ == '__main__':
unittest.main()
+232
View File
@@ -0,0 +1,232 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram Video"""
import os
import unittest
import sys
sys.path.append('.')
import telegram
from tests.base import BaseTest
class VideoTest(BaseTest, unittest.TestCase):
"""This object represents Tests for Telegram Video."""
def setUp(self):
self.video_file = open('tests/data/telegram.mp4', 'rb')
self.video_file_id = 'BAADAQADXwADHyP1BwJFTcmY2RYCAg'
self.width = 360
self.height = 640
self.duration = 4
self.thumb = telegram.PhotoSize.de_json({})
self.mime_type = 'video/mp4'
self.file_size = 326534
# caption is part of sendVideo method but not Video object
self.caption = u'VideoTest - Caption'
self.json_dict = {
'file_id': self.video_file_id,
'width': self.width,
'height': self.height,
'duration': self.duration,
'thumb': self.thumb,
'mime_type': self.mime_type,
'file_size': self.file_size
}
def test_send_video_required_args_only(self):
"""Test telegram.Bot sendVideo method"""
print('Testing bot.sendVideo - With required arguments only')
message = self._bot.sendVideo(self._chat_id,
self.video_file)
video = message.video
self.assertTrue(isinstance(video.file_id, str))
self.assertNotEqual(video.file_id, '')
self.assertEqual(video.width, 0)
self.assertEqual(video.height, 0)
self.assertEqual(video.duration, 0)
self.assertEqual(video.thumb, None)
self.assertEqual(video.mime_type, '')
self.assertEqual(video.file_size, self.file_size)
def test_send_video_all_args(self):
"""Test telegram.Bot sendAudio method"""
print('Testing bot.sendVideo - With all arguments')
message = self._bot.sendVideo(self._chat_id,
self.video_file,
duration=self.duration,
caption=self.caption)
video = message.video
self.assertTrue(isinstance(video.file_id, str))
self.assertNotEqual(video.file_id, '')
self.assertEqual(video.width, 0)
self.assertEqual(video.height, 0)
self.assertEqual(video.duration, self.duration)
self.assertEqual(video.thumb, None)
self.assertEqual(video.mime_type, '')
self.assertEqual(video.file_size, self.file_size)
self.assertEqual(message.caption, self.caption)
def test_send_video_mp4_file(self):
"""Test telegram.Bot sendVideo method"""
print('Testing bot.sendVideo - MP4 File')
message = self._bot.sendVideo(chat_id=self._chat_id,
video=self.video_file,
duration=self.duration,
caption=self.caption)
video = message.video
self.assertTrue(isinstance(video.file_id, str))
self.assertNotEqual(video.file_id, '')
self.assertEqual(video.width, 0)
self.assertEqual(video.height, 0)
self.assertEqual(video.duration, self.duration)
self.assertEqual(video.thumb, None)
self.assertEqual(video.mime_type, '')
self.assertEqual(video.file_size, self.file_size)
self.assertEqual(message.caption, self.caption)
def test_send_video_mp4_file_with_custom_filename(self):
"""Test telegram.Bot sendVideo method"""
print('Testing bot.sendVideo - MP4 File with custom filename')
message = self._bot.sendVideo(chat_id=self._chat_id,
video=self.video_file,
duration=self.duration,
caption=self.caption,
filename='telegram_custom.mp4')
video = message.video
self.assertTrue(isinstance(video.file_id, str))
self.assertNotEqual(video.file_id, '')
self.assertEqual(video.width, 0)
self.assertEqual(video.height, 0)
self.assertEqual(video.duration, self.duration)
self.assertEqual(video.thumb, None)
self.assertEqual(video.mime_type, '')
self.assertEqual(video.file_size, self.file_size)
self.assertEqual(message.caption, self.caption)
def test_send_video_resend(self):
"""Test telegram.Bot sendVideo method"""
print('Testing bot.sendVideo - Resend by file_id')
message = self._bot.sendVideo(chat_id=self._chat_id,
video=self.video_file_id,
duration=self.duration,
caption=self.caption)
video = message.video
self.assertEqual(video.file_id, self.video_file_id)
self.assertEqual(video.duration, 0)
self.assertEqual(video.thumb, None)
self.assertEqual(video.mime_type, '')
self.assertEqual(message.caption, self.caption)
def test_video_de_json(self):
"""Test Video.de_json() method"""
print('Testing Video.de_json()')
video = telegram.Video.de_json(self.json_dict)
self.assertEqual(video.file_id, self.video_file_id)
self.assertEqual(video.width, self.width)
self.assertEqual(video.height, self.height)
self.assertEqual(video.duration, self.duration)
self.assertEqual(video.thumb, None)
self.assertEqual(video.mime_type, self.mime_type)
self.assertEqual(video.file_size, self.file_size)
def test_video_to_json(self):
"""Test Video.to_json() method"""
print('Testing Video.to_json()')
video = telegram.Video.de_json(self.json_dict)
self.assertTrue(self.is_json(video.to_json()))
def test_video_to_dict(self):
"""Test Video.to_dict() method"""
print('Testing Video.to_dict()')
video = telegram.Video.de_json(self.json_dict)
self.assertTrue(self.is_dict(video.to_dict()))
self.assertEqual(video['file_id'], self.video_file_id)
self.assertEqual(video['width'], self.width)
self.assertEqual(video['height'], self.height)
self.assertEqual(video['duration'], self.duration)
self.assertEqual(video['mime_type'], self.mime_type)
self.assertEqual(video['file_size'], self.file_size)
def test_error_send_video_empty_file(self):
print('Testing bot.sendVideo - Null file')
json_dict = self.json_dict
del(json_dict['file_id'])
json_dict['video'] = open(os.devnull, 'rb')
self.assertRaises(telegram.TelegramError,
lambda: self._bot.sendVideo(chat_id=self._chat_id,
**json_dict))
def test_error_send_video_empty_file_id(self):
print('Testing bot.sendVideo - Empty file_id')
json_dict = self.json_dict
del(json_dict['file_id'])
json_dict['video'] = ''
self.assertRaises(telegram.TelegramError,
lambda: self._bot.sendVideo(chat_id=self._chat_id,
**json_dict))
def test_error_video_without_required_args(self):
print('Testing bot.sendVideo - Without required arguments')
json_dict = self.json_dict
del(json_dict['file_id'])
del(json_dict['duration'])
self.assertRaises(TypeError,
lambda: self._bot.sendVideo(chat_id=self._chat_id,
**json_dict))
if __name__ == '__main__':
unittest.main()
+195
View File
@@ -0,0 +1,195 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains a object that represents Tests for Telegram Voice"""
import os
import unittest
import sys
sys.path.append('.')
import telegram
from tests.base import BaseTest
class VoiceTest(BaseTest, unittest.TestCase):
"""This object represents Tests for Telegram Voice."""
def setUp(self):
self.voice_file = open('tests/data/telegram.ogg', 'rb')
self.voice_file_id = 'AwADAQADTgADHyP1B_mbw34svXPHAg'
self.duration = 0
self.mime_type = 'audio/ogg'
self.file_size = 9199
self.json_dict = {
'file_id': self.voice_file_id,
'duration': self.duration,
'mime_type': self.mime_type,
'file_size': self.file_size
}
def test_send_voice_required_args_only(self):
"""Test telegram.Bot sendVoice method"""
print('Testing bot.sendVoice - With required arguments only')
message = self._bot.sendVoice(self._chat_id,
self.voice_file)
voice = message.voice
self.assertTrue(isinstance(voice.file_id, str))
self.assertNotEqual(voice.file_id, '')
self.assertEqual(voice.duration, self.duration)
self.assertEqual(voice.mime_type, self.mime_type)
self.assertEqual(voice.file_size, self.file_size)
def test_send_voice_all_args(self):
"""Test telegram.Bot sendAudio method"""
print('Testing bot.sendVoice - With all arguments')
message = self._bot.sendVoice(self._chat_id,
self.voice_file,
self.duration,
mime_type=self.mime_type,
file_size=self.file_size)
voice = message.voice
self.assertTrue(isinstance(voice.file_id, str))
self.assertNotEqual(voice.file_id, '')
self.assertEqual(voice.duration, self.duration)
self.assertEqual(voice.mime_type, self.mime_type)
self.assertEqual(voice.file_size, self.file_size)
def test_send_voice_ogg_file(self):
"""Test telegram.Bot sendVoice method"""
print('Testing bot.sendVoice - Ogg File')
message = self._bot.sendVoice(chat_id=self._chat_id,
voice=self.voice_file,
duration=self.duration)
voice = message.voice
self.assertTrue(isinstance(voice.file_id, str))
self.assertNotEqual(voice.file_id, '')
self.assertEqual(voice.duration, self.duration)
self.assertEqual(voice.mime_type, self.mime_type)
self.assertEqual(voice.file_size, self.file_size)
def test_send_voice_ogg_file_with_custom_filename(self):
"""Test telegram.Bot sendVoice method"""
print('Testing bot.sendVoice - Ogg File with custom filename')
message = self._bot.sendVoice(chat_id=self._chat_id,
voice=self.voice_file,
duration=self.duration,
filename='telegram_custom.ogg')
voice = message.voice
self.assertTrue(isinstance(voice.file_id, str))
self.assertNotEqual(voice.file_id, '')
self.assertEqual(voice.duration, self.duration)
self.assertEqual(voice.mime_type, self.mime_type)
self.assertEqual(voice.file_size, self.file_size)
def test_send_voice_resend(self):
"""Test telegram.Bot sendVoice method"""
print('Testing bot.sendVoice - Resend by file_id')
message = self._bot.sendVoice(chat_id=self._chat_id,
voice=self.voice_file_id,
duration=self.duration)
voice = message.voice
self.assertEqual(voice.file_id, self.voice_file_id)
self.assertEqual(voice.duration, self.duration)
self.assertEqual(voice.mime_type, self.mime_type)
def test_voice_de_json(self):
"""Test Voice.de_json() method"""
print('Testing Voice.de_json()')
voice = telegram.Voice.de_json(self.json_dict)
self.assertEqual(voice.file_id, self.voice_file_id)
self.assertEqual(voice.duration, self.duration)
self.assertEqual(voice.mime_type, self.mime_type)
self.assertEqual(voice.file_size, self.file_size)
def test_voice_to_json(self):
"""Test Voice.to_json() method"""
print('Testing Voice.to_json()')
voice = telegram.Voice.de_json(self.json_dict)
self.assertTrue(self.is_json(voice.to_json()))
def test_voice_to_dict(self):
"""Test Voice.to_dict() method"""
print('Testing Voice.to_dict()')
voice = telegram.Voice.de_json(self.json_dict)
self.assertTrue(self.is_dict(voice.to_dict()))
self.assertEqual(voice['file_id'], self.voice_file_id)
self.assertEqual(voice['duration'], self.duration)
self.assertEqual(voice['mime_type'], self.mime_type)
self.assertEqual(voice['file_size'], self.file_size)
def test_error_send_voice_empty_file(self):
print('Testing bot.sendVoice - Null file')
json_dict = self.json_dict
del(json_dict['file_id'])
json_dict['voice'] = open(os.devnull, 'rb')
self.assertRaises(telegram.TelegramError,
lambda: self._bot.sendVoice(chat_id=self._chat_id,
**json_dict))
def test_error_send_voice_empty_file_id(self):
print('Testing bot.sendVoice - Empty file_id')
json_dict = self.json_dict
del(json_dict['file_id'])
json_dict['voice'] = ''
self.assertRaises(telegram.TelegramError,
lambda: self._bot.sendVoice(chat_id=self._chat_id,
**json_dict))
def test_error_voice_without_required_args(self):
print('Testing bot.sendVoice - Without required arguments')
json_dict = self.json_dict
del(json_dict['file_id'])
del(json_dict['duration'])
self.assertRaises(TypeError,
lambda: self._bot.sendVoice(chat_id=self._chat_id,
**json_dict))
if __name__ == '__main__':
unittest.main()