Fix command handler return hints

This commit is contained in:
Tulir Asokan
2019-08-04 01:51:13 +03:00
parent d8653961af
commit 05f906427e
5 changed files with 39 additions and 36 deletions
@@ -13,7 +13,7 @@
# #
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
from typing import Dict, Optional from typing import Optional
from telethon.errors import (UsernameInvalidError, UsernameNotModifiedError, UsernameOccupiedError, from telethon.errors import (UsernameInvalidError, UsernameNotModifiedError, UsernameOccupiedError,
HashInvalidError, AuthKeyError, FirstNameInvalidError) HashInvalidError, AuthKeyError, FirstNameInvalidError)
@@ -30,7 +30,7 @@ from .. import command_handler, CommandEvent, SECTION_AUTH
help_section=SECTION_AUTH, help_section=SECTION_AUTH,
help_args="<_new username_>", help_args="<_new username_>",
help_text="Change your Telegram username.") help_text="Change your Telegram username.")
async def username(evt: CommandEvent) -> Optional[Dict]: async def username(evt: CommandEvent) -> EventID:
if len(evt.args) == 0: if len(evt.args) == 0:
return await evt.reply("**Usage:** `$cmdprefix+sp username <new username>`") return await evt.reply("**Usage:** `$cmdprefix+sp username <new username>`")
if evt.sender.is_bot: if evt.sender.is_bot:
@@ -56,7 +56,7 @@ async def username(evt: CommandEvent) -> Optional[Dict]:
@command_handler(needs_auth=True, help_section=SECTION_AUTH, help_args="<_new displayname_>", @command_handler(needs_auth=True, help_section=SECTION_AUTH, help_args="<_new displayname_>",
help_text="Change your Telegram displayname.") help_text="Change your Telegram displayname.")
async def displayname(evt: CommandEvent) -> Optional[Dict]: async def displayname(evt: CommandEvent) -> EventID:
if len(evt.args) == 0: if len(evt.args) == 0:
return await evt.reply("**Usage:** `$cmdprefix+sp displayname <new displayname>`") return await evt.reply("**Usage:** `$cmdprefix+sp displayname <new displayname>`")
if evt.sender.is_bot: if evt.sender.is_bot:
@@ -70,7 +70,7 @@ async def displayname(evt: CommandEvent) -> Optional[Dict]:
except FirstNameInvalidError: except FirstNameInvalidError:
return await evt.reply("Invalid first name") return await evt.reply("Invalid first name")
await evt.sender.update_info() await evt.sender.update_info()
await evt.reply("Displayname updated") return await evt.reply("Displayname updated")
def _format_session(sess: Authorization) -> str: def _format_session(sess: Authorization) -> str:
@@ -84,7 +84,7 @@ def _format_session(sess: Authorization) -> str:
help_section=SECTION_AUTH, help_section=SECTION_AUTH,
help_args="<`list`|`terminate`> [_hash_]", help_args="<`list`|`terminate`> [_hash_]",
help_text="View or delete other Telegram sessions.") help_text="View or delete other Telegram sessions.")
async def session(evt: CommandEvent) -> Optional[Dict]: async def session(evt: CommandEvent) -> EventID:
if len(evt.args) == 0: if len(evt.args) == 0:
return await evt.reply("**Usage:** `$cmdprefix+sp session <list|terminate> [hash]`") return await evt.reply("**Usage:** `$cmdprefix+sp session <list|terminate> [hash]`")
elif evt.sender.is_bot: elif evt.sender.is_bot:
+18 -16
View File
@@ -16,21 +16,23 @@
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
import asyncio import asyncio
from telethon.errors import ( from telethon.errors import ( # isort: skip
AccessTokenExpiredError, AccessTokenInvalidError, FirstNameInvalidError, FloodWaitError, AccessTokenExpiredError, AccessTokenInvalidError, FirstNameInvalidError, FloodWaitError,
PasswordHashInvalidError, PhoneCodeExpiredError, PhoneCodeInvalidError, PasswordHashInvalidError, PhoneCodeExpiredError, PhoneCodeInvalidError,
PhoneNumberAppSignupForbiddenError, PhoneNumberBannedError, PhoneNumberFloodError, PhoneNumberAppSignupForbiddenError, PhoneNumberBannedError, PhoneNumberFloodError,
PhoneNumberOccupiedError, PhoneNumberUnoccupiedError, SessionPasswordNeededError) PhoneNumberOccupiedError, PhoneNumberUnoccupiedError, SessionPasswordNeededError)
from ... import puppet as pu, user as u from mautrix.types import EventID
from ... import user as u
from ...commands import command_handler, CommandEvent, SECTION_AUTH from ...commands import command_handler, CommandEvent, SECTION_AUTH
from ...util import format_duration, ignore_coro from ...util import format_duration
@command_handler(needs_auth=False, @command_handler(needs_auth=False,
help_section=SECTION_AUTH, help_section=SECTION_AUTH,
help_text="Check if you're logged into Telegram.") help_text="Check if you're logged into Telegram.")
async def ping(evt: CommandEvent) -> Optional[Dict]: async def ping(evt: CommandEvent) -> EventID:
me = await evt.sender.client.get_me() if await evt.sender.is_logged_in() else None me = await evt.sender.client.get_me() if await evt.sender.is_logged_in() else None
if me: if me:
human_tg_id = f"@{me.username}" if me.username else f"+{me.phone}" human_tg_id = f"@{me.username}" if me.username else f"+{me.phone}"
@@ -42,7 +44,7 @@ async def ping(evt: CommandEvent) -> Optional[Dict]:
@command_handler(needs_auth=False, needs_puppeting=False, @command_handler(needs_auth=False, needs_puppeting=False,
help_section=SECTION_AUTH, help_section=SECTION_AUTH,
help_text="Get the info of the message relay Telegram bot.") help_text="Get the info of the message relay Telegram bot.")
async def ping_bot(evt: CommandEvent) -> Optional[Dict]: async def ping_bot(evt: CommandEvent) -> EventID:
if not evt.tgbot: if not evt.tgbot:
return await evt.reply("Telegram message relay bot not configured.") return await evt.reply("Telegram message relay bot not configured.")
info, mxid = await evt.tgbot.get_me(use_cache=False) info, mxid = await evt.tgbot.get_me(use_cache=False)
@@ -55,7 +57,7 @@ async def ping_bot(evt: CommandEvent) -> Optional[Dict]:
help_section=SECTION_AUTH, help_section=SECTION_AUTH,
help_args="<_phone_> <_full name_>", help_args="<_phone_> <_full name_>",
help_text="Register to Telegram") help_text="Register to Telegram")
async def register(evt: CommandEvent) -> Optional[Dict]: async def register(evt: CommandEvent) -> Optional[EventID]:
if await evt.sender.is_logged_in(): if await evt.sender.is_logged_in():
return await evt.reply("You are already logged in.") return await evt.reply("You are already logged in.")
elif len(evt.args) < 1: elif len(evt.args) < 1:
@@ -75,14 +77,14 @@ async def register(evt: CommandEvent) -> Optional[Dict]:
return None return None
async def enter_code_register(evt: CommandEvent) -> Dict: async def enter_code_register(evt: CommandEvent) -> EventID:
if len(evt.args) == 0: if len(evt.args) == 0:
return await evt.reply("**Usage:** `$cmdprefix+sp <code>`") return await evt.reply("**Usage:** `$cmdprefix+sp <code>`")
try: try:
await evt.sender.ensure_started(even_if_no_session=True) await evt.sender.ensure_started(even_if_no_session=True)
first_name, last_name = evt.sender.command_status["full_name"] first_name, last_name = evt.sender.command_status["full_name"]
user = await evt.sender.client.sign_up(evt.args[0], first_name, last_name) user = await evt.sender.client.sign_up(evt.args[0], first_name, last_name)
ignore_coro(asyncio.ensure_future(evt.sender.post_login(user), loop=evt.loop)) asyncio.ensure_future(evt.sender.post_login(user), loop=evt.loop)
evt.sender.command_status = None evt.sender.command_status = None
return await evt.reply(f"Successfully registered to Telegram.") return await evt.reply(f"Successfully registered to Telegram.")
except PhoneNumberOccupiedError: except PhoneNumberOccupiedError:
@@ -104,7 +106,7 @@ async def enter_code_register(evt: CommandEvent) -> Dict:
@command_handler(needs_auth=False, management_only=True, @command_handler(needs_auth=False, management_only=True,
help_section=SECTION_AUTH, help_section=SECTION_AUTH,
help_text="Get instructions on how to log in.") help_text="Get instructions on how to log in.")
async def login(evt: CommandEvent) -> Optional[Dict]: async def login(evt: CommandEvent) -> EventID:
override_sender = False override_sender = False
if len(evt.args) > 0 and evt.sender.is_admin: if len(evt.args) > 0 and evt.sender.is_admin:
evt.sender = await u.User.get_by_mxid(evt.args[0]).ensure_started() evt.sender = await u.User.get_by_mxid(evt.args[0]).ensure_started()
@@ -141,7 +143,7 @@ async def login(evt: CommandEvent) -> Optional[Dict]:
async def _request_code(evt: CommandEvent, phone_number: str, next_status: Dict[str, Any] async def _request_code(evt: CommandEvent, phone_number: str, next_status: Dict[str, Any]
) -> Dict: ) -> EventID:
ok = False ok = False
try: try:
await evt.sender.ensure_started(even_if_no_session=True) await evt.sender.ensure_started(even_if_no_session=True)
@@ -173,7 +175,7 @@ async def _request_code(evt: CommandEvent, phone_number: str, next_status: Dict[
@command_handler(needs_auth=False) @command_handler(needs_auth=False)
async def enter_phone_or_token(evt: CommandEvent) -> Optional[Dict]: async def enter_phone_or_token(evt: CommandEvent) -> Optional[EventID]:
if len(evt.args) == 0: if len(evt.args) == 0:
return await evt.reply("**Usage:** `$cmdprefix+sp enter-phone-or-token <phone-or-token>`") return await evt.reply("**Usage:** `$cmdprefix+sp enter-phone-or-token <phone-or-token>`")
elif not evt.config.get("bridge.allow_matrix_login", True): elif not evt.config.get("bridge.allow_matrix_login", True):
@@ -197,7 +199,7 @@ async def enter_phone_or_token(evt: CommandEvent) -> Optional[Dict]:
@command_handler(needs_auth=False) @command_handler(needs_auth=False)
async def enter_code(evt: CommandEvent) -> Optional[Dict]: async def enter_code(evt: CommandEvent) -> Optional[EventID]:
if len(evt.args) == 0: if len(evt.args) == 0:
return await evt.reply("**Usage:** `$cmdprefix+sp enter-code <code>`") return await evt.reply("**Usage:** `$cmdprefix+sp enter-code <code>`")
elif not evt.config.get("bridge.allow_matrix_login", True): elif not evt.config.get("bridge.allow_matrix_login", True):
@@ -213,7 +215,7 @@ async def enter_code(evt: CommandEvent) -> Optional[Dict]:
@command_handler(needs_auth=False) @command_handler(needs_auth=False)
async def enter_password(evt: CommandEvent) -> Optional[Dict]: async def enter_password(evt: CommandEvent) -> Optional[EventID]:
if len(evt.args) == 0: if len(evt.args) == 0:
return await evt.reply("**Usage:** `$cmdprefix+sp enter-password <password>`") return await evt.reply("**Usage:** `$cmdprefix+sp enter-password <password>`")
elif not evt.config.get("bridge.allow_matrix_login", True): elif not evt.config.get("bridge.allow_matrix_login", True):
@@ -232,7 +234,7 @@ async def enter_password(evt: CommandEvent) -> Optional[Dict]:
return None return None
async def _sign_in(evt: CommandEvent, **sign_in_info) -> Dict: async def _sign_in(evt: CommandEvent, **sign_in_info) -> EventID:
try: try:
await evt.sender.ensure_started(even_if_no_session=True) await evt.sender.ensure_started(even_if_no_session=True)
user = await evt.sender.client.sign_in(**sign_in_info) user = await evt.sender.client.sign_in(**sign_in_info)
@@ -242,7 +244,7 @@ async def _sign_in(evt: CommandEvent, **sign_in_info) -> Dict:
await evt.reply(f"[{existing_user.displayname}]" await evt.reply(f"[{existing_user.displayname}]"
f"(https://matrix.to/#/{existing_user.mxid})" f"(https://matrix.to/#/{existing_user.mxid})"
" was logged out from the account.") " was logged out from the account.")
ignore_coro(asyncio.ensure_future(evt.sender.post_login(user), loop=evt.loop)) asyncio.ensure_future(evt.sender.post_login(user), loop=evt.loop)
evt.sender.command_status = None evt.sender.command_status = None
name = f"@{user.username}" if user.username else f"+{user.phone}" name = f"@{user.username}" if user.username else f"+{user.phone}"
return await evt.reply(f"Successfully logged in as {name}") return await evt.reply(f"Successfully logged in as {name}")
@@ -264,7 +266,7 @@ async def _sign_in(evt: CommandEvent, **sign_in_info) -> Dict:
@command_handler(needs_auth=True, @command_handler(needs_auth=True,
help_section=SECTION_AUTH, help_section=SECTION_AUTH,
help_text="Log out from Telegram.") help_text="Log out from Telegram.")
async def logout(evt: CommandEvent) -> Optional[Dict]: async def logout(evt: CommandEvent) -> EventID:
if await evt.sender.log_out(): if await evt.sender.log_out():
return await evt.reply("Logged out successfully.") return await evt.reply("Logged out successfully.")
return await evt.reply("Failed to log out.") return await evt.reply("Failed to log out.")
+11 -9
View File
@@ -13,7 +13,7 @@
# #
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
from typing import Dict, List, Optional, Tuple from typing import List, Optional, Tuple
import codecs import codecs
import base64 import base64
import re import re
@@ -28,6 +28,8 @@ from telethon.tl.functions.messages import (ImportChatInviteRequest, CheckChatIn
GetBotCallbackAnswerRequest, SendVoteRequest) GetBotCallbackAnswerRequest, SendVoteRequest)
from telethon.tl.functions.channels import JoinChannelRequest from telethon.tl.functions.channels import JoinChannelRequest
from mautrix.types import EventID
from ... import puppet as pu, portal as po from ... import puppet as pu, portal as po
from ...abstract_user import AbstractUser from ...abstract_user import AbstractUser
from ...db import Message as DBMessage from ...db import Message as DBMessage
@@ -38,7 +40,7 @@ from ...commands import command_handler, CommandEvent, SECTION_MISC, SECTION_CRE
@command_handler(help_section=SECTION_MISC, @command_handler(help_section=SECTION_MISC,
help_args="[_-r|--remote_] <_query_>", help_args="[_-r|--remote_] <_query_>",
help_text="Search your contacts or the Telegram servers for users.") help_text="Search your contacts or the Telegram servers for users.")
async def search(evt: CommandEvent) -> Optional[Dict]: async def search(evt: CommandEvent) -> EventID:
if len(evt.args) == 0: if len(evt.args) == 0:
return await evt.reply("**Usage:** `$cmdprefix+sp search [-r|--remote] <query>`") return await evt.reply("**Usage:** `$cmdprefix+sp search [-r|--remote] <query>`")
@@ -79,7 +81,7 @@ async def search(evt: CommandEvent) -> Optional[Dict]:
"either the internal user ID, the username or the phone number. " "either the internal user ID, the username or the phone number. "
"**N.B.** The phone numbers you start chats with must already be in " "**N.B.** The phone numbers you start chats with must already be in "
"your contacts.") "your contacts.")
async def pm(evt: CommandEvent) -> Optional[Dict]: async def pm(evt: CommandEvent) -> EventID:
if len(evt.args) == 0: if len(evt.args) == 0:
return await evt.reply("**Usage:** `$cmdprefix+sp pm <user identifier>`") return await evt.reply("**Usage:** `$cmdprefix+sp pm <user identifier>`")
@@ -98,7 +100,7 @@ async def pm(evt: CommandEvent) -> Optional[Dict]:
f"{pu.Puppet.get_displayname(user, False)}") f"{pu.Puppet.get_displayname(user, False)}")
async def _join(evt: CommandEvent, arg: str) -> Tuple[Optional[TypeUpdates], Optional[Dict]]: async def _join(evt: CommandEvent, arg: str) -> Tuple[Optional[TypeUpdates], Optional[EventID]]:
if arg.startswith("joinchat/"): if arg.startswith("joinchat/"):
invite_hash = arg[len("joinchat/"):] invite_hash = arg[len("joinchat/"):]
try: try:
@@ -121,7 +123,7 @@ async def _join(evt: CommandEvent, arg: str) -> Tuple[Optional[TypeUpdates], Opt
@command_handler(help_section=SECTION_CREATING_PORTALS, @command_handler(help_section=SECTION_CREATING_PORTALS,
help_args="<_link_>", help_args="<_link_>",
help_text="Join a chat with an invite link.") help_text="Join a chat with an invite link.")
async def join(evt: CommandEvent) -> Optional[Dict]: async def join(evt: CommandEvent) -> Optional[EventID]:
if len(evt.args) == 0: if len(evt.args) == 0:
return await evt.reply("**Usage:** `$cmdprefix+sp join <invite link>`") return await evt.reply("**Usage:** `$cmdprefix+sp join <invite link>`")
@@ -149,7 +151,7 @@ async def join(evt: CommandEvent) -> Optional[Dict]:
@command_handler(help_section=SECTION_MISC, @command_handler(help_section=SECTION_MISC,
help_args="[`chats`|`contacts`|`me`]", help_args="[`chats`|`contacts`|`me`]",
help_text="Synchronize your chat portals, contacts and/or own info.") help_text="Synchronize your chat portals, contacts and/or own info.")
async def sync(evt: CommandEvent) -> Optional[Dict]: async def sync(evt: CommandEvent) -> EventID:
if len(evt.args) > 0: if len(evt.args) > 0:
sync_only = evt.args[0] sync_only = evt.args[0]
if sync_only not in ("chats", "contacts", "me"): if sync_only not in ("chats", "contacts", "me"):
@@ -211,7 +213,7 @@ async def _parse_encoded_msgid(user: AbstractUser, enc_id: str, type_name: str
@command_handler(help_section=SECTION_MISC, @command_handler(help_section=SECTION_MISC,
help_args="<_play ID_>", help_args="<_play ID_>",
help_text="Play a Telegram game.") help_text="Play a Telegram game.")
async def play(evt: CommandEvent) -> Optional[Dict]: async def play(evt: CommandEvent) -> EventID:
if len(evt.args) < 1: if len(evt.args) < 1:
return await evt.reply("**Usage:** `$cmdprefix+sp play <play ID>`") return await evt.reply("**Usage:** `$cmdprefix+sp play <play ID>`")
elif not await evt.sender.is_logged_in(): elif not await evt.sender.is_logged_in():
@@ -231,14 +233,14 @@ async def play(evt: CommandEvent) -> Optional[Dict]:
if not isinstance(game, BotCallbackAnswer): if not isinstance(game, BotCallbackAnswer):
return await evt.reply("Game request response invalid") return await evt.reply("Game request response invalid")
await evt.reply(f"Click [here]({game.url}) to play {msg.media.game.title}:\n\n" return await evt.reply(f"Click [here]({game.url}) to play {msg.media.game.title}:\n\n"
f"{msg.media.game.description}") f"{msg.media.game.description}")
@command_handler(help_section=SECTION_MISC, @command_handler(help_section=SECTION_MISC,
help_args="<_poll ID_> <_choice number_>", help_args="<_poll ID_> <_choice number_>",
help_text="Vote in a Telegram poll.") help_text="Vote in a Telegram poll.")
async def vote(evt: CommandEvent) -> Optional[Dict]: async def vote(evt: CommandEvent) -> EventID:
if len(evt.args) < 1: if len(evt.args) < 1:
return await evt.reply("**Usage:** `$cmdprefix+sp vote <poll ID> <choice number>`") return await evt.reply("**Usage:** `$cmdprefix+sp vote <poll ID> <choice number>`")
elif not await evt.sender.is_logged_in(): elif not await evt.sender.is_logged_in():
+3 -3
View File
@@ -17,9 +17,9 @@ from typing import List, Union, Optional
from telethon import TelegramClient, utils from telethon import TelegramClient, utils
from telethon.tl.functions.messages import SendMediaRequest from telethon.tl.functions.messages import SendMediaRequest
from telethon.tl.types import ( from telethon.tl.types import (InputMediaUploadedDocument, InputMediaUploadedPhoto,
InputMediaUploadedDocument, InputMediaUploadedPhoto, TypeDocumentAttribute, TypeInputMedia, TypeDocumentAttribute, TypeInputMedia, TypeInputPeer,
TypeInputPeer, TypeMessageEntity, TypeMessageMedia, TypePeer) TypeMessageEntity, TypeMessageMedia, TypePeer)
from telethon.tl.patched import Message from telethon.tl.patched import Message
from telethon.sessions.abstract import Session from telethon.sessions.abstract import Session
+2 -3
View File
@@ -19,9 +19,8 @@ import logging
import asyncio import asyncio
import re import re
from telethon.tl.types import ( from telethon.tl.types import (TypeUpdate, UpdateNewMessage, UpdateNewChannelMessage, PeerUser,
TypeUpdate, UpdateNewMessage, UpdateNewChannelMessage, PeerUser, UpdateShortChatMessage, UpdateShortMessage, User as TLUser)
UpdateShortChatMessage, UpdateShortMessage, User as TLUser)
from telethon.tl.types.contacts import ContactsNotModified from telethon.tl.types.contacts import ContactsNotModified
from telethon.tl.functions.contacts import GetContactsRequest, SearchRequest from telethon.tl.functions.contacts import GetContactsRequest, SearchRequest
from telethon.tl.functions.account import UpdateStatusRequest from telethon.tl.functions.account import UpdateStatusRequest