Sync mute status even if portal is created outside dialog sync
Closes #897
This commit is contained in:
@@ -23,6 +23,7 @@ from sqlite3 import IntegrityError
|
||||
from string import Template
|
||||
import asyncio
|
||||
import base64
|
||||
import itertools
|
||||
import random
|
||||
import time
|
||||
|
||||
@@ -36,6 +37,7 @@ from telethon.errors import (
|
||||
ReactionInvalidError,
|
||||
RPCError,
|
||||
)
|
||||
from telethon.tl.custom import Dialog
|
||||
from telethon.tl.functions.channels import (
|
||||
CreateChannelRequest,
|
||||
EditPhotoRequest,
|
||||
@@ -54,6 +56,7 @@ from telethon.tl.functions.messages import (
|
||||
ExportChatInviteRequest,
|
||||
GetMessageReactionsListRequest,
|
||||
GetMessagesReactionsRequest,
|
||||
GetPeerDialogsRequest,
|
||||
MigrateChatRequest,
|
||||
SendReactionRequest,
|
||||
SetTypingRequest,
|
||||
@@ -66,6 +69,7 @@ from telethon.tl.types import (
|
||||
ChannelFull,
|
||||
Chat,
|
||||
ChatBannedRights,
|
||||
ChatEmpty,
|
||||
ChatFull,
|
||||
ChatPhoto,
|
||||
ChatPhotoEmpty,
|
||||
@@ -76,6 +80,7 @@ from telethon.tl.types import (
|
||||
GeoPoint,
|
||||
InputChannel,
|
||||
InputChatUploadedPhoto,
|
||||
InputDialogPeer,
|
||||
InputMediaUploadedDocument,
|
||||
InputMediaUploadedPhoto,
|
||||
InputPeerChannel,
|
||||
@@ -136,11 +141,13 @@ from telethon.tl.types import (
|
||||
UpdatePhoneCall,
|
||||
UpdateUserTyping,
|
||||
User,
|
||||
UserEmpty,
|
||||
UserFull,
|
||||
UserProfilePhoto,
|
||||
UserProfilePhotoEmpty,
|
||||
)
|
||||
from telethon.utils import encode_waveform
|
||||
from telethon.tl.types.messages import PeerDialogs
|
||||
from telethon.utils import encode_waveform, get_peer_id
|
||||
import attr
|
||||
|
||||
from mautrix.appservice import DOUBLE_PUPPET_SOURCE_KEY, IntentAPI
|
||||
@@ -725,6 +732,7 @@ class Portal(DBPortal, BasePortal):
|
||||
entity: TypeChat | User = None,
|
||||
invites: InviteList = None,
|
||||
update_if_exists: bool = True,
|
||||
from_dialog_sync: bool = False,
|
||||
client: MautrixTelegramClient | None = None,
|
||||
) -> RoomID | None:
|
||||
if self.mxid:
|
||||
@@ -741,7 +749,9 @@ class Portal(DBPortal, BasePortal):
|
||||
return self.mxid
|
||||
async with self._room_create_lock:
|
||||
try:
|
||||
return await self._create_matrix_room(user, entity, invites, client=client)
|
||||
return await self._create_matrix_room(
|
||||
user, entity, invites, client=client, from_dialog_sync=from_dialog_sync
|
||||
)
|
||||
except Exception:
|
||||
self.log.exception("Fatal error creating Matrix room")
|
||||
|
||||
@@ -796,6 +806,7 @@ class Portal(DBPortal, BasePortal):
|
||||
user: au.AbstractUser,
|
||||
entity: TypeChat | User,
|
||||
invites: InviteList,
|
||||
from_dialog_sync: bool,
|
||||
client: MautrixTelegramClient | None = None,
|
||||
) -> RoomID | None:
|
||||
if self.mxid:
|
||||
@@ -807,6 +818,31 @@ class Portal(DBPortal, BasePortal):
|
||||
|
||||
invites = invites or []
|
||||
|
||||
dialog = None
|
||||
if not from_dialog_sync and not user.is_bot:
|
||||
self.log.debug("Fetching dialog info for new portal")
|
||||
dialogs: PeerDialogs = await user.client(
|
||||
GetPeerDialogsRequest(peers=[InputDialogPeer(await self.get_input_entity(user))])
|
||||
)
|
||||
if dialogs.chats and dialogs.chats[0].id == self.tgid:
|
||||
entity = dialogs.chats[0]
|
||||
self.log.debug("Got entity info from get dialogs request")
|
||||
elif self.is_direct and dialogs.users:
|
||||
for user in dialogs.users:
|
||||
if user.id == self.tgid:
|
||||
entity = user
|
||||
self.log.debug("Got user entity info from get dialogs request")
|
||||
break
|
||||
if dialogs.dialogs:
|
||||
entities = {
|
||||
get_peer_id(x): x
|
||||
for x in itertools.chain(dialogs.users, dialogs.chats)
|
||||
if not isinstance(x, (UserEmpty, ChatEmpty))
|
||||
}
|
||||
msg = dialogs.messages[0] if len(dialogs.messages) == 1 else None
|
||||
dialog = Dialog(user.client, dialogs.dialogs[0], entities, msg)
|
||||
self.log.debug("Got dialog info for new portal: %s", dialog)
|
||||
|
||||
if not entity:
|
||||
entity = await self.get_entity(user, client)
|
||||
self.log.trace("Fetched data: %s", entity)
|
||||
@@ -959,6 +995,10 @@ class Portal(DBPortal, BasePortal):
|
||||
self.log.debug(f"Matrix room created: {self.mxid}")
|
||||
await self.az.state_store.set_power_levels(self.mxid, power_levels)
|
||||
await user.register_portal(self)
|
||||
if dialog and isinstance(user, u.User):
|
||||
await user.post_sync_dialog(
|
||||
self, puppet=None, was_created=True, **user.dialog_to_sync_args(dialog)
|
||||
)
|
||||
|
||||
if not autojoin_invites or not self.is_direct:
|
||||
await self.invite_to_matrix(invites)
|
||||
|
||||
+28
-13
@@ -490,13 +490,16 @@ class User(DBUser, AbstractUser, BaseUser):
|
||||
self.log.info(f"Creating portal for {portal.tgid_log} as part of backfill loop")
|
||||
try:
|
||||
await portal.create_matrix_room(
|
||||
self, client=client, update_if_exists=False, invites=[self.mxid]
|
||||
self,
|
||||
client=client,
|
||||
update_if_exists=False,
|
||||
invites=[self.mxid],
|
||||
from_dialog_sync=True,
|
||||
)
|
||||
except Exception:
|
||||
self.log.exception(f"Error while creating {portal.tgid_log}")
|
||||
else:
|
||||
puppet = await pu.Puppet.get_by_custom_mxid(self.mxid)
|
||||
await self._post_sync_dialog(portal, puppet, was_created=True, **post_sync_args)
|
||||
await self.post_sync_dialog(portal, puppet=None, was_created=True, **post_sync_args)
|
||||
|
||||
async def update(self, update: TypeUpdate) -> bool:
|
||||
if not self.is_bot:
|
||||
@@ -746,12 +749,12 @@ class User(DBUser, AbstractUser, BaseUser):
|
||||
)
|
||||
await self._mute_room(puppet, portal, update.notify_settings.mute_until.timestamp())
|
||||
|
||||
async def _sync_dialog(
|
||||
self, portal: po.Portal, dialog: Dialog, should_create: bool, puppet: pu.Puppet | None
|
||||
) -> None:
|
||||
was_created = False
|
||||
post_sync_args = {
|
||||
"last_message_ts": cast(datetime, dialog.date).timestamp(),
|
||||
@staticmethod
|
||||
def dialog_to_sync_args(dialog: Dialog) -> dict:
|
||||
return {
|
||||
"last_message_ts": (
|
||||
cast(datetime, dialog.date).timestamp() if dialog.date else time.time()
|
||||
),
|
||||
"unread_count": dialog.unread_count,
|
||||
"max_read_id": dialog.dialog.read_inbox_max_id,
|
||||
"mute_until": (
|
||||
@@ -762,6 +765,12 @@ class User(DBUser, AbstractUser, BaseUser):
|
||||
"pinned": dialog.pinned,
|
||||
"archived": dialog.archived,
|
||||
}
|
||||
|
||||
async def _sync_dialog(
|
||||
self, portal: po.Portal, dialog: Dialog, should_create: bool, puppet: pu.Puppet | None
|
||||
) -> None:
|
||||
was_created = False
|
||||
post_sync_args = self.dialog_to_sync_args(dialog)
|
||||
if portal.mxid:
|
||||
self.log.debug(f"Backfilling and updating {portal.tgid_log} (dialog sync)")
|
||||
try:
|
||||
@@ -775,7 +784,9 @@ class User(DBUser, AbstractUser, BaseUser):
|
||||
elif should_create:
|
||||
self.log.debug(f"Creating portal for {portal.tgid_log} immediately (dialog sync)")
|
||||
try:
|
||||
await portal.create_matrix_room(self, dialog.entity, invites=[self.mxid])
|
||||
await portal.create_matrix_room(
|
||||
self, dialog.entity, invites=[self.mxid], from_dialog_sync=True
|
||||
)
|
||||
was_created = True
|
||||
except Exception:
|
||||
self.log.exception(f"Error while creating {portal.tgid_log}")
|
||||
@@ -788,7 +799,7 @@ class User(DBUser, AbstractUser, BaseUser):
|
||||
extra_data=post_sync_args,
|
||||
)
|
||||
if portal.mxid and puppet and puppet.is_real_user:
|
||||
await self._post_sync_dialog(
|
||||
await self.post_sync_dialog(
|
||||
portal=portal,
|
||||
puppet=puppet,
|
||||
was_created=was_created,
|
||||
@@ -796,10 +807,10 @@ class User(DBUser, AbstractUser, BaseUser):
|
||||
)
|
||||
self.log.debug(f"_sync_dialog finished for {portal.tgid_log}")
|
||||
|
||||
async def _post_sync_dialog(
|
||||
async def post_sync_dialog(
|
||||
self,
|
||||
portal: po.Portal,
|
||||
puppet: pu.Puppet,
|
||||
puppet: pu.Puppet | None,
|
||||
was_created: bool,
|
||||
max_read_id: int,
|
||||
last_message_ts: float,
|
||||
@@ -808,6 +819,10 @@ class User(DBUser, AbstractUser, BaseUser):
|
||||
pinned: bool,
|
||||
archived: bool,
|
||||
) -> None:
|
||||
if puppet is None:
|
||||
puppet = await pu.Puppet.get_by_custom_mxid(self.mxid)
|
||||
if not puppet or not puppet.is_real_user:
|
||||
return
|
||||
self.log.debug(
|
||||
f"Running dialog post-sync for {portal.tgid_log} with args "
|
||||
f"{was_created=}, {max_read_id=}, {last_message_ts=}, {unread_count=}, "
|
||||
|
||||
Reference in New Issue
Block a user