From 9c79ba2f876d34941c10d94acd5dde5a42b26224 Mon Sep 17 00:00:00 2001
From: Badiboy <badialex@gmail.com>
Date: Mon, 14 May 2018 13:29:34 +0300
Subject: [PATCH 1/9] html_text fix and html_caption

html_text now works with text_link
html_caption now works for caption/caption_entities
---
 telebot/types.py | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/telebot/types.py b/telebot/types.py
index d958908..5ca1b4e 100644
--- a/telebot/types.py
+++ b/telebot/types.py
@@ -437,8 +437,7 @@ class Message(JsonDeserializable):
             setattr(self, key, options[key])
         self.json = json_string
 
-    @property
-    def html_text(self):
+    def __html_text(self, text, entities):
         """
         Author: @sviat9440
         Message: "*Test* parse _formatting_, [url](https://example.com), [text_mention](tg://user?id=123456) and mention @username"
@@ -455,19 +454,20 @@ class Message(JsonDeserializable):
             >> "<strong class=\"example\">Test</strong> parse <i class=\"example\">formatting</i>, <a href=\"https://example.com\">url</a> and <a href=\"tg://user?id=123456\">text_mention</a> and mention <a href=\"https://t.me/username\">@username</a>"
         """
 
-        if not self.entities:
-            return self.text
+        if not entities:
+            return text
         _subs = {
             "bold": "<b>{text}</b>",
             "italic": "<i>{text}</i>",
             "pre": "<pre>{text}</pre>",
             "code": "<code>{text}</code>",
-            "url": "<a href=\"{url}\">{text}</a>"
+            "url": "<a href=\"{url}\">{text}</a>",
+            "text_link": "<a href=\"{url}\">{text}</a>"
         }
         if hasattr(self, "custom_subs"):
             for type in self.custom_subs:
                 _subs[type] = self.custom_subs[type]
-        utf16_text = self.text.encode("utf-16-le")
+        utf16_text = text.encode("utf-16-le")
         html_text = ""
         def func(text, type=None, url=None, user=None):
             text = text.decode("utf-16-le")
@@ -483,7 +483,7 @@ class Message(JsonDeserializable):
             return subs.format(text=text, url=url)
 
         offset = 0
-        for entity in self.entities:
+        for entity in entities:
             if entity.offset > offset:
                 html_text += func(utf16_text[offset * 2 : entity.offset * 2])
                 offset = entity.offset
@@ -493,6 +493,13 @@ class Message(JsonDeserializable):
             html_text += func(utf16_text[offset * 2:])
         return html_text
 
+    @property
+    def html_text(self):
+        return self.__html_text(self.text, self.entities)
+
+    @property
+    def html_caption(self):
+        return self.__html_text(self.caption, self.caption_entities)
 
 class MessageEntity(JsonDeserializable):
     @classmethod

From 78afd045d81b32bdc5b024e7eb6c8c2645650cd4 Mon Sep 17 00:00:00 2001
From: Badiboy <badialex@gmail.com>
Date: Sun, 27 May 2018 23:24:37 +0300
Subject: [PATCH 2/9] _notify_next_handlers drops messages if empty handler
 list

After calling
clear_step_handler(...)
code:
self.next_step_handlers[chat_id] = []
left the key in next_step_handlers.
When a next message arrives, the old handler executes nothing (no handlers), but still remove message from message queue:
new_messages.pop(i).

Updated to pop message only when there are real handlers in the list.
---
 telebot/__init__.py | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/telebot/__init__.py b/telebot/__init__.py
index 8f9b60b..2204bfa 100644
--- a/telebot/__init__.py
+++ b/telebot/__init__.py
@@ -1155,10 +1155,11 @@ class TeleBot:
             chat_id = message.chat.id
             if chat_id in self.next_step_handlers.keys():
                 handlers = self.next_step_handlers[chat_id]
