mirror of
https://github.com/paul-nameless/tg
synced 2024-11-22 03:43:19 +00:00
Rewrite config file
This commit is contained in:
parent
797c9a82e0
commit
f331affb58
4 changed files with 105 additions and 81 deletions
72
tg/config.py
72
tg/config.py
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
54
tg/main.py
54
tg/main.py
|
@ -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())
|
||||
|
|
17
tg/utils.py
17
tg/utils.py
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue