Replace star imports with literal values

This commit is contained in:
Kai A. Hiller
2018-07-26 16:42:17 +02:00
parent 08dd5b5b15
commit 01e153662e
8 changed files with 79 additions and 38 deletions
+6 -2
View File
@@ -14,11 +14,15 @@
# #
# 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 Awaitable, Callable, Pattern, Dict, TYPE_CHECKING from typing import Awaitable, Callable, Dict, Optional, Pattern, TYPE_CHECKING
import logging import logging
import re import re
from telethon.tl.types import * from telethon.tl.types import (
ChannelParticipantAdmin, ChannelParticipantCreator, ChatForbidden, ChatParticipantAdmin,
ChatParticipantCreator, InputChannel, InputUser, Message, MessageActionChatAddUser,
MessageActionChatDeleteUser, MessageEntityBotCommand, MessageService, PeerChannel, PeerChat,
TypePeer, UpdateNewChannelMessage, UpdateNewMessage)
from telethon.tl.functions.messages import GetChatsRequest, GetFullChatRequest from telethon.tl.functions.messages import GetChatsRequest, GetFullChatRequest
from telethon.tl.functions.channels import GetChannelsRequest, GetParticipantRequest from telethon.tl.functions.channels import GetChannelsRequest, GetParticipantRequest
from telethon.errors import ChannelInvalidError, ChannelPrivateError from telethon.errors import ChannelInvalidError, ChannelPrivateError
+5 -1
View File
@@ -17,7 +17,11 @@
from typing import Dict from typing import Dict
import asyncio import asyncio
from telethon.errors import * from telethon.errors import (
AccessTokenExpiredError, AccessTokenInvalidError, FirstNameInvalidError, FloodWaitError,
PasswordHashInvalidError, PhoneCodeExpiredError, PhoneCodeInvalidError,
PhoneNumberAppSignupForbiddenError, PhoneNumberBannedError, PhoneNumberFloodError,
PhoneNumberOccupiedError, PhoneNumberUnoccupiedError, SessionPasswordNeededError)
from . import command_handler, CommandEvent, SECTION_AUTH from . import command_handler, CommandEvent, SECTION_AUTH
from .. import puppet as pu from .. import puppet as pu
+2 -1
View File
@@ -17,7 +17,8 @@
from typing import Optional, Callable from typing import Optional, Callable
import asyncio import asyncio
from telethon.errors import * from telethon.errors import (ChatAdminRequiredError, UsernameInvalidError,
UsernameNotModifiedError, UsernameOccupiedError)
from telethon.tl.types import ChatForbidden, ChannelForbidden from telethon.tl.types import ChatForbidden, ChannelForbidden
from mautrix_appservice import MatrixRequestError, IntentAPI from mautrix_appservice import MatrixRequestError, IntentAPI
+3 -1
View File
@@ -14,7 +14,9 @@
# #
# 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 telethon.errors import *
from telethon.errors import (
InviteHashInvalidError, InviteHashExpiredError, UserAlreadyParticipantError)
from telethon.tl.types import User as TLUser from telethon.tl.types import User as TLUser
from telethon.tl.functions.messages import ImportChatInviteRequest, CheckChatInviteRequest from telethon.tl.functions.messages import ImportChatInviteRequest, CheckChatInviteRequest
from telethon.tl.functions.channels import JoinChannelRequest from telethon.tl.functions.channels import JoinChannelRequest
+52 -29
View File
@@ -14,7 +14,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 Pattern, Dict, Tuple, Awaitable, TYPE_CHECKING from typing import Awaitable, Dict, List, Optional, Pattern, Tuple, Union, TYPE_CHECKING
from collections import deque from collections import deque
from datetime import datetime from datetime import datetime
from string import Template from string import Template
@@ -32,14 +32,37 @@ from sqlalchemy import orm
from sqlalchemy.exc import IntegrityError, InvalidRequestError from sqlalchemy.exc import IntegrityError, InvalidRequestError
from sqlalchemy.orm.exc import FlushError from sqlalchemy.orm.exc import FlushError
from telethon.tl.functions.messages import * from telethon.tl.functions.messages import (
from telethon.tl.functions.channels import * AddChatUserRequest, CreateChatRequest, DeleteChatUserRequest, EditChatAdminRequest,
EditChatPhotoRequest, EditChatTitleRequest, ExportChatInviteRequest, GetFullChatRequest,
MigrateChatRequest, SetTypingRequest)
from telethon.tl.functions.channels import (
CreateChannelRequest, EditAboutRequest, EditAdminRequest, EditBannedRequest, EditPhotoRequest,
EditTitleRequest, ExportInviteRequest, GetParticipantsRequest, InviteToChannelRequest,
JoinChannelRequest, LeaveChannelRequest, UpdatePinnedMessageRequest, UpdateUsernameRequest)
from telethon.tl.functions.messages import ReadHistoryRequest as ReadMessageHistoryRequest from telethon.tl.functions.messages import ReadHistoryRequest as ReadMessageHistoryRequest
from telethon.tl.functions.channels import ReadHistoryRequest as ReadChannelHistoryRequest from telethon.tl.functions.channels import ReadHistoryRequest as ReadChannelHistoryRequest
from telethon.errors import ChatAdminRequiredError, ChatNotModifiedError from telethon.errors import ChatAdminRequiredError, ChatNotModifiedError
from telethon.tl.types import * from telethon.tl.types import (
Channel, ChannelAdminRights, ChannelBannedRights, ChannelFull, ChannelParticipantAdmin,
ChannelParticipantCreator, ChannelParticipantsRecent, ChannelParticipantsSearch, Chat,
ChatFull, ChatInviteEmpty, ChatParticipantAdmin, ChatParticipantCreator, ChatPhoto,
DocumentAttributeFilename, DocumentAttributeImageSize, DocumentAttributeSticker,
DocumentAttributeVideo, FileLocation, GeoPoint, InputChannel, InputChatUploadedPhoto,
InputPeerChannel, InputPeerChat, InputPeerUser, InputUser, InputUserSelf, Message,
MessageActionChannelCreate, MessageActionChatAddUser, MessageActionChatCreate,
MessageActionChatDeletePhoto, MessageActionChatDeleteUser, MessageActionChatEditPhoto,
MessageActionChatEditTitle, MessageActionChatJoinedByLink, MessageActionChatMigrateTo,
MessageActionPinMessage, MessageMediaContact, MessageMediaDocument, MessageMediaGeo,
MessageMediaPhoto, MessageService, PeerChannel, PeerChat, PeerUser, Photo, PhotoCachedSize,
SendMessageCancelAction, SendMessageTypingAction, TypeChannelParticipant, TypeChat,
TypeChatParticipant, TypeDocumentAttribute, TypeInputPeer, TypeMessageAction,
TypeMessageEntity, TypePeer, TypePhotoSize, TypeUpdates, TypeUser, TypeUserFull,
UpdateChatUserTyping, UpdateNewChannelMessage, UpdateNewMessage, UpdateUserTyping, User,
UserFull)
from mautrix_appservice import MatrixRequestError, IntentError, AppService, IntentAPI from mautrix_appservice import MatrixRequestError, IntentError, AppService, IntentAPI
from .context import Context from .context import Context
from .db import Portal as DBPortal, Message as DBMessage, TelegramFile as DBTelegramFile from .db import Portal as DBPortal, Message as DBMessage, TelegramFile as DBTelegramFile
from . import puppet as p, user as u, formatter, util from . import puppet as p, user as u, formatter, util
@@ -232,7 +255,7 @@ class Portal:
del self._dedup_mxid[self._dedup.popleft()] del self._dedup_mxid[self._dedup.popleft()]
return None return None
def get_input_entity(self, user: u.User) -> Awaitable[TypeInputPeer]: def get_input_entity(self, user: 'u.User') -> Awaitable[TypeInputPeer]:
return user.client.get_input_entity(self.peer) return user.client.get_input_entity(self.peer)
# endregion # endregion
@@ -587,7 +610,7 @@ class Portal:
elif self.peer_type == "user": elif self.peer_type == "user":
return [entity], [] return [entity], []
async def get_invite_link(self, user: u.User) -> str: async def get_invite_link(self, user: 'u.User') -> str:
if self.peer_type == "user": if self.peer_type == "user":
raise ValueError("You can't invite users to private chats.") raise ValueError("You can't invite users to private chats.")
elif self.peer_type == "chat": elif self.peer_type == "chat":
@@ -605,7 +628,7 @@ class Portal:
return link.link return link.link
async def get_authenticated_matrix_users(self) -> List[u.User]: async def get_authenticated_matrix_users(self) -> List['u.User']:
try: try:
members = await self.main_intent.get_room_members(self.mxid) members = await self.main_intent.get_room_members(self.mxid)
except MatrixRequestError: except MatrixRequestError:
@@ -664,7 +687,7 @@ class Portal:
else: else:
return "" return ""
async def _get_state_change_message(self, event: str, user: u.User, async def _get_state_change_message(self, event: str, user: 'u.User',
arguments: Optional[dict] = None) -> Optional[dict]: arguments: Optional[dict] = None) -> Optional[dict]:
tpl = config[f"bridge.state_event_formats.{event}"] tpl = config[f"bridge.state_event_formats.{event}"]
if len(tpl) == 0: if len(tpl) == 0:
@@ -682,7 +705,7 @@ class Portal:
"formatted_body": message, "formatted_body": message,
} }
async def name_change_matrix(self, user: u.User, displayname: str, prev_displayname: str, async def name_change_matrix(self, user: 'u.User', displayname: str, prev_displayname: str,
event_id: str) -> None: event_id: str) -> None:
async with self.require_send_lock(self.bot.tgid): async with self.require_send_lock(self.bot.tgid):
message = await self._get_state_change_message( message = await self._get_state_change_message(
@@ -696,16 +719,16 @@ class Portal:
space = self.tgid if self.peer_type == "channel" else self.bot.tgid space = self.tgid if self.peer_type == "channel" else self.bot.tgid
self.is_duplicate(response, (event_id, space)) self.is_duplicate(response, (event_id, space))
async def get_displayname(self, user: u.User) -> str: async def get_displayname(self, user: 'u.User') -> str:
return (await self.main_intent.get_displayname(self.mxid, user.mxid) return (await self.main_intent.get_displayname(self.mxid, user.mxid)
or user.mxid_localpart) or user.mxid_localpart)
def set_typing(self, user: u.User, typing: bool = True, def set_typing(self, user: 'u.User', typing: bool = True,
action=SendMessageTypingAction) -> None: action=SendMessageTypingAction) -> None:
return user.client(SetTypingRequest( return user.client(SetTypingRequest(
self.peer, action() if typing else SendMessageCancelAction())) self.peer, action() if typing else SendMessageCancelAction()))
async def mark_read(self, user: u.User, event_id: str) -> None: async def mark_read(self, user: 'u.User', event_id: str) -> None:
if user.is_bot: if user.is_bot:
return return
space = self.tgid if self.peer_type == "channel" else user.tgid space = self.tgid if self.peer_type == "channel" else user.tgid
@@ -720,7 +743,7 @@ class Portal:
else: else:
await user.client(ReadMessageHistoryRequest(peer=self.peer, max_id=message.tgid)) await user.client(ReadMessageHistoryRequest(peer=self.peer, max_id=message.tgid))
async def leave_matrix(self, user: u.User, source: u.User, event_id: str) -> None: async def leave_matrix(self, user: 'u.User', source: 'u.User', event_id: str) -> None:
if await user.needs_relaybot(self): if await user.needs_relaybot(self):
async with self.require_send_lock(self.bot.tgid): async with self.require_send_lock(self.bot.tgid):
message = await self._get_state_change_message("leave", user) message = await self._get_state_change_message("leave", user)
@@ -756,7 +779,7 @@ class Portal:
channel = await self.get_input_entity(user) channel = await self.get_input_entity(user)
await user.client(LeaveChannelRequest(channel=channel)) await user.client(LeaveChannelRequest(channel=channel))
async def join_matrix(self, user: u.User, event_id: str) -> None: async def join_matrix(self, user: 'u.User', event_id: str) -> None:
if await user.needs_relaybot(self): if await user.needs_relaybot(self):
async with self.require_send_lock(self.bot.tgid): async with self.require_send_lock(self.bot.tgid):
message = await self._get_state_change_message("join", user) message = await self._get_state_change_message("join", user)
@@ -775,7 +798,7 @@ class Portal:
# We'll just assume the user is already in the chat. # We'll just assume the user is already in the chat.
pass pass
async def _apply_msg_format(self, sender: u.User, msgtype: str, message: dict) -> None: async def _apply_msg_format(self, sender: 'u.User', msgtype: str, message: dict) -> None:
if "formatted_body" not in message: if "formatted_body" not in message:
message["format"] = "org.matrix.custom.html" message["format"] = "org.matrix.custom.html"
message["formatted_body"] = escape_html(message.get("body", "")) message["formatted_body"] = escape_html(message.get("body", ""))
@@ -790,7 +813,7 @@ class Portal:
message=body) message=body)
message["formatted_body"] = Template(tpl).safe_substitute(tpl_args) message["formatted_body"] = Template(tpl).safe_substitute(tpl_args)
async def _pre_process_matrix_message(self, sender: u.User, use_relaybot: bool, async def _pre_process_matrix_message(self, sender: 'u.User', use_relaybot: bool,
message: dict) -> None: message: dict) -> None:
msgtype = message.get("msgtype", "m.text") msgtype = message.get("msgtype", "m.text")
if msgtype == "m.emote": if msgtype == "m.emote":
@@ -898,7 +921,7 @@ class Portal:
mxid=event_id)) mxid=event_id))
self.db.commit() self.db.commit()
async def handle_matrix_message(self, sender: u.User, message: dict, event_id: str) -> None: async def handle_matrix_message(self, sender: 'u.User', message: dict, event_id: str) -> None:
puppet = p.Puppet.get_by_custom_mxid(sender.mxid) puppet = p.Puppet.get_by_custom_mxid(sender.mxid)
if puppet and message.get("net.maunium.telegram.puppet", False): if puppet and message.get("net.maunium.telegram.puppet", False):
self.log.debug("Ignoring puppet-sent message by confirmed puppet user %s", sender.mxid) self.log.debug("Ignoring puppet-sent message by confirmed puppet user %s", sender.mxid)
@@ -926,7 +949,7 @@ class Portal:
else: else:
self.log.debug(f"Unhandled Matrix event: {message}") self.log.debug(f"Unhandled Matrix event: {message}")
async def handle_matrix_pin(self, sender: u.User, pinned_message: Optional[str]) -> None: async def handle_matrix_pin(self, sender: 'u.User', pinned_message: Optional[str]) -> None:
if self.peer_type != "channel": if self.peer_type != "channel":
return return
try: try:
@@ -940,7 +963,7 @@ class Portal:
except ChatNotModifiedError: except ChatNotModifiedError:
pass pass
async def handle_matrix_deletion(self, deleter: u.User, event_id: str) -> None: async def handle_matrix_deletion(self, deleter: 'u.User', event_id: str) -> None:
deleter = deleter if not await deleter.needs_relaybot(self) else self.bot deleter = deleter if not await deleter.needs_relaybot(self) else self.bot
space = self.tgid if self.peer_type == "channel" else deleter.tgid space = self.tgid if self.peer_type == "channel" else deleter.tgid
message = DBMessage.query.filter(DBMessage.mxid == event_id, message = DBMessage.query.filter(DBMessage.mxid == event_id,
@@ -950,7 +973,7 @@ class Portal:
return return
await deleter.client.delete_messages(self.peer, [message.tgid]) await deleter.client.delete_messages(self.peer, [message.tgid])
async def _update_telegram_power_level(self, sender: u.User, user_id: int, level: int) -> None: async def _update_telegram_power_level(self, sender: 'u.User', user_id: int, level: int) -> None:
if self.peer_type == "chat": if self.peer_type == "chat":
await sender.client(EditChatAdminRequest( await sender.client(EditChatAdminRequest(
chat_id=self.tgid, user_id=user_id, is_admin=level >= 50)) chat_id=self.tgid, user_id=user_id, is_admin=level >= 50))
@@ -966,7 +989,7 @@ class Portal:
EditAdminRequest(channel=await self.get_input_entity(sender), EditAdminRequest(channel=await self.get_input_entity(sender),
user_id=user_id, admin_rights=rights)) user_id=user_id, admin_rights=rights))
async def handle_matrix_power_levels(self, sender: u.User, new_users: Dict[str, int], async def handle_matrix_power_levels(self, sender: 'u.User', new_users: Dict[str, int],
old_users: Dict[str, int]) -> None: old_users: Dict[str, int]) -> None:
# TODO handle all power level changes and bridge exact admin rights to supergroups/channels # TODO handle all power level changes and bridge exact admin rights to supergroups/channels
for user, level in new_users.items(): for user, level in new_users.items():
@@ -983,7 +1006,7 @@ class Portal:
if user not in old_users or level != old_users[user]: if user not in old_users or level != old_users[user]:
await self._update_telegram_power_level(sender, user_id, level) await self._update_telegram_power_level(sender, user_id, level)
async def handle_matrix_about(self, sender: u.User, about: str) -> None: async def handle_matrix_about(self, sender: 'u.User', about: str) -> None:
if self.peer_type not in {"channel"}: if self.peer_type not in {"channel"}:
return return
channel = await self.get_input_entity(sender) channel = await self.get_input_entity(sender)
@@ -991,7 +1014,7 @@ class Portal:
self.about = about self.about = about
self.save() self.save()
async def handle_matrix_title(self, sender: u.User, title: str) -> None: async def handle_matrix_title(self, sender: 'u.User', title: str) -> None:
if self.peer_type not in {"chat", "channel"}: if self.peer_type not in {"chat", "channel"}:
return return
@@ -1004,7 +1027,7 @@ class Portal:
self.title = title self.title = title
self.save() self.save()
async def handle_matrix_avatar(self, sender: u.User, url: str) -> None: async def handle_matrix_avatar(self, sender: 'u.User', url: str) -> None:
if self.peer_type not in {"chat", "channel"}: if self.peer_type not in {"chat", "channel"}:
# Invalid peer type # Invalid peer type
return return
@@ -1055,7 +1078,7 @@ class Portal:
user_tgids.add(puppet_id) user_tgids.add(puppet_id)
return list(user_tgids) return list(user_tgids)
async def upgrade_telegram_chat(self, source: u.User) -> None: async def upgrade_telegram_chat(self, source: 'u.User') -> None:
if self.peer_type != "chat": if self.peer_type != "chat":
raise ValueError("Only normal group chats are upgradable to supergroups.") raise ValueError("Only normal group chats are upgradable to supergroups.")
@@ -1071,7 +1094,7 @@ class Portal:
self.migrate_and_save(entity.id) self.migrate_and_save(entity.id)
await self.update_info(source, entity) await self.update_info(source, entity)
async def set_telegram_username(self, source: u.User, username: str) -> None: async def set_telegram_username(self, source: 'u.User', username: str) -> None:
if self.peer_type != "channel": if self.peer_type != "channel":
raise ValueError("Only channels and supergroups have usernames.") raise ValueError("Only channels and supergroups have usernames.")
await source.client( await source.client(
@@ -1079,7 +1102,7 @@ class Portal:
if await self.update_username(username): if await self.update_username(username):
self.save() self.save()
async def create_telegram_chat(self, source: u.User, supergroup: bool = False) -> None: async def create_telegram_chat(self, source: 'u.User', supergroup: bool = False) -> None:
if not self.mxid: if not self.mxid:
raise ValueError("Can't create Telegram chat for portal without Matrix room.") raise ValueError("Can't create Telegram chat for portal without Matrix room.")
elif self.tgid: elif self.tgid:
@@ -1120,7 +1143,7 @@ class Portal:
await self.main_intent.set_power_levels(self.mxid, levels) await self.main_intent.set_power_levels(self.mxid, levels)
await self.handle_matrix_power_levels(source, levels["users"], {}) await self.handle_matrix_power_levels(source, levels["users"], {})
async def invite_telegram(self, source: u.User, async def invite_telegram(self, source: 'u.User',
puppet: Union[p.Puppet, "AbstractUser"]) -> None: puppet: Union[p.Puppet, "AbstractUser"]) -> None:
if self.peer_type == "chat": if self.peer_type == "chat":
await source.client( await source.client(
@@ -1544,7 +1567,7 @@ class Portal:
return 0 return 0
@staticmethod @staticmethod
def _participant_to_power_levels(levels: dict, user: Union[u.User, p.Puppet], new_level: int, def _participant_to_power_levels(levels: dict, user: Union['u.User', p.Puppet], new_level: int,
bot_level: int) -> bool: bot_level: int) -> bool:
new_level = min(new_level, bot_level) new_level = min(new_level, bot_level)
default_level = levels["users_default"] if "users_default" in levels else 0 default_level = levels["users_default"] if "users_default" in levels else 0
+5 -1
View File
@@ -14,9 +14,13 @@
# #
# 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 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, TypeDocumentAttribute, TypeInputMedia,
TypeInputPeer, TypeMessageEntity, TypeMessageMedia, TypePeer)
from telethon.tl import custom from telethon.tl import custom
+4 -2
View File
@@ -14,12 +14,14 @@
# #
# 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, Awaitable, Optional, Match, Tuple, TYPE_CHECKING from typing import Awaitable, Dict, List, Match, Optional, Tuple, TYPE_CHECKING
import logging import logging
import asyncio import asyncio
import re import re
from telethon.tl.types import * from telethon.tl.types import (
TypeUpdate, UpdateNewMessage, UpdateNewChannelMessage, PeerUser,
UpdateShortChatMessage, UpdateShortMessage)
from telethon.tl.types import User as TLUser from telethon.tl.types import 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
+2 -1
View File
@@ -27,7 +27,8 @@ from sqlalchemy.orm.exc import FlushError
from telethon.tl.types import (Document, FileLocation, InputFileLocation, from telethon.tl.types import (Document, FileLocation, InputFileLocation,
InputDocumentFileLocation, PhotoSize, PhotoCachedSize) InputDocumentFileLocation, PhotoSize, PhotoCachedSize)
from telethon.errors import * from telethon.errors import (AuthBytesInvalidError, AuthKeyInvalidError, LocationInvalidError,
SecurityError)
from mautrix_appservice import IntentAPI from mautrix_appservice import IntentAPI
from ..tgclient import MautrixTelegramClient from ..tgclient import MautrixTelegramClient