Implement disappearing photos. Fixes #481
This commit is contained in:
@@ -50,7 +50,7 @@ class PortalDedup:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def _always_force_hash(self) -> bool:
|
def _always_force_hash(self) -> bool:
|
||||||
return self._portal.peer_type != 'channel'
|
return self._portal.peer_type == 'chat'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _hash_event(event: TypeMessage) -> str:
|
def _hash_event(event: TypeMessage) -> str:
|
||||||
@@ -69,7 +69,7 @@ class PortalDedup:
|
|||||||
hash_content += {
|
hash_content += {
|
||||||
MessageMediaContact: lambda media: [media.user_id],
|
MessageMediaContact: lambda media: [media.user_id],
|
||||||
MessageMediaDocument: lambda media: [media.document.id],
|
MessageMediaDocument: lambda media: [media.document.id],
|
||||||
MessageMediaPhoto: lambda media: [media.photo.id],
|
MessageMediaPhoto: lambda media: [media.photo.id if media.photo else 0],
|
||||||
MessageMediaGeo: lambda media: [media.geo.long, media.geo.lat],
|
MessageMediaGeo: lambda media: [media.geo.long, media.geo.lat],
|
||||||
}[type(event.media)](event.media)
|
}[type(event.media)](event.media)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import mimetypes
|
|||||||
import codecs
|
import codecs
|
||||||
import unicodedata
|
import unicodedata
|
||||||
import base64
|
import base64
|
||||||
|
import asyncio
|
||||||
|
|
||||||
from sqlalchemy.exc import IntegrityError
|
from sqlalchemy.exc import IntegrityError
|
||||||
|
|
||||||
@@ -73,9 +74,22 @@ class PortalTelegram(BasePortal, ABC):
|
|||||||
return f"https://t.me/c/{self.tgid}/{evt.id}"
|
return f"https://t.me/c/{self.tgid}/{evt.id}"
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
async def _expire_telegram_photo(self, intent: IntentAPI, event_id: EventID, ttl: int) -> None:
|
||||||
|
try:
|
||||||
|
content = TextMessageEventContent(msgtype=MessageType.NOTICE, body="Photo has expired")
|
||||||
|
content.set_edit(event_id)
|
||||||
|
await asyncio.sleep(ttl)
|
||||||
|
await self._send_message(intent, content)
|
||||||
|
except Exception:
|
||||||
|
self.log.warning("Failed to expire Telegram photo %s", event_id, exc_info=True)
|
||||||
|
|
||||||
async def handle_telegram_photo(self, source: 'AbstractUser', intent: IntentAPI, evt: Message,
|
async def handle_telegram_photo(self, source: 'AbstractUser', intent: IntentAPI, evt: Message,
|
||||||
relates_to: RelatesTo = None) -> Optional[EventID]:
|
relates_to: RelatesTo = None) -> Optional[EventID]:
|
||||||
loc, largest_size = self._get_largest_photo_size(evt.media.photo)
|
media: MessageMediaPhoto = evt.media
|
||||||
|
if media.photo is None and media.ttl_seconds:
|
||||||
|
return await self._send_message(intent, TextMessageEventContent(
|
||||||
|
msgtype=MessageType.NOTICE, body="Photo has expired"))
|
||||||
|
loc, largest_size = self._get_largest_photo_size(media.photo)
|
||||||
if loc is None:
|
if loc is None:
|
||||||
content = TextMessageEventContent(msgtype=MessageType.TEXT,
|
content = TextMessageEventContent(msgtype=MessageType.TEXT,
|
||||||
body="Failed to bridge image",
|
body="Failed to bridge image",
|
||||||
@@ -98,7 +112,8 @@ class PortalTelegram(BasePortal, ABC):
|
|||||||
height=largest_size.h, width=largest_size.w, orientation=0, mimetype=file.mime_type,
|
height=largest_size.h, width=largest_size.w, orientation=0, mimetype=file.mime_type,
|
||||||
size=(len(largest_size.bytes) if (isinstance(largest_size, PhotoCachedSize))
|
size=(len(largest_size.bytes) if (isinstance(largest_size, PhotoCachedSize))
|
||||||
else largest_size.size))
|
else largest_size.size))
|
||||||
name = f"image{sane_mimetypes.guess_extension(file.mime_type)}"
|
ext = sane_mimetypes.guess_extension(file.mime_type)
|
||||||
|
name = f"disappearing_image{ext}" if media.ttl_seconds else f"image{ext}"
|
||||||
await intent.set_typing(self.mxid, is_typing=False)
|
await intent.set_typing(self.mxid, is_typing=False)
|
||||||
content = MediaMessageEventContent(msgtype=MessageType.IMAGE, info=info,
|
content = MediaMessageEventContent(msgtype=MessageType.IMAGE, info=info,
|
||||||
body=name, relates_to=relates_to,
|
body=name, relates_to=relates_to,
|
||||||
@@ -108,6 +123,9 @@ class PortalTelegram(BasePortal, ABC):
|
|||||||
else:
|
else:
|
||||||
content.url = file.mxc
|
content.url = file.mxc
|
||||||
result = await self._send_message(intent, content, timestamp=evt.date)
|
result = await self._send_message(intent, content, timestamp=evt.date)
|
||||||
|
if media.ttl_seconds:
|
||||||
|
self.loop.create_task(self._expire_telegram_photo(intent, result,
|
||||||
|
media.ttl_seconds))
|
||||||
if evt.message:
|
if evt.message:
|
||||||
caption_content = await formatter.telegram_to_matrix(evt, source, self.main_intent,
|
caption_content = await formatter.telegram_to_matrix(evt, source, self.main_intent,
|
||||||
no_reply_fallback=True)
|
no_reply_fallback=True)
|
||||||
@@ -535,9 +553,9 @@ class PortalTelegram(BasePortal, ABC):
|
|||||||
if self.backfill_lock.locked or (self.dedup.pre_db_check and self.peer_type == "channel"):
|
if self.backfill_lock.locked or (self.dedup.pre_db_check and self.peer_type == "channel"):
|
||||||
msg = DBMessage.get_one_by_tgid(TelegramID(evt.id), tg_space)
|
msg = DBMessage.get_one_by_tgid(TelegramID(evt.id), tg_space)
|
||||||
if msg:
|
if msg:
|
||||||
self.log.debug(f"Ignoring message {evt.id} (src {source.tgid}) as it was already"
|
self.log.debug(f"Ignoring message {evt.id} (src {source.tgid}) as it was already "
|
||||||
f"handled into {msg.mxid}. This duplicate was catched in the db "
|
f"handled into {msg.mxid}. This duplicate was catched in the db "
|
||||||
"check. If you get this message often, consider increasing"
|
"check. If you get this message often, consider increasing "
|
||||||
"bridge.deduplication.cache_queue_length in the config.")
|
"bridge.deduplication.cache_queue_length in the config.")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user