From 03de901b7ff057ac03f8b020d621fd77aca5a3b5 Mon Sep 17 00:00:00 2001
From: Lonami Exo <totufals@hotmail.com>
Date: Sat, 16 Oct 2021 12:40:25 +0200
Subject: [PATCH] Add enum for typing action

---
 readthedocs/misc/changelog.rst | 12 +++++++
 telethon/_client/chats.py      | 60 +++++++++++++---------------------
 telethon/_misc/enums.py        | 22 +++++++++++++
 telethon/enums.py              |  1 +
 4 files changed, 58 insertions(+), 37 deletions(-)

diff --git a/readthedocs/misc/changelog.rst b/readthedocs/misc/changelog.rst
index 951cf2e0..74005356 100644
--- a/readthedocs/misc/changelog.rst
+++ b/readthedocs/misc/changelog.rst
@@ -13,6 +13,18 @@ it can take advantage of new goodies!
 
 .. contents:: List of All Versions
 
+
+Complete overhaul of the library (v2.0)
+=======================================
+
++------------------------+
+| Scheme layer used: 133 |
++------------------------+
+
+(inc and link all of migration guide)
+properly-typed enums for filters and actions
+
+
 New schema and bug fixes (v1.23)
 ================================
 
diff --git a/telethon/_client/chats.py b/telethon/_client/chats.py
index 693feeab..3034b5d9 100644
--- a/telethon/_client/chats.py
+++ b/telethon/_client/chats.py
@@ -17,31 +17,6 @@ _MAX_PROFILE_PHOTO_CHUNK_SIZE = 100
 
 
 class _ChatAction:
-    _str_mapping = {
-        'typing': _tl.SendMessageTypingAction(),
-        'contact': _tl.SendMessageChooseContactAction(),
-        'game': _tl.SendMessageGamePlayAction(),
-        'location': _tl.SendMessageGeoLocationAction(),
-        'sticker': _tl.SendMessageChooseStickerAction(),
-
-        'record-audio': _tl.SendMessageRecordAudioAction(),
-        'record-voice': _tl.SendMessageRecordAudioAction(),  # alias
-        'record-round': _tl.SendMessageRecordRoundAction(),
-        'record-video': _tl.SendMessageRecordVideoAction(),
-
-        'audio': _tl.SendMessageUploadAudioAction(1),
-        'voice': _tl.SendMessageUploadAudioAction(1),  # alias
-        'song': _tl.SendMessageUploadAudioAction(1),  # alias
-        'round': _tl.SendMessageUploadRoundAction(1),
-        'video': _tl.SendMessageUploadVideoAction(1),
-
-        'photo': _tl.SendMessageUploadPhotoAction(1),
-        'document': _tl.SendMessageUploadDocumentAction(1),
-        'file': _tl.SendMessageUploadDocumentAction(1),  # alias
-
-        'cancel': _tl.SendMessageCancelAction()
-    }
-
     def __init__(self, client, chat, action, *, delay, auto_cancel):
         self._client = client
         self._chat = chat
@@ -88,6 +63,28 @@ class _ChatAction:
                 await self._client(_tl.fn.messages.SetTyping(
                     self._chat, _tl.SendMessageCancelAction()))
 
+    @staticmethod
+    def _parse(action):
+        if isinstance(action, tlobject.TLObject) and action.SUBCLASS_OF_ID != 0x20b2cc21:
+            return action
+
+        return {
+            enums.TYPING: _tl.SendMessageTypingAction(),
+            enums.CONTACT: _tl.SendMessageChooseContactAction(),
+            enums.GAME: _tl.SendMessageGamePlayAction(),
+            enums.LOCATION: _tl.SendMessageGeoLocationAction(),
+            enums.STICKER: _tl.SendMessageChooseStickerAction(),
+            enums.RECORD_AUDIO: _tl.SendMessageRecordAudioAction(),
+            enums.RECORD_ROUND: _tl.SendMessageRecordRoundAction(),
+            enums.RECORD_VIDEO: _tl.SendMessageRecordVideoAction(),
+            enums.AUDIO: _tl.SendMessageUploadAudioAction(1),
+            enums.ROUND: _tl.SendMessageUploadRoundAction(1),
+            enums.VIDEO: _tl.SendMessageUploadVideoAction(1),
+            enums.PHOTO: _tl.SendMessageUploadPhotoAction(1),
+            enums.DOCUMENT: _tl.SendMessageUploadDocumentAction(1),
+            enums.CANCEL: _tl.SendMessageCancelAction(),
+        }[enums.parse_typing_action(action)]
+
     def progress(self, current, total):
         if hasattr(self._action, 'progress'):
             self._action.progress = 100 * round(current / total)
@@ -457,18 +454,7 @@ def action(
         *,
         delay: float = 4,
         auto_cancel: bool = True) -> 'typing.Union[_ChatAction, typing.Coroutine]':
-    if isinstance(action, str):
-        try:
-            action = _ChatAction._str_mapping[action.lower()]
-        except KeyError:
-            raise ValueError(
-                'No such action "{}"'.format(action)) from None
-    elif not isinstance(action, tlobject.TLObject) or action.SUBCLASS_OF_ID != 0x20b2cc21:
-        # 0x20b2cc21 = crc32(b'SendMessageAction')
-        if isinstance(action, type):
-            raise ValueError('You must pass an instance, not the class')
-        else:
-            raise ValueError('Cannot use {} as action'.format(action))
+    action = _ChatAction._parse(action)
 
     if isinstance(action, _tl.SendMessageCancelAction):
         # ``SetTyping.resolve`` will get input peer of ``entity``.
diff --git a/telethon/_misc/enums.py b/telethon/_misc/enums.py
index edce6776..c8fa656b 100644
--- a/telethon/_misc/enums.py
+++ b/telethon/_misc/enums.py
@@ -17,6 +17,27 @@ class Participant(Enum):
     CONTACT = 'contact'
 
 
+class Action(Enum):
+    TYPING = 'typing'
+    CONTACT = 'contact'
+    GAME = 'game'
+    LOCATION = 'location'
+    STICKER = 'sticker'
+    RECORD_AUDIO = 'record-audio'
+    RECORD_VOICE = RECORD_AUDIO
+    RECORD_ROUND = 'record-round'
+    RECORD_VIDEO = 'record-video'
+    AUDIO = 'audio'
+    VOICE = AUDIO
+    SONG = AUDIO
+    ROUND = 'round'
+    VIDEO = 'video'
+    PHOTO = 'photo'
+    DOCUMENT = 'document'
+    FILE = DOCUMENT
+    CANCEL = 'cancel'
+
+
 def _mk_parser(cls):
     def parser(value):
         if isinstance(value, cls):
@@ -35,3 +56,4 @@ def _mk_parser(cls):
 
 parse_conn_mode = _mk_parser(ConnectionMode)
 parse_participant = _mk_parser(Participant)
+parse_typing_action = _mk_parser(Action)
diff --git a/telethon/enums.py b/telethon/enums.py
index 8de39a15..bad39ea0 100644
--- a/telethon/enums.py
+++ b/telethon/enums.py
@@ -1,4 +1,5 @@
 from ._misc.enums import (
     ConnectionMode,
     Participant,
+    Action,
 )