Add support for openMessageContent and updateMessageContentOpened (#43)

* Add support for openMessageContent and updateMessageContentOpened

Co-authored-by: Alexander Zveruk <sanyazveruk@gmail.com>
This commit is contained in:
Nameless 2020-05-21 13:27:50 +08:00 committed by GitHub
parent 38d7758822
commit 4641931ed9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 101 additions and 20 deletions

View file

@ -61,6 +61,7 @@ class Controller:
"updateMessageContent": self.update_msg_content,
"updateMessageSendSucceeded": self.update_msg_send_succeeded,
"updateNewMessage": self.update_new_msg,
"updateMessageContentOpened": self.update_message_content_opened,
}
self.chat_size = 0.5
signal(SIGWINCH, self.resize_handler)
@ -106,7 +107,6 @@ class Controller:
def open_current_msg(self):
msg = MsgProxy(self.model.current_msg())
log.info("Open msg: %s", msg.msg)
if msg.is_text:
text = msg["content"]["text"]["text"]
with NamedTemporaryFile("w", suffix=".txt") as f:
@ -118,8 +118,9 @@ class Controller:
path = msg.local_path
if path:
chat_id = self.model.chats.id_by_index(self.model.current_chat)
self.tg.open_message_content(chat_id, msg.msg_id)
with suspend(self.view) as s:
log.info("Opening file: %s", path)
s.open_file(path)
def write_long_msg(self):
@ -523,3 +524,10 @@ class Controller:
if proxy.is_downloaded:
self.model.downloads.pop(file_id)
break
@handle_exception
def update_message_content_opened(self, update: Dict[str, Any]):
chat_id = update["chat_id"]
message_id = update["message_id"]
self.model.msgs.update_msg_content_opened(chat_id, message_id)
self.refresh_msgs()

View file

@ -5,7 +5,7 @@ import threading
from curses import window, wrapper # type: ignore
from functools import partial
from telegram.client import Telegram
from telegram.client import AsyncResult, Telegram
from tg import config, utils
from tg.controllers import Controller
@ -48,7 +48,7 @@ class TelegramApi(Telegram):
)
result.wait()
def send_doc(self, file_path, chat_id):
def send_doc(self, file_path: str, chat_id: int) -> AsyncResult:
data = {
"@type": "sendMessage",
"chat_id": chat_id,
@ -59,7 +59,7 @@ class TelegramApi(Telegram):
}
return self._send_data(data)
def send_audio(self, file_path, chat_id):
def send_audio(self, file_path: str, chat_id: int) -> AsyncResult:
data = {
"@type": "sendMessage",
"chat_id": chat_id,
@ -70,7 +70,7 @@ class TelegramApi(Telegram):
}
return self._send_data(data)
def send_photo(self, file_path, chat_id):
def send_photo(self, file_path: str, chat_id: int) -> AsyncResult:
data = {
"@type": "sendMessage",
"chat_id": chat_id,
@ -81,7 +81,14 @@ class TelegramApi(Telegram):
}
return self._send_data(data)
def send_video(self, file_path, chat_id, width, height, duration):
def send_video(
self,
file_path: str,
chat_id: int,
width: int,
height: int,
duration: int,
) -> AsyncResult:
data = {
"@type": "sendMessage",
"chat_id": chat_id,
@ -95,7 +102,9 @@ class TelegramApi(Telegram):
}
return self._send_data(data)
def send_voice(self, file_path, chat_id, duration, waveform):
def send_voice(
self, file_path: str, chat_id: int, duration: int, waveform: int
):
data = {
"@type": "sendMessage",
"chat_id": chat_id,
@ -110,7 +119,7 @@ class TelegramApi(Telegram):
def toggle_chat_is_marked_as_unread(
self, chat_id: int, is_marked_as_unread: bool
):
) -> AsyncResult:
data = {
"@type": "toggleChatIsMarkedAsUnread",
"chat_id": chat_id,
@ -118,7 +127,9 @@ class TelegramApi(Telegram):
}
return self._send_data(data)
def toggle_chat_is_pinned(self, chat_id: int, is_pinned: bool):
def toggle_chat_is_pinned(
self, chat_id: int, is_pinned: bool
) -> AsyncResult:
data = {
"@type": "toggleChatIsPinned",
"chat_id": chat_id,
@ -138,7 +149,7 @@ class TelegramApi(Telegram):
def view_messages(
self, chat_id: int, message_ids: list, force_read: bool = True
):
) -> AsyncResult:
data = {
"@type": "viewMessages",
"chat_id": chat_id,
@ -147,6 +158,16 @@ class TelegramApi(Telegram):
}
return self._send_data(data)
def open_message_content(
self, chat_id: int, message_id: int
) -> AsyncResult:
data = {
"@type": "openMessageContent",
"chat_id": chat_id,
"message_id": message_id,
}
return self._send_data(data)
def main():
def signal_handler(sig, frame):

