Rewrite config file

This commit is contained in:
Paul Nameless 2020-05-22 11:59:39 +08:00
parent 797c9a82e0
commit f331affb58
4 changed files with 105 additions and 81 deletions

View file

@ -1,36 +1,46 @@
import configparser
import mailcap
import mimetypes
"""
Every parameter (except for DEFAULT_CONFIG) can be
overwritten by external config file
"""
import os
import platform
import runpy
DEFAULT_CONFIG = os.path.expanduser("~/.config/tg/tg.conf")
_os_name = platform.system()
_darwin = 'Darwin'
_linux = 'Linux'
DEFAULT_CONFIG = os.path.expanduser("~/.config/tg/conf.py")
DEFAULT_FILES = os.path.expanduser("~/.cache/tg/")
max_download_size = "10MB"
record_cmd = "ffmpeg -f avfoundation -i ':0' -ar 22050 -b:a 32k '{file_path}'"
long_msg_cmd = "vim -c 'startinsert' {file_path}"
editor = os.environ.get("EDITOR", "vi")
LOG_LEVEL = "INFO"
API_ID = '559815'
API_HASH = 'fd121358f59d764c57c55871aa0807ca'
PHONE = None
ENC_KEY = None
TDLIB_PATH = None
TDLIB_VERBOSITY = 0
MAX_DOWNLOAD_SIZE = "10MB"
# TODO: check if darwin
NOTIFY_CMD = "/usr/local/bin/terminal-notifier -title '{title}' -subtitle '{subtitle}' -message '{msg}' -appIcon '{icon_path}'"
# TODO: check if darwin
RECORD_CMD = "ffmpeg -f avfoundation -i ':0' -ar 22050 -b:a 32k '{file_path}'"
# TODO: use mailcap instead of editor
LONG_MSG_CMD = "vim -c 'startinsert' {file_path}"
EDITOR = os.environ.get("EDITOR", "vi")
# TODO: if os == darwin else open-xdb?
DEFAULT_OPEN = "open '{file_path}'" if _os_name == _linux else "open '{file_path}'"
def get_cfg(config=DEFAULT_CONFIG):
cfg = configparser.ConfigParser()
cfg.read(config)
return cfg
def save_cfg(cfg, config=DEFAULT_CONFIG):
config_dir = os.path.dirname(config)
if not os.path.isdir(config_dir):
os.makedirs(config_dir)
with open(config, "w") as f:
cfg.write(f)
def get_file_handler(file_name, default=None):
mtype, _ = mimetypes.guess_type(file_name)
if not mtype:
return default
caps = mailcap.getcaps()
handler, view = mailcap.findmatch(caps, mtype, filename=file_name)
if not handler:
return None
return handler
if os.path.isfile(DEFAULT_CONFIG):
env_config_params = runpy.run_path(DEFAULT_CONFIG)
for param, value in env_config_params.items():
if param.isupper():
globals()[param] = value

View file

@ -4,7 +4,6 @@ import os
import threading
from datetime import datetime
from functools import partial
from signal import SIGWINCH, signal
from tempfile import NamedTemporaryFile
from typing import Any, Callable, Dict, Optional
@ -51,7 +50,6 @@ class Controller:
self.lock = threading.Lock()
self.tg = tg
self.chat_size = 0.5
signal(SIGWINCH, self.resize_handler)
self.chat_bindings: Dict[str, key_bind_handler] = {
"q": lambda _: "QUIT",
@ -62,18 +60,20 @@ class Controller:
"^P": self.prev_chat,
"J": lambda _: self.next_chat(10),
"K": lambda _: self.prev_chat(10),
"gg": lambda _: self.first_chat,
"bp": lambda _: self.breakpoint,
"u": lambda _: self.toggle_unread,
"p": lambda _: self.toggle_pin,
"m": lambda _: self.toggle_mute,
"r": lambda _: self.read_msgs,
"gg": lambda _: self.first_chat(),
"bp": lambda _: self.breakpoint(),
"u": lambda _: self.toggle_unread(),
"p": lambda _: self.toggle_pin(),
"m": lambda _: self.toggle_mute(),
"r": lambda _: self.read_msgs(),
}
self.msg_bindings: Dict[str, key_bind_handler] = {
"q": lambda _: "QUIT",
"h": lambda _: "BACK",
"bp": lambda _: self.breakpoint(),
"^D": lambda _: "BACK",
# navigate msgs
"]": self.next_chat,
"[": self.prev_chat,
"J": lambda _: self.next_msg(10),
@ -82,18 +82,27 @@ class Controller:
"^N": self.next_msg,
"k": self.prev_msg,
"^P": self.prev_msg,
"G": lambda _: self.jump_bottom,
"dd": lambda _: self.delete_msg,
"D": lambda _: self.download_current_file,
"l": lambda _: self.open_current_msg,
"G": lambda _: self.jump_bottom(),
# send files
"sd": lambda _: self.send_file(self.tg.send_doc),
"sp": lambda _: self.send_file(self.tg.send_photo),
"sa": lambda _: self.send_file(self.tg.send_audio),
" ": lambda _: self.toggle_select_msg,
"^[": lambda _: self.discard_selected_msgs, # esc
"y": lambda _: self.copy_msgs,
"p": lambda _: self.forward_msgs,
"sv": lambda _: self.send_video(),
"v": lambda _: self.send_voice(),
# manipulate msgs
"dd": lambda _: self.delete_msg(),
"D": lambda _: self.download_current_file(),
"l": lambda _: self.open_current_msg(),
"e": lambda _: self.edit_msg(),
"i": lambda _: self.write_short_msg(),
"a": lambda _: self.write_short_msg(),
"I": lambda _: self.write_long_msg(),
"A": lambda _: self.write_long_msg(),
"p": lambda _: self.forward_msgs(),
"y": lambda _: self.copy_msgs(),
# message selection
" ": lambda _: self.toggle_select_msg(),
"^[": lambda _: self.discard_selected_msgs(), # esc
}
def forward_msgs(self, _: int):

