diff --git a/tg/controllers/__init__.py b/tg/controllers/__init__.py index 6e1da1f..e78f3d2 100644 --- a/tg/controllers/__init__.py +++ b/tg/controllers/__init__.py @@ -6,6 +6,8 @@ from utils import notify log = logging.getLogger(__name__) +SUPPORTED_MSG_TYPES = "updateNewMessage", "updateChatLastMessage" + class Controller: """ @@ -85,11 +87,7 @@ class Controller: # write new message msg = self.view.get_input() if msg: - chat_id = self.model.get_current_chat_id() - self.model.msgs.send_message( - chat_id=chat_id, - text=msg, - ) + self.model.send_message(text=msg) self.view.draw_status(f'Sent: {msg}') elif keys in ('h', '^D'): @@ -131,12 +129,14 @@ class Controller: self.refresh_chats() def refresh_chats(self): - self.view.draw_chats( - self.model.current_chat, - self.model.get_chats(limit=self.view.chats.h) - ) - self.refresh_msgs() - self.view.draw_status() + with self.lock: + # using lock here, because model.get_chats is vulnerable to race conditions + self.view.draw_chats( + self.model.current_chat, + self.model.get_chats(limit=self.view.chats.h) + ) + self.refresh_msgs() + self.view.draw_status() def refresh_msgs(self): self.view.msgs.users = self.model.users @@ -145,10 +145,10 @@ class Controller: def update_handler(self, update): try: - log.info('===Received: %s', update) _type = update['@type'] + log.info('===Received %s type: %s', _type, update) if _type == 'updateNewMessage': - # with self.lock: + # with self.lock(): chat_id = update['message']['chat_id'] self.model.msgs.msgs[chat_id].append(update['message']) # msgs = self.model.get_current_chat_msg() @@ -156,6 +156,13 @@ class Controller: if not update.get('disable_notification'): if update['message']['content'] == 'text': notify(update['message']['content']['text']['text']) + elif _type == 'updateChatLastMessage': + log.info("Proccessing updateChatLastMessage") + chat_id = update['chat_id'] + message = update['last_message'] + self.model.chats.update_last_message(chat_id, message) + self.refresh_chats() + except Exception: log.exception("Error happened in update_handler") # message_content = update['message']['content'].get('text', {}) diff --git a/tg/main.py b/tg/main.py index 72824fa..321e191 100644 --- a/tg/main.py +++ b/tg/main.py @@ -7,7 +7,7 @@ from functools import partial from telegram.client import Telegram -from tg.controllers import Controller +from tg.controllers import Controller, SUPPORTED_MSG_TYPES from tg.models import Model from tg.views import View @@ -37,7 +37,8 @@ def run(tg, stdscr): model = Model(tg) controller = Controller(model, view) controller.tg = tg - tg.add_message_handler(controller.update_handler) + for msg_type in SUPPORTED_MSG_TYPES: + tg.add_update_handler(msg_type, controller.update_handler) t = threading.Thread( target=controller.run, diff --git a/tg/models/__init__.py b/tg/models/__init__.py index 50155b9..2dc5a25 100644 --- a/tg/models/__init__.py +++ b/tg/models/__init__.py @@ -77,7 +77,14 @@ class Model: return self.msgs.jump_prev_msg(chat_id) def get_chats(self, offset=0, limit=10): - return self.chats.get_chats(offset=offset, limit=limit) + return self.chats.fetch_chats(offset=offset, limit=limit) + + def send_message(self, text): + chat_id = self.get_current_chat_id() + if chat_id is None: + return False + self.msgs.send_message(chat_id, text) + return True def delete_msg(self): chat_id = self.get_current_chat_id() @@ -92,14 +99,14 @@ class ChatModel: self.chats = [] # Dict[int, list] self.chat_ids = [] - def get_chats(self, offset=0, limit=10): + def fetch_chats(self, offset=0, limit=10): if offset + limit < len(self.chats): # return data from cache return self.chats[offset:limit] previous_chats_num = len(self.chat_ids) - self.get_chat_ids( + self.fetch_chat_ids( offset=len(self.chats), limit=len(self.chats) + limit ) @@ -107,12 +114,12 @@ class ChatModel: return self.chats[offset:limit] for chat_id in self.chat_ids: - chat = self.get_chat(chat_id) + chat = self.fetch_chat(chat_id) self.chats.append(chat) return self.chats[offset:limit] - def get_chat_ids(self, offset=0, limit=10): + def fetch_chat_ids(self, offset=0, limit=10): if len(self.chats): result = self.tg.get_chats( offset_chat_id=self.chats[-1]['id'], @@ -139,7 +146,7 @@ class ChatModel: return self.chat_ids[offset:limit] - def get_chat(self, chat_id): + def fetch_chat(self, chat_id): result = self.tg.get_chat(chat_id) result.wait() @@ -148,6 +155,17 @@ class ChatModel: return {} return result.update + def update_last_message(self, chat_id, message): + for i, c in enumerate(self.chats): + if c['id'] != chat_id: + continue + self.chats[i]['last_message'] = message + log.info("Updated last message") + return True + else: + log.error(f"Can't find chat {chat_id} in existing chats") + return False + class MsgModel: