Compare commits
6 Commits
v0.5.0-rc1
...
v0.5.0-rc2
| Author | SHA1 | Date | |
|---|---|---|---|
| 1b719027e6 | |||
| d661f7b798 | |||
| e437869c13 | |||
| c979de9387 | |||
| be806949bf | |||
| 1c08725ade |
@@ -1,2 +1,2 @@
|
||||
__version__ = "0.5.0rc1"
|
||||
__version__ = "0.5.0rc2"
|
||||
__author__ = "Tulir Asokan <tulir@maunium.net>"
|
||||
|
||||
@@ -23,7 +23,7 @@ from telethon.tl.types import (
|
||||
ChannelParticipantAdmin, ChannelParticipantCreator, ChatForbidden, ChatParticipantAdmin,
|
||||
ChatParticipantCreator, InputChannel, InputUser, MessageActionChatAddUser,
|
||||
MessageActionChatDeleteUser, MessageEntityBotCommand, PeerChannel, PeerChat, TypePeer,
|
||||
UpdateNewChannelMessage, UpdateNewMessage)
|
||||
UpdateNewChannelMessage, UpdateNewMessage, MessageActionChatMigrateTo)
|
||||
from telethon.tl.functions.messages import GetChatsRequest, GetFullChatRequest
|
||||
from telethon.tl.functions.channels import GetChannelsRequest, GetParticipantRequest
|
||||
from telethon.errors import ChannelInvalidError, ChannelPrivateError
|
||||
@@ -238,7 +238,7 @@ class Bot(AbstractUser):
|
||||
await self.handle_command_invite(portal, reply, mxid_input=mxid)
|
||||
|
||||
def handle_service_message(self, message: MessageService) -> None:
|
||||
to_id = message.to_id
|
||||
to_id = message.to_id # type: TelegramID
|
||||
if isinstance(to_id, PeerChannel):
|
||||
to_id = to_id.channel_id
|
||||
chat_type = "channel"
|
||||
@@ -250,9 +250,12 @@ class Bot(AbstractUser):
|
||||
|
||||
action = message.action
|
||||
if isinstance(action, MessageActionChatAddUser) and self.tgid in action.users:
|
||||
self.add_chat(TelegramID(to_id), chat_type)
|
||||
self.add_chat(to_id, chat_type)
|
||||
elif isinstance(action, MessageActionChatDeleteUser) and action.user_id == self.tgid:
|
||||
self.remove_chat(TelegramID(to_id))
|
||||
self.remove_chat(to_id)
|
||||
elif isinstance(action, MessageActionChatMigrateTo):
|
||||
self.remove_chat(to_id)
|
||||
self.add_chat(TelegramID(action.channel_id), "channel")
|
||||
|
||||
async def update(self, update) -> bool:
|
||||
if not isinstance(update, (UpdateNewMessage, UpdateNewChannelMessage)):
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
# -*- coding: future_fstrings -*-
|
||||
# mautrix-telegram - A Matrix-Telegram puppeting bridge
|
||||
# Copyright (C) 2018 Tulir Asokan
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
#
|
||||
# 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/>.
|
||||
from typing import Dict, Tuple
|
||||
|
||||
from mautrix_appservice import MatrixRequestError, IntentAPI
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
# -*- coding: future_fstrings -*-
|
||||
# mautrix-telegram - A Matrix-Telegram puppeting bridge
|
||||
# Copyright (C) 2018 Tulir Asokan
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
#
|
||||
# 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/>.
|
||||
from abc import abstractmethod
|
||||
|
||||
from sqlalchemy import Table
|
||||
|
||||
+43
-27
@@ -418,24 +418,36 @@ class Portal:
|
||||
|
||||
def _get_base_power_levels(self, levels: dict = None, entity: TypeChat = None) -> dict:
|
||||
levels = levels or {}
|
||||
levels["ban"] = 99
|
||||
levels["kick"] = 50
|
||||
levels["invite"] = 50 if entity.default_banned_rights.invite_users else 0
|
||||
if "events" not in levels:
|
||||
levels["events"] = {}
|
||||
levels["events"]["m.room.name"] = 50 if entity.default_banned_rights.change_info else 0
|
||||
levels["events"]["m.room.avatar"] = 50 if entity.default_banned_rights.change_info else 0
|
||||
levels["events"]["m.room.topic"] = 50 if entity.default_banned_rights.change_info else 0
|
||||
levels["events"][
|
||||
"m.room.pinned_events"] = 50 if entity.default_banned_rights.pin_messages else 0
|
||||
levels["events"]["m.sticker"] = 50 if entity.default_banned_rights.send_stickers else 0
|
||||
levels["events"]["m.room.power_levels"] = 75
|
||||
levels["events"]["m.room.history_visibility"] = 75
|
||||
levels["state_default"] = 50
|
||||
levels["users_default"] = 0
|
||||
levels["events_default"] = (50 if (self.peer_type == "channel" and not entity.megagroup
|
||||
or entity.default_banned_rights.send_messages)
|
||||
else 0)
|
||||
if self.peer_type == "user":
|
||||
levels["ban"] = 100
|
||||
levels["kick"] = 100
|
||||
levels["invite"] = 100
|
||||
levels.setdefault("events", {})
|
||||
levels["events"]["m.room.name"] = 0
|
||||
levels["events"]["m.room.avatar"] = 0
|
||||
levels["events"]["m.room.topic"] = 0
|
||||
levels["state_default"] = 0
|
||||
levels["users_default"] = 0
|
||||
levels["events_default"] = 0
|
||||
else:
|
||||
dbr = entity.default_banned_rights
|
||||
levels["ban"] = 99
|
||||
levels["kick"] = 50
|
||||
levels["invite"] = 50 if dbr.invite_users else 0
|
||||
levels.setdefault("events", {})
|
||||
levels["events"]["m.room.name"] = 50 if dbr.change_info else 0
|
||||
levels["events"]["m.room.avatar"] = 50 if dbr.change_info else 0
|
||||
levels["events"]["m.room.topic"] = 50 if dbr.change_info else 0
|
||||
levels["events"][
|
||||
"m.room.pinned_events"] = 50 if dbr.pin_messages else 0
|
||||
levels["events"]["m.sticker"] = 50 if dbr.send_stickers else 0
|
||||
levels["events"]["m.room.power_levels"] = 75
|
||||
levels["events"]["m.room.history_visibility"] = 75
|
||||
levels["state_default"] = 50
|
||||
levels["users_default"] = 0
|
||||
levels["events_default"] = (50 if (self.peer_type == "channel" and not entity.megagroup
|
||||
or entity.default_banned_rights.send_messages)
|
||||
else 0)
|
||||
if "users" not in levels:
|
||||
levels["users"] = {
|
||||
self.main_intent.mxid: 100
|
||||
@@ -598,8 +610,8 @@ class Portal:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _get_largest_photo_size(photo: Photo) -> TypePhotoSize:
|
||||
return max(photo.sizes, key=(lambda photo2: (
|
||||
def _get_largest_photo_size(photo: Union[Photo, List[TypePhotoSize]]) -> TypePhotoSize:
|
||||
return max(photo.sizes if isinstance(photo, Photo) else photo, key=(lambda photo2: (
|
||||
len(photo2.bytes) if not isinstance(photo2, PhotoSize) else photo2.size)))
|
||||
|
||||
async def remove_avatar(self, _: 'AbstractUser', save: bool = False) -> None:
|
||||
@@ -1352,8 +1364,8 @@ class Portal:
|
||||
return attrs
|
||||
|
||||
@staticmethod
|
||||
def _parse_telegram_document_meta(evt: Message, file: DBTelegramFile, attrs: Dict
|
||||
) -> Tuple[Dict, str]:
|
||||
def _parse_telegram_document_meta(evt: Message, file: DBTelegramFile, attrs: Dict,
|
||||
thumb: TypePhotoSize) -> Tuple[Dict, str]:
|
||||
document = evt.media.document
|
||||
name = evt.message or attrs["name"]
|
||||
if attrs["is_sticker"]:
|
||||
@@ -1381,8 +1393,8 @@ class Portal:
|
||||
info["thumbnail_url"] = file.thumbnail.mxc
|
||||
info["thumbnail_info"] = {
|
||||
"mimetype": file.thumbnail.mime_type,
|
||||
"h": file.thumbnail.height or document.thumb.h,
|
||||
"w": file.thumbnail.width or document.thumb.w,
|
||||
"h": file.thumbnail.height or thumb.h,
|
||||
"w": file.thumbnail.width or thumb.w,
|
||||
"size": file.thumbnail.size,
|
||||
}
|
||||
|
||||
@@ -1393,12 +1405,16 @@ class Portal:
|
||||
document = evt.media.document
|
||||
attrs = self._parse_telegram_document_attributes(document.attributes)
|
||||
|
||||
file = await util.transfer_file_to_matrix(source.client, intent, document,
|
||||
document.thumb, is_sticker=attrs["is_sticker"])
|
||||
thumb = self._get_largest_photo_size(document.thumbs)
|
||||
if not isinstance(thumb, (PhotoSize, PhotoCachedSize)):
|
||||
self.log.debug(f"Unsupported thumbnail type {type(thumb)}")
|
||||
thumb = None
|
||||
file = await util.transfer_file_to_matrix(source.client, intent, document, thumb,
|
||||
is_sticker=attrs["is_sticker"])
|
||||
if not file:
|
||||
return None
|
||||
|
||||
info, name = self._parse_telegram_document_meta(evt, file, attrs)
|
||||
info, name = self._parse_telegram_document_meta(evt, file, attrs, thumb)
|
||||
|
||||
await intent.set_typing(self.mxid, is_typing=False)
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@ import asyncio
|
||||
import magic
|
||||
from sqlalchemy.exc import IntegrityError, InvalidRequestError
|
||||
|
||||
from telethon.tl.types import (Document, FileLocation, InputFileLocation,
|
||||
InputDocumentFileLocation, PhotoSize, PhotoCachedSize)
|
||||
from telethon.tl.types import (Document, FileLocation, InputFileLocation, InputDocumentFileLocation,
|
||||
TypePhotoSize, PhotoSize, PhotoCachedSize)
|
||||
from telethon.errors import (AuthBytesInvalidError, AuthKeyInvalidError, LocationInvalidError,
|
||||
SecurityError)
|
||||
from mautrix_appservice import IntentAPI
|
||||
@@ -149,7 +149,7 @@ transfer_locks = {} # type: Dict[str, asyncio.Lock]
|
||||
|
||||
|
||||
async def transfer_file_to_matrix(client: MautrixTelegramClient, intent: IntentAPI,
|
||||
location: TypeLocation, thumbnail: Optional[TypeLocation] = None,
|
||||
location: TypeLocation, thumbnail: Optional[Union[TypeLocation, TypePhotoSize]] = None,
|
||||
is_sticker: bool = False) -> Optional[DBTelegramFile]:
|
||||
location_id = _location_to_id(location)
|
||||
if not location_id:
|
||||
@@ -171,7 +171,7 @@ async def transfer_file_to_matrix(client: MautrixTelegramClient, intent: IntentA
|
||||
|
||||
async def _unlocked_transfer_file_to_matrix(client: MautrixTelegramClient, intent: IntentAPI,
|
||||
loc_id: str, location: TypeLocation,
|
||||
thumbnail: Optional[TypeLocation],
|
||||
thumbnail: Optional[Union[TypeLocation, TypePhotoSize]],
|
||||
is_sticker: bool) -> Optional[DBTelegramFile]:
|
||||
db_file = DBTelegramFile.get(loc_id)
|
||||
if db_file:
|
||||
|
||||
Reference in New Issue
Block a user