Sync mute status even if portal is created outside dialog sync

Closes #897
This commit is contained in:
Tulir Asokan
2023-03-10 13:35:25 +02:00
parent 6eda8bd165
commit 233468b37b
2 changed files with 70 additions and 15 deletions
+42 -2
View File
@@ -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
View File
@@ -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=}, "