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