View file

@ -14,14 +14,34 @@ from tg.views import ChatView, MsgView, StatusView, View
log = logging.getLogger(__name__)
def run(tg: Tdlib, stdscr: window) -> None:
# run this function in thread?
def main(stdscr: window) -> None:
utils.setup_log(config.LOG_LEVEL)
tg = Tdlib(
api_id=config.API_ID,
api_hash=config.API_HASH,
phone=config.PHONE,
database_encryption_key=config.ENC_KEY,
files_directory=config.DEFAULT_FILES,
tdlib_verbosity=config.TDLIB_VERBOSITY,
library_path=config.TDLIB_PATH,
)
tg.login()
# handle ctrl+c, to avoid interrupting tg when subprocess is called
def interrupt_signal_handler(sig, frame):
# TODO: draw on status pane: to quite press <q>
log.info("Interrupt signal is handled and ignored on purpose")
signal.signal(signal.SIGINT, interrupt_signal_handler)
model = Model(tg)
status_view = StatusView(stdscr)
msg_view = MsgView(stdscr, model.msgs, model, model.users)
chat_view = ChatView(stdscr)
view = View(stdscr, chat_view, msg_view, status_view)
controller = Controller(model, view, tg)
# hanlde resize of terminal correctly
signal.signal(signal.SIGWINCH, controller.resize_handler)
for msg_type, handler in update_handlers.handlers.items():
tg.add_update_handler(msg_type, partial(handler, controller))
@ -30,33 +50,5 @@ def run(tg: Tdlib, stdscr: window) -> None:
t.join()
def main():
def signal_handler(sig, frame):
log.info("You pressed Ctrl+C!")
signal.signal(signal.SIGINT, signal_handler)
cfg = config.get_cfg()["DEFAULT"]
utils.setup_log(cfg.get("level", "DEBUG"))
log.debug("#" * 64)
tg = Tdlib(
api_id=cfg["api_id"],
api_hash=cfg["api_hash"],
phone=cfg["phone"],
database_encryption_key=cfg["enc_key"],
files_directory=cfg.get("files", config.DEFAULT_FILES),
tdlib_verbosity=cfg.get("tdlib_verbosity", 0),
library_path=cfg.get("library_path"),
)
config.max_download_size = utils.parse_size(
cfg.get("max_download_size", config.max_download_size)
)
config.record_cmd = cfg.get("record_cmd", config.record_cmd)
config.long_msg_cmd = cfg.get("long_msg_cmd", config.long_msg_cmd)
tg.login()
wrapper(partial(run, tg))
if __name__ == "__main__":
main()
wrapper(main())

View file

@ -1,7 +1,9 @@
import base64
import curses
import logging
import mailcap
import math
import mimetypes
import os
import random
import re
@ -30,6 +32,17 @@ emoji_pattern = re.compile(
units = {"B": 1, "KB": 10 ** 3, "MB": 10 ** 6, "GB": 10 ** 9, "TB": 10 ** 12}
def get_file_handler(file_name, default=None):
mtype, _ = mimetypes.guess_type(file_name)
if not mtype:
return default
caps = mailcap.getcaps()
handler, view = mailcap.findmatch(caps, mtype, filename=file_name)
if not handler:
return None
return handler
def parse_size(size):
if size[-2].isalpha():
number, unit = size[:-2], size[-2:]
@ -110,7 +123,7 @@ def notify(
msg,
subtitle="",
title="tg",
cmd=config.get_cfg()["DEFAULT"].get("notify_cmd"),
cmd=config.NOTIFY_CMD,
):
if not cmd:
return
@ -146,7 +159,7 @@ class suspend:
subprocess.call(cmd, shell=True)
def open_file(self, file_path):
cmd = config.get_file_handler(file_path)
cmd = get_file_handler(file_path)
if not cmd:
return
self.call(cmd)