View file

@ -4,6 +4,8 @@ from typing import Any, Dict, List, Optional, Set, Tuple
from telegram.client import Telegram
from tg.msg import MsgProxy
log = logging.getLogger(__name__)
@ -250,6 +252,21 @@ class MsgModel:
continue
msg["content"] = message_content
return True
return False
def update_msg_content_opened(self, chat_id: int, msg_id: int):
for message in self.msgs[chat_id]:
if message["id"] != msg_id:
continue
msg = MsgProxy(message)
if msg.type == "voice":
msg.is_listened = True
elif msg.type == "recording":
msg.is_viewed = True
# TODO: start the TTL timer for self-destructing messages
# that is the last case to implement
# https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1update_message_content_opened.html
return
def add_message(self, chat_id: int, message: Dict[str, Any]) -> bool:
msg_id = message["id"]

View file

@ -1,6 +1,6 @@
import logging
from datetime import datetime
from typing import Any, Dict
from typing import Any, Dict, Optional
from tg import utils
@ -58,8 +58,8 @@ class MsgProxy:
self.msg[key] = value
@property
def type(self):
return self.msg["@type"]
def type(self) -> Optional[str]:
return self.msg.get("@type")
@property
def date(self) -> datetime:
@ -145,7 +145,35 @@ class MsgProxy:
return doc["local"]["is_downloading_completed"]
@property
def reply_msg_id(self):
def is_listened(self) -> Optional[bool]:
if self.type != "voice":
return None
return self.msg["content"]["is_listened"]
@is_listened.setter
def is_listened(self, value: bool):
if self.type != "voice":
return None
self.msg["content"]["is_listened"] = value
@property
def is_viewed(self) -> Optional[bool]:
if self.type != "recording":
return None
return self.msg["content"]["is_viewed"]
@is_viewed.setter
def is_viewed(self, value: bool):
if self.type != "recording":
return None
self.msg["content"]["is_viewed"] = value
@property
def msg_id(self) -> int:
return self.msg["id"]
@property
def reply_msg_id(self) -> Optional[int]:
return self.msg.get("reply_to_message_id")
@property

View file

@ -5,8 +5,7 @@ from datetime import datetime
from typing import Any, Dict, List, Optional, Tuple, cast
from tg.colors import blue, cyan, get_color, magenta, reverse, white
from tg.models import MsgModel
from tg.models import UserModel
from tg.models import MsgModel, UserModel
from tg.msg import MsgProxy
from tg.utils import emoji_pattern, num, truncate_to_len
@ -420,15 +419,23 @@ def parse_content(content: Dict[str, Any]) -> str:
fields = dict(
name=msg.file_name,
duration=msg.duration,
size=msg.human_size,
download=get_download(msg.local, msg.size),
size=msg.human_size,
duration=msg.duration,
listened=format_bool(msg.is_listened),
viewed=format_bool(msg.is_viewed),
)
info = ", ".join(f"{k}={v}" for k, v in fields.items() if v)
return f"[{msg.content_type}: {info}]"
def format_bool(value: Optional[bool]) -> Optional[str]:
if value is None:
return None
return "yes" if value else "no"
def get_download(local, size):
if local["is_downloading_completed"]:
return "yes"