-                for handler in handlers:
-                    self._exec_task(handler["callback"], message, *handler["args"], **handler["kwargs"])
+                if (handlers):
+                    for handler in handlers:
+                        self._exec_task(handler["callback"], message, *handler["args"], **handler["kwargs"])
+                    new_messages.pop(i)  # removing message that detects with next_step_handler
                 self.next_step_handlers.pop(chat_id, None)
-                new_messages.pop(i)  # removing message that detects with next_step_handler
             i += 1
 
     @staticmethod

From 776a699a8d78d621e8d2dcce9bac7e7041a36307 Mon Sep 17 00:00:00 2001
From: Badiboy <badialex@gmail.com>
Date: Tue, 29 May 2018 18:55:41 +0300
Subject: [PATCH 3/9] _notify_next_handlers skips sequential messages

Is there are several sequential messages and next_step_handlers are set, the _notify_next_handlers will process only every even message dew to execute both .pop(i) and i+=1
---
 telebot/__init__.py | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/telebot/__init__.py b/telebot/__init__.py
index 2204bfa..32ed84d 100644
--- a/telebot/__init__.py
+++ b/telebot/__init__.py
@@ -1153,14 +1153,17 @@ class TeleBot:
         while i < len(new_messages):
             message = new_messages[i]
             chat_id = message.chat.id
+            was_poped = False
             if chat_id in self.next_step_handlers.keys():
                 handlers = self.next_step_handlers[chat_id]
                 if (handlers):
                     for handler in handlers:
                         self._exec_task(handler["callback"], message, *handler["args"], **handler["kwargs"])
                     new_messages.pop(i)  # removing message that detects with next_step_handler
+                    was_poped = True
                 self.next_step_handlers.pop(chat_id, None)
-            i += 1
+            if (not was_poped):
+                i += 1
 
     @staticmethod
     def _build_handler_dict(handler, **filters):

From c8b2b1415745abc5278749dfc42e059bd65f332b Mon Sep 17 00:00:00 2001
From: users <skar404@gmail.com>
Date: Mon, 2 Jul 2018 18:13:11 +0300
Subject: [PATCH 4/9] rename async -> async_dec

---
 telebot/__init__.py | 114 ++++++++++++++++++++++----------------------
 telebot/util.py     |   2 +-
 2 files changed, 58 insertions(+), 58 deletions(-)

