Add type hints

This commit is contained in:
Paul Nameless 2020-05-21 20:59:30 +08:00
parent cf80ce41af
commit 3413d8fed8
3 changed files with 43 additions and 36 deletions

View file

@ -6,7 +6,7 @@ import os
DEFAULT_CONFIG = os.path.expanduser("~/.config/tg/tg.conf") DEFAULT_CONFIG = os.path.expanduser("~/.config/tg/tg.conf")
DEFAULT_FILES = os.path.expanduser("~/.cache/tg/") DEFAULT_FILES = os.path.expanduser("~/.cache/tg/")
max_download_size = "10MB" max_download_size = "10MB"
record_cmd = None record_cmd = "ffmpeg -f avfoundation -i ':0' -ar 22050 -b:a 32k '{file_path}'"
long_msg_cmd = "vim -c 'startinsert' {file_path}" long_msg_cmd = "vim -c 'startinsert' {file_path}"
editor = os.environ.get("EDITOR", "vi") editor = os.environ.get("EDITOR", "vi")

View file

@ -34,6 +34,8 @@ MSGS_LEFT_SCROLL_THRESHOLD = 10
# cause blan areas on the msg display screen # cause blan areas on the msg display screen
MSGS_LEFT_SCROLL_THRESHOLD = 2 MSGS_LEFT_SCROLL_THRESHOLD = 2
key_bind_handler = Callable[[Any], Any]
class Controller: class Controller:
""" """
@ -51,9 +53,7 @@ class Controller:
self.chat_size = 0.5 self.chat_size = 0.5
signal(SIGWINCH, self.resize_handler) signal(SIGWINCH, self.resize_handler)
_key_handler_type = Callable[[Any], Any] self.chat_bindings: Dict[str, key_bind_handler] = {
self.chat_bindings: Dict[str, _key_handler_type] = {
"q": lambda _: "QUIT", "q": lambda _: "QUIT",
"l": self.handle_msgs, "l": self.handle_msgs,
"j": self.next_chat, "j": self.next_chat,
@ -70,7 +70,7 @@ class Controller:
"r": self.read_msgs, "r": self.read_msgs,
} }
self.msg_bindings: Dict[str, _key_handler_type] = { self.msg_bindings: Dict[str, key_bind_handler] = {
"q": lambda _: "QUIT", "q": lambda _: "QUIT",
"h": lambda _: "BACK", "h": lambda _: "BACK",
"^D": lambda _: "BACK", "^D": lambda _: "BACK",
@ -99,45 +99,45 @@ class Controller:
"bp": self.breakpoint, "bp": self.breakpoint,
} }
def jump_bottom(self, _): def jump_bottom(self, _: int):
log.info("jump_bottom:") log.info("jump_bottom:")
if self.model.jump_bottom(): if self.model.jump_bottom():
self.refresh_msgs() self.refresh_msgs()
def handle_msgs(self, _): def handle_msgs(self, _: int):
rc = self.handle(self.msg_bindings, 0.2) rc = self.handle(self.msg_bindings, 0.2)
if rc == "QUIT": if rc == "QUIT":
return rc return rc
self.chat_size = 0.5 self.chat_size = 0.5
self.resize() self.resize()
def next_chat(self, rf): def next_chat(self, rf: int):
if self.model.next_chat(rf): if self.model.next_chat(rf):
self.render() self.render()
def prev_chat(self, rf): def prev_chat(self, rf: int):
if self.model.prev_chat(rf): if self.model.prev_chat(rf):
self.render() self.render()
def first_chat(self, _): def first_chat(self, _: int):
if self.model.first_chat(): if self.model.first_chat():
self.render() self.render()
def toggle_unread(self, _): def toggle_unread(self, _: int):
chat = self.model.chats.chats[self.model.current_chat] chat = self.model.chats.chats[self.model.current_chat]
chat_id = chat["id"] chat_id = chat["id"]
toggle = not chat["is_marked_as_unread"] toggle = not chat["is_marked_as_unread"]
self.tg.toggle_chat_is_marked_as_unread(chat_id, toggle) self.tg.toggle_chat_is_marked_as_unread(chat_id, toggle)
self.render() self.render()
def read_msgs(self, _): def read_msgs(self, _: int):
chat = self.model.chats.chats[self.model.current_chat] chat = self.model.chats.chats[self.model.current_chat]
chat_id = chat["id"] chat_id = chat["id"]
msg_id = chat["last_message"]["id"] msg_id = chat["last_message"]["id"]
self.tg.view_messages(chat_id, [msg_id]) self.tg.view_messages(chat_id, [msg_id])
self.render() self.render()
def toggle_mute(self, _): def toggle_mute(self, _: int):
# TODO: if it's msg to yourself, do not change its # TODO: if it's msg to yourself, do not change its
# notification setting, because we can't by documentation, # notification setting, because we can't by documentation,
# instead write about it in status # instead write about it in status
@ -154,26 +154,26 @@ class Controller:
self.tg.set_chat_nottification_settings(chat_id, notification_settings) self.tg.set_chat_nottification_settings(chat_id, notification_settings)
self.render() self.render()
def toggle_pin(self, _): def toggle_pin(self, _: int):
chat = self.model.chats.chats[self.model.current_chat] chat = self.model.chats.chats[self.model.current_chat]
chat_id = chat["id"] chat_id = chat["id"]
toggle = not chat["is_pinned"] toggle = not chat["is_pinned"]
self.tg.toggle_chat_is_pinned(chat_id, toggle) self.tg.toggle_chat_is_pinned(chat_id, toggle)
self.render() self.render()
def next_msg(self, rf): def next_msg(self, rf: int):
if self.model.next_msg(rf): if self.model.next_msg(rf):
self.refresh_msgs() self.refresh_msgs()
def prev_msg(self, rf): def prev_msg(self, rf: int):
if self.model.prev_msg(rf): if self.model.prev_msg(rf):
self.refresh_msgs() self.refresh_msgs()
def breakpoint(self, _): def breakpoint(self, _: int):
with suspend(self.view): with suspend(self.view):
breakpoint() breakpoint()
def write_short_msg(self, _): def write_short_msg(self, _: int):
# write new message # write new message
if msg := self.view.status.get_input(): if msg := self.view.status.get_input():
self.model.send_message(text=msg) self.model.send_message(text=msg)
@ -181,7 +181,7 @@ class Controller:
else: else:
self.present_info("Message wasn't sent") self.present_info("Message wasn't sent")
def send_video(self, _): def send_video(self, _: int):
file_path = self.view.status.get_input() file_path = self.view.status.get_input()
if not file_path or not os.path.isfile(file_path): if not file_path or not os.path.isfile(file_path):
return return
@ -192,7 +192,7 @@ class Controller:
duration = get_duration(file_path) duration = get_duration(file_path)
self.tg.send_video(file_path, chat_id, width, height, duration) self.tg.send_video(file_path, chat_id, width, height, duration)
def delete_msg(self, _): def delete_msg(self, _: int):
if self.model.delete_msg(): if self.model.delete_msg():
self.refresh_msgs() self.refresh_msgs()
self.present_info("Message deleted") self.present_info("Message deleted")
@ -204,7 +204,7 @@ class Controller:
send_file_fun(file_path, chat_id, *args, **kwargs) send_file_fun(file_path, chat_id, *args, **kwargs)
self.present_info("File sent") self.present_info("File sent")
def send_voice(self, _): def send_voice(self, _: int):
file_path = f"/tmp/voice-{datetime.now()}.oga" file_path = f"/tmp/voice-{datetime.now()}.oga"
with suspend(self.view) as s: with suspend(self.view) as s:
s.call(config.record_cmd.format(file_path=file_path)) s.call(config.record_cmd.format(file_path=file_path))
@ -213,14 +213,19 @@ class Controller:
) )
if not is_yes(resp): if not is_yes(resp):
self.present_info("Voice message discarded") self.present_info("Voice message discarded")
elif not os.path.isfile(file_path): return
if not os.path.isfile(file_path):
self.present_info(f"Can't load recording file {file_path}") self.present_info(f"Can't load recording file {file_path}")
else: return
chat_id = self.model.chats.id_by_index(self.model.current_chat)
duration = get_duration(file_path) chat_id = self.model.chats.id_by_index(self.model.current_chat)
waveform = get_waveform(file_path) if not chat_id:
self.tg.send_voice(file_path, chat_id, duration, waveform) return
self.present_info(f"Sent voice msg: {file_path}") duration = get_duration(file_path)
waveform = get_waveform(file_path)
self.tg.send_voice(file_path, chat_id, duration, waveform)
self.present_info(f"Sent voice msg: {file_path}")
def run(self) -> None: def run(self) -> None:
try: try:
@ -228,7 +233,7 @@ class Controller:
except Exception: except Exception:
log.exception("Error happened in main loop") log.exception("Error happened in main loop")
def download_current_file(self, _): def download_current_file(self, _: int):
msg = MsgProxy(self.model.current_msg) msg = MsgProxy(self.model.current_msg)
log.debug("Downloading msg: %s", msg.msg) log.debug("Downloading msg: %s", msg.msg)
file_id = msg.file_id file_id = msg.file_id
@ -244,7 +249,7 @@ class Controller:
self.tg.download_file(file_id=file_id) self.tg.download_file(file_id=file_id)
log.info("Downloaded: file_id=%s", file_id) log.info("Downloaded: file_id=%s", file_id)
def open_current_msg(self, _): def open_current_msg(self, _: int):
msg = MsgProxy(self.model.current_msg) msg = MsgProxy(self.model.current_msg)
if msg.is_text: if msg.is_text:
with NamedTemporaryFile("w", suffix=".txt") as f: with NamedTemporaryFile("w", suffix=".txt") as f:
@ -259,6 +264,8 @@ class Controller:
self.present_info("File should be downloaded first") self.present_info("File should be downloaded first")
return return
chat_id = self.model.chats.id_by_index(self.model.current_chat) chat_id = self.model.chats.id_by_index(self.model.current_chat)
if not chat_id:
return
self.tg.open_message_content(chat_id, msg.msg_id) self.tg.open_message_content(chat_id, msg.msg_id)
with suspend(self.view) as s: with suspend(self.view) as s:
s.open_file(path) s.open_file(path)
@ -273,7 +280,7 @@ class Controller:
with self.lock: with self.lock:
self.view.status.draw(f"{level}: {msg}") self.view.status.draw(f"{level}: {msg}")
def edit_msg(self, _): def edit_msg(self, _: int):
msg = MsgProxy(self.model.current_msg) msg = MsgProxy(self.model.current_msg)
log.info("Editing msg: %s", msg.msg) log.info("Editing msg: %s", msg.msg)
if not self.model.is_me(msg.sender_id): if not self.model.is_me(msg.sender_id):
@ -290,11 +297,11 @@ class Controller:
f.flush() f.flush()
s.call(f"{config.editor} {f.name}") s.call(f"{config.editor} {f.name}")
with open(f.name) as f: with open(f.name) as f:
if msg := f.read().strip(): if text := f.read().strip():
self.model.edit_message(text=msg) self.model.edit_message(text=text)
self.present_info("Message edited") self.present_info("Message edited")
def write_long_msg(self, _): def write_long_msg(self, _: int):
with NamedTemporaryFile("r+", suffix=".txt") as f, suspend( with NamedTemporaryFile("r+", suffix=".txt") as f, suspend(
self.view self.view
) as s: ) as s:
@ -322,7 +329,7 @@ class Controller:
self.view.status.resize(rows, cols) self.view.status.resize(rows, cols)
self.render() self.render()
def handle(self, key_bindings, size): def handle(self, key_bindings: Dict[str, key_bind_handler], size: float):
self.chat_size = size self.chat_size = size
self.resize() self.resize()

View file

@ -51,7 +51,7 @@ def main():
config.max_download_size = utils.parse_size( config.max_download_size = utils.parse_size(
cfg.get("max_download_size", config.max_download_size) cfg.get("max_download_size", config.max_download_size)
) )
config.record_cmd = cfg.get("record_cmd") config.record_cmd = cfg.get("record_cmd", config.record_cmd)
config.long_msg_cmd = cfg.get("long_msg_cmd", config.long_msg_cmd) config.long_msg_cmd = cfg.get("long_msg_cmd", config.long_msg_cmd)
tg.login() tg.login()