diff --git a/tg/controllers/__init__.py b/tg/controllers/__init__.py index d75f448..6515751 100644 --- a/tg/controllers/__init__.py +++ b/tg/controllers/__init__.py @@ -42,17 +42,19 @@ class Controller: def download_current_file(self): msg = MsgProxy(self.model.current_msg()) log.debug("Downloading msg: %s", msg.msg) - if msg.file_id: - log.info("Downloading file: file_id=%s", msg.file_id) - self.tg.download_file(file_id=msg.file_id) - log.info("Downloaded: file_id=%s", msg.file_id) + file_id = msg.file_id + if file_id: + log.info("Downloading file: file_id=%s", file_id) + self.model.downloads[file_id] = (msg["chat_id"], msg["id"]) + self.tg.download_file(file_id=file_id) + log.info("Downloaded: file_id=%s", file_id) 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') as f: + text = msg["content"]["text"]["text"] + with NamedTemporaryFile("w") as f: f.write(text) f.flush() with suspend(self.view) as s: @@ -64,6 +66,7 @@ class Controller: # handle with mimetype and mailcap # if multiple entries in mailcap, open fzf to choose with suspend(self.view) as s: + log.info("Opening file: %s", path) s.call(["open", path]) def handle_msgs(self) -> str: @@ -224,11 +227,20 @@ class Controller: @handle_exception def update_file(self, update): log.info("====: %s", update) - file_id = update['file']['id'] - local = update['file']['local'] - for msg in map(MsgProxy, self.model.get_current_chat_msgs()): - log.info("____: %s, %s", msg.file_id, file_id) - if msg.file_id == file_id: - msg.local = local + file_id = update["file"]["id"] + local = update["file"]["local"] + chat_id, msg_id = self.model.downloads.get(file_id, (None, None)) + if chat_id is None: + log.warning( + "Can't find information about file with file_id=%s", file_id + ) + return + msgs = self.model.msgs.msgs[chat_id] + for msg in msgs: + if msg["id"] == msg_id: + proxy = MsgProxy(msg) + proxy.local = local self.refresh_msgs() + if proxy.is_downloaded(): + self.model.downloads.pop(file_id) break diff --git a/tg/models/__init__.py b/tg/models/__init__.py index 928b7be..669fa80 100644 --- a/tg/models/__init__.py +++ b/tg/models/__init__.py @@ -13,6 +13,7 @@ class Model: self.msgs = MsgModel(tg) self.users = UserModel(tg) self.current_chat = 0 + self.downloads = {} def get_me(self): return self.users.get_me() @@ -26,12 +27,6 @@ class Model: return None return self.msgs.current_msgs[chat_id] - def get_current_chat_msgs(self) -> Optional[int]: - chat_id = self.chats.id_by_index(self.current_chat) - if chat_id is None: - return None - return self.msgs.msgs[chat_id] - def fetch_msgs(self, offset: int = 0, limit: int = 10) -> Any: chat_id = self.chats.id_by_index(self.current_chat) if chat_id is None: @@ -41,7 +36,7 @@ class Model: def current_msg(self): chat_id = self.chats.id_by_index(self.current_chat) if chat_id is None: - return [] + return {} current_msg = self.msgs.current_msgs[chat_id] return self.msgs.msgs[chat_id][current_msg] @@ -232,6 +227,7 @@ class MsgModel: return False log.info(f"adding {msg_id=} {message}") self.msgs[chat_id].append(message) + # self.current_msgs[chat_id] += 1 msg_set.add(msg_id) return True diff --git a/tg/msg.py b/tg/msg.py index 25db1a4..8dd0fee 100644 --- a/tg/msg.py +++ b/tg/msg.py @@ -6,29 +6,31 @@ log = logging.getLogger(__name__) class MsgProxy: fields_mapping = { - 'messageDocument': ("document", "document"), - 'messageVoiceNote': ("voice_note", "voice"), - 'messageText': ("text", "text"), + "messageDocument": ("document", "document"), + "messageVoiceNote": ("voice_note", "voice"), + "messageText": ("text", "text"), "messagePhoto": ("photo", "sizes", 0, "photo"), - 'messageAudio': ("audio", "audio"), - 'messageVideo': ('video', "video"), - 'messageVideoNote': ("video_note", "video"), + "messageAudio": ("audio", "audio"), + "messageVideo": ("video", "video"), + "messageVideoNote": ("video_note", "video"), + "messageSticker": ("sticker", "sticker"), } types = { - 'messageDocument': 'document', - 'messageVoiceNote': 'voice', - 'messageText': 'text', - "messagePhoto": 'photo', - 'messageAudio': 'audio', - 'messageVideo': 'video', - 'messageVideoNote': 'recording', + "messageDocument": "document", + "messageVoiceNote": "voice", + "messageText": "text", + "messagePhoto": "photo", + "messageAudio": "audio", + "messageVideo": "video", + "messageVideoNote": "recording", + "messageSticker": "sticker", } @classmethod def get_doc(cls, msg, deep=10): - doc = msg['content'] - _type = doc['@type'] + doc = msg["content"] + _type = doc["@type"] fields = cls.fields_mapping.get(_type) if fields is None: log.error("msg type not supported: %s", _type) @@ -53,54 +55,65 @@ class MsgProxy: @property def type(self): - return self.types.get(self.msg['content']['@type']) + return self.types.get(self.msg["content"]["@type"]) @property def size(self): doc = self.get_doc(self.msg) - return doc['size'] + return doc["size"] @property def duration(self): - if self.type not in ('audio', 'voice'): + if self.type not in ("audio", "voice"): return None doc = self.get_doc(self.msg, deep=1) - return doc['duration'] + return doc["duration"] @property def file_name(self): - if self.type not in ('audio', 'document', 'video'): + if self.type not in ("audio", "document", "video"): return None doc = self.get_doc(self.msg, deep=1) - return doc['file_name'] + return doc["file_name"] @property def file_id(self): - if self.type not in ('audio', 'document', 'photo', 'video', 'recording'): + if self.type not in ( + "audio", + "document", + "photo", + "video", + "recording", + "sticker", + ): return None doc = self.get_doc(self.msg) - return doc['id'] + return doc["id"] @property def local_path(self): + if self.msg["content"]["@type"] not in self.types: + return None doc = self.get_doc(self.msg) - return doc['local']['path'] + return doc["local"]["path"] @property def local(self): doc = self.get_doc(self.msg) - return doc['local'] + return doc["local"] @local.setter def local(self, value): + if self.msg["content"]["@type"] not in self.types: + return None doc = self.get_doc(self.msg) - doc['local'] = value + doc["local"] = value @property def is_text(self): - return self.msg['content']['@type'] == 'messageText' + return self.msg["content"]["@type"] == "messageText" @property def is_downloaded(self): doc = self.get_doc(self.msg) - return doc['local']['is_downloading_completed'] + return doc["local"]["is_downloading_completed"] diff --git a/tg/utils.py b/tg/utils.py index 3f063b5..ee78306 100644 --- a/tg/utils.py +++ b/tg/utils.py @@ -35,11 +35,11 @@ def handle_exception(fun): return fun(*args, **kwargs) except Exception: log.exception("Error happened in %s handler", fun.__name__) + return wrapper class suspend: - def __init__(self, view): self.view = view diff --git a/tg/views/__init__.py b/tg/views/__init__.py index 8a76fdb..cbd74e3 100644 --- a/tg/views/__init__.py +++ b/tg/views/__init__.py @@ -324,27 +324,25 @@ def parse_content(content: Dict[str, Any]) -> str: if not msg.type: # not implemented - _type = content['@type'] + _type = content["@type"] return f"[{_type}]" fields = dict( name=msg.file_name, duration=msg.duration, size=msg.size, - download=get_download(msg.local, msg.size) - ) - info = ', '.join( - f"{k}={v}" for k, v in fields.items() if v is not None + download=get_download(msg.local, msg.size), ) + info = ", ".join(f"{k}={v}" for k, v in fields.items() if v is not None) return f"[{msg.type}: {info}]" def get_download(local, size): - if local['is_downloading_completed']: + if local["is_downloading_completed"]: return "yes" - elif local['is_downloading_active']: - d = local['downloaded_size'] + elif local["is_downloading_active"]: + d = local["downloaded_size"] percent = int(d * 100 / size) return f"{percent}%" return "no"