diff --git a/telebot/__init__.py b/telebot/__init__.py
index 32ed84d..fb7770b 100644
--- a/telebot/__init__.py
+++ b/telebot/__init__.py
@@ -1354,230 +1354,230 @@ class AsyncTeleBot(TeleBot):
     def __init__(self, *args, **kwargs):
         TeleBot.__init__(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def get_me(self):
         return TeleBot.get_me(self)
 
-    @util.async()
+    @util.async_dec()
     def get_file(self, *args):
         return TeleBot.get_file(self, *args)
 
-    @util.async()
+    @util.async_dec()
     def download_file(self, *args):
         return TeleBot.download_file(self, *args)
 
-    @util.async()
+    @util.async_dec()
     def get_user_profile_photos(self, *args, **kwargs):
         return TeleBot.get_user_profile_photos(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def get_chat(self, *args):
         return TeleBot.get_chat(self, *args)
 
-    @util.async()
+    @util.async_dec()
     def leave_chat(self, *args):
         return TeleBot.leave_chat(self, *args)
 
-    @util.async()
+    @util.async_dec()
     def get_chat_administrators(self, *args):
         return TeleBot.get_chat_administrators(self, *args)
 
-    @util.async()
+    @util.async_dec()
     def get_chat_members_count(self, *args):
         return TeleBot.get_chat_members_count(self, *args)
 
-    @util.async()
+    @util.async_dec()
     def set_chat_sticker_set(self, *args):
         return TeleBot.set_chat_sticker_set(self, *args)
 
-    @util.async()
+    @util.async_dec()
     def delete_chat_sticker_set(self, *args):
         return TeleBot.delete_chat_sticker_set(self, *args)
 
-    @util.async()
+    @util.async_dec()
     def get_chat_member(self, *args):
         return TeleBot.get_chat_member(self, *args)
 
-    @util.async()
+    @util.async_dec()
     def send_message(self, *args, **kwargs):
         return TeleBot.send_message(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def forward_message(self, *args, **kwargs):
         return TeleBot.forward_message(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def delete_message(self, *args):
         return TeleBot.delete_message(self, *args)
 
-    @util.async()
+    @util.async_dec()
     def send_photo(self, *args, **kwargs):
         return TeleBot.send_photo(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def send_audio(self, *args, **kwargs):
         return TeleBot.send_audio(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def send_voice(self, *args, **kwargs):
         return TeleBot.send_voice(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def send_document(self, *args, **kwargs):
         return TeleBot.send_document(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def send_sticker(self, *args, **kwargs):
         return TeleBot.send_sticker(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def send_video(self, *args, **kwargs):
         return TeleBot.send_video(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def send_video_note(self, *args, **kwargs):
         return TeleBot.send_video_note(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def send_media_group(self, *args, **kwargs):
         return TeleBot.send_media_group(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def send_location(self, *args, **kwargs):
         return TeleBot.send_location(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def edit_message_live_location(self, *args, **kwargs):
         return TeleBot.edit_message_live_location(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def stop_message_live_location(self, *args, **kwargs):
         return TeleBot.stop_message_live_location(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def send_venue(self, *args, **kwargs):
         return TeleBot.send_venue(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def send_contact(self, *args, **kwargs):
         return TeleBot.send_contact(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def send_chat_action(self, *args, **kwargs):
         return TeleBot.send_chat_action(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def kick_chat_member(self, *args, **kwargs):
         return TeleBot.kick_chat_member(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def unban_chat_member(self, *args):
         return TeleBot.unban_chat_member(self, *args)
 
-    @util.async()
+    @util.async_dec()
     def restrict_chat_member(self, *args, **kwargs):
         return TeleBot.restrict_chat_member(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def promote_chat_member(self, *args, **kwargs):
         return TeleBot.promote_chat_member(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def export_chat_invite_link(self, *args):
         return TeleBot.export_chat_invite_link(self, *args)
 
-    @util.async()
+    @util.async_dec()
     def set_chat_photo(self, *args):
         return TeleBot.set_chat_photo(self, *args)
 
-    @util.async()
+    @util.async_dec()
     def delete_chat_photo(self, *args):
         return TeleBot.delete_chat_photo(self, *args)
 
-    @util.async()
+    @util.async_dec()
     def set_chat_title(self, *args):
         return TeleBot.set_chat_title(self, *args)
 
-    @util.async()
+    @util.async_dec()
     def set_chat_description(self, *args):
         return TeleBot.set_chat_description(self, *args)
 
-    @util.async()
+    @util.async_dec()
     def pin_chat_message(self, *args, **kwargs):
         return TeleBot.pin_chat_message(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def unpin_chat_message(self, *args):
         return TeleBot.unpin_chat_message(self, *args)
 
-    @util.async()
+    @util.async_dec()
     def edit_message_text(self, *args, **kwargs):
         return TeleBot.edit_message_text(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def edit_message_reply_markup(self, *args, **kwargs):
         return TeleBot.edit_message_reply_markup(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def send_game(self, *args, **kwargs):
         return TeleBot.send_game(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def set_game_score(self, *args, **kwargs):
         return TeleBot.set_game_score(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def get_game_high_scores(self, *args, **kwargs):
         return TeleBot.get_game_high_scores(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def send_invoice(self, *args, **kwargs):
         return TeleBot.send_invoice(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def answer_shipping_query(self, *args, **kwargs):
         return TeleBot.answer_shipping_query(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def answer_pre_checkout_query(self, *args, **kwargs):
         return TeleBot.answer_pre_checkout_query(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def edit_message_caption(self, *args, **kwargs):
         return TeleBot.edit_message_caption(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def answer_inline_query(self, *args, **kwargs):
         return TeleBot.answer_inline_query(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def answer_callback_query(self, *args, **kwargs):
         return TeleBot.answer_callback_query(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def send_sticker(self, *args, **kwargs):
         return TeleBot.send_sticker(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def get_sticker_set(self, *args, **kwargs):
         return TeleBot.get_sticker_set(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def upload_sticker_file(self, *args, **kwargs):
         return TeleBot.upload_sticker_file(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def create_new_sticker_set(self, *args, **kwargs):
         return TeleBot.create_new_sticker_set(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def add_sticker_to_set(self, *args, **kwargs):
         return TeleBot.add_sticker_to_set(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def set_sticker_position_in_set(self, *args, **kwargs):
         return TeleBot.set_sticker_position_in_set(self, *args, **kwargs)
 
-    @util.async()
+    @util.async_dec()
     def delete_sticker_from_set(self, *args, **kwargs):
         return TeleBot.delete_sticker_from_set(self, *args, **kwargs)
diff --git a/telebot/util.py b/telebot/util.py
index 769f73b..f448d78 100644
--- a/telebot/util.py
+++ b/telebot/util.py
@@ -143,7 +143,7 @@ class AsyncTask:
             return self.result
 
 
-def async():
+def async_dec():
     def decorator(fn):
         def wrapper(*args, **kwargs):
             return AsyncTask(fn, *args, **kwargs)

From 9547a8d7b1dbf9934f44b765d9ec587c41c1d0cc Mon Sep 17 00:00:00 2001
From: user <skar404@gmail.com>
Date: Mon, 2 Jul 2018 23:23:48 +0300
Subject: [PATCH 5/9] test python 3.7

---
 .travis.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.travis.yml b/.travis.yml
index f5f202a..312da5f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,6 +6,7 @@ python:
     - "3.4"
     - "3.5"
     - "3.6"
+    - "3.7"
     - "pypy"
     - "pypy3"
 install: "pip install -r requirements.txt"

From 4079772fd3e0186bfea516490c8bd92189d79837 Mon Sep 17 00:00:00 2001
From: user <skar404@gmail.com>
Date: Mon, 2 Jul 2018 23:29:07 +0300
Subject: [PATCH 6/9] Update .travis.yml

---
 .travis.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index 312da5f..693456c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,7 +6,7 @@ python:
     - "3.4"
     - "3.5"
     - "3.6"
-    - "3.7"
+    - "3.7-dev"
     - "pypy"
     - "pypy3"
 install: "pip install -r requirements.txt"

From c3b6ee9dc0757b51234df87e9372f93d5a7b8c75 Mon Sep 17 00:00:00 2001
From: user <skar404@gmail.com>
Date: Mon, 2 Jul 2018 23:41:37 +0300
Subject: [PATCH 7/9] bug in travis-ci

---
 .travis.yml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index 693456c..f5f202a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,7 +6,6 @@ python:
     - "3.4"
     - "3.5"
     - "3.6"
-    - "3.7-dev"
     - "pypy"
     - "pypy3"
 install: "pip install -r requirements.txt"

From a3a2bd5793cc2411fa7c73785f169630dee742fb Mon Sep 17 00:00:00 2001
From: FrankWang <eternnoir@gmail.com>
Date: Tue, 3 Jul 2018 11:17:44 +0800
Subject: [PATCH 8/9] Add python 3.7 in travis ci.

#527
---
 .travis.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.travis.yml b/.travis.yml
index f5f202a..312da5f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,6 +6,7 @@ python:
     - "3.4"
     - "3.5"
     - "3.6"
+    - "3.7"
     - "pypy"
     - "pypy3"
 install: "pip install -r requirements.txt"

From 8bc5b744959b490f1df070032403742b08dd6537 Mon Sep 17 00:00:00 2001
From: FrankWang <eternnoir@gmail.com>
Date: Tue, 3 Jul 2018 22:34:28 +0800
Subject: [PATCH 9/9] Remove 3.7 stable. Travis ci not support now.

---
 .travis.yml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index 312da5f..f5f202a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,7 +6,6 @@ python:
     - "3.4"
     - "3.5"
     - "3.6"
-    - "3.7"
     - "pypy"
     - "pypy3"
 install: "pip install -r requirements.txt"