mirror of
https://github.com/paul-nameless/tg
synced 2024-11-22 03:43:19 +00:00
Fix incorrect window resizing
Add sending message functionality
This commit is contained in:
parent
473f96902f
commit
d03866f0e3
4 changed files with 110 additions and 104 deletions
|
@ -2,6 +2,8 @@ import logging
|
||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
|
from utils import notify
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,52 +20,12 @@ class Controller:
|
||||||
self.view = view
|
self.view = view
|
||||||
self.lock = threading.Lock()
|
self.lock = threading.Lock()
|
||||||
|
|
||||||
def init(self):
|
|
||||||
pass
|
|
||||||
# self.refresh_chats()
|
|
||||||
# self.refresh_msgs()
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
try:
|
try:
|
||||||
self.handle()
|
self.handle_chats()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception('Error happened in main loop')
|
logger.exception('Error happened in main loop')
|
||||||
|
|
||||||
# def send_msg(self):
|
|
||||||
# import curses
|
|
||||||
# # curses.nocbreak()
|
|
||||||
# curses.echo()
|
|
||||||
# curses.curs_set(1)
|
|
||||||
|
|
||||||
# buff = ''
|
|
||||||
# while True:
|
|
||||||
# key = self.view.get_key(
|
|
||||||
# self.view.chats.h, self.view.chats.w)
|
|
||||||
# logger.info('Pressed in send msg: %s', key)
|
|
||||||
# if key == '^J':
|
|
||||||
# break
|
|
||||||
# elif key == '^G':
|
|
||||||
# # curses.cbreak()
|
|
||||||
# # curses.noecho()
|
|
||||||
# # self.view.chats.win.refresh()
|
|
||||||
# buff = ''
|
|
||||||
# break
|
|
||||||
# buff += key
|
|
||||||
|
|
||||||
# logger.info('Sending msg: %s', buff)
|
|
||||||
# curses.cbreak()
|
|
||||||
# curses.noecho()
|
|
||||||
# curses.curs_set(0)
|
|
||||||
|
|
||||||
# chat_id = self.model.get_current_chat_id()
|
|
||||||
# self.model.send_msg(chat_id, buff)
|
|
||||||
# self.view.draw_chats(
|
|
||||||
# self.model.current_chat,
|
|
||||||
# self.model.get_chats()
|
|
||||||
# )
|
|
||||||
# msgs = self.model.get_current_msgs()
|
|
||||||
# self.view.draw_msgs(msgs)
|
|
||||||
|
|
||||||
def handle_msgs(self):
|
def handle_msgs(self):
|
||||||
# set width to 0.25, move window to left
|
# set width to 0.25, move window to left
|
||||||
# refresh everything
|
# refresh everything
|
||||||
|
@ -102,26 +64,22 @@ class Controller:
|
||||||
# reply to this msg
|
# reply to this msg
|
||||||
# print to status line
|
# print to status line
|
||||||
pass
|
pass
|
||||||
|
elif key == 'I':
|
||||||
|
# open vim or emacs to write long messages
|
||||||
|
pass
|
||||||
elif key == 'i':
|
elif key == 'i':
|
||||||
# write new message
|
# write new message
|
||||||
pass
|
msg = self.view.get_input()
|
||||||
|
if msg:
|
||||||
|
chat_id = self.model.get_current_chat_id()
|
||||||
|
self.model.msgs.tg.send_message(
|
||||||
|
chat_id=chat_id,
|
||||||
|
text=msg,
|
||||||
|
)
|
||||||
|
|
||||||
elif key == 'h':
|
elif key == 'h':
|
||||||
return 'BACK'
|
return 'BACK'
|
||||||
|
|
||||||
def handle(self):
|
|
||||||
self.handle_chats()
|
|
||||||
|
|
||||||
def refresh_chats(self):
|
|
||||||
self.view.draw_chats(
|
|
||||||
self.model.current_chat,
|
|
||||||
self.model.get_chats()
|
|
||||||
)
|
|
||||||
self.refresh_msgs()
|
|
||||||
|
|
||||||
def refresh_msgs(self):
|
|
||||||
msgs = self.model.get_current_msgs()
|
|
||||||
self.view.draw_msgs(self.model.get_current_msg(), msgs)
|
|
||||||
|
|
||||||
def handle_chats(self):
|
def handle_chats(self):
|
||||||
# set width to 0.5, move window to center?
|
# set width to 0.5, move window to center?
|
||||||
# refresh everything
|
# refresh everything
|
||||||
|
@ -152,6 +110,17 @@ class Controller:
|
||||||
if is_changed:
|
if is_changed:
|
||||||
self.refresh_chats()
|
self.refresh_chats()
|
||||||
|
|
||||||
|
def refresh_chats(self):
|
||||||
|
self.view.draw_chats(
|
||||||
|
self.model.current_chat,
|
||||||
|
self.model.get_chats()
|
||||||
|
)
|
||||||
|
self.refresh_msgs()
|
||||||
|
|
||||||
|
def refresh_msgs(self):
|
||||||
|
msgs = self.model.get_current_msgs()
|
||||||
|
self.view.draw_msgs(self.model.get_current_msg(), msgs)
|
||||||
|
|
||||||
def update_handler(self, update):
|
def update_handler(self, update):
|
||||||
logger.debug('===============Received: %s', update)
|
logger.debug('===============Received: %s', update)
|
||||||
_type = update['@type']
|
_type = update['@type']
|
||||||
|
@ -178,18 +147,3 @@ class Controller:
|
||||||
# chat_id=chat_id,
|
# chat_id=chat_id,
|
||||||
# text='pong',
|
# text='pong',
|
||||||
# )
|
# )
|
||||||
|
|
||||||
|
|
||||||
def notify(msg, subtitle='New message', title='Telegram'):
|
|
||||||
msg = '-message {!r}'.format(msg)
|
|
||||||
subtitle = '-subtitle {!r}'.format(subtitle)
|
|
||||||
title = '-title {!r}'.format(title)
|
|
||||||
sound = '-sound default'
|
|
||||||
icon_path = os.path.join(os.path.dirname(__file__), 'tg.png')
|
|
||||||
icon = f'-appIcon {icon_path}'
|
|
||||||
cmd = '/usr/local/bin/terminal-notifier'
|
|
||||||
|
|
||||||
logger.debug('####: %s', f'{cmd} {icon} {sound} {title} {subtitle} {msg}')
|
|
||||||
os.system(
|
|
||||||
f'{cmd} {icon} {sound} {title} {subtitle} {msg}'
|
|
||||||
)
|
|
||||||
|
|
2
main.py
2
main.py
|
@ -32,11 +32,11 @@ if PHONE is None:
|
||||||
|
|
||||||
|
|
||||||
def run(tg, stdscr):
|
def run(tg, stdscr):
|
||||||
|
# run this function in thread?
|
||||||
view = View(stdscr)
|
view = View(stdscr)
|
||||||
model = Model(tg)
|
model = Model(tg)
|
||||||
controller = Controller(model, view)
|
controller = Controller(model, view)
|
||||||
controller.tg = tg
|
controller.tg = tg
|
||||||
controller.init()
|
|
||||||
tg.add_message_handler(controller.update_handler)
|
tg.add_message_handler(controller.update_handler)
|
||||||
|
|
||||||
t = threading.Thread(
|
t = threading.Thread(
|
||||||
|
|
19
utils.py
Normal file
19
utils.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def notify(msg, subtitle='New message', title='Telegram'):
|
||||||
|
msg = '-message {!r}'.format(msg)
|
||||||
|
subtitle = '-subtitle {!r}'.format(subtitle)
|
||||||
|
title = '-title {!r}'.format(title)
|
||||||
|
sound = '-sound default'
|
||||||
|
icon_path = os.path.join(os.path.dirname(__file__), 'tg.png')
|
||||||
|
icon = f'-appIcon {icon_path}'
|
||||||
|
cmd = '/usr/local/bin/terminal-notifier'
|
||||||
|
|
||||||
|
logger.debug('####: %s', f'{cmd} {icon} {sound} {title} {subtitle} {msg}')
|
||||||
|
os.system(
|
||||||
|
f'{cmd} {icon} {sound} {title} {subtitle} {msg}'
|
||||||
|
)
|
97
view.py
97
view.py
|
@ -35,15 +35,48 @@ class View:
|
||||||
|
|
||||||
ch = self.stdscr.getch(y, x)
|
ch = self.stdscr.getch(y, x)
|
||||||
logger.info('raw ch without unctrl: %s', ch)
|
logger.info('raw ch without unctrl: %s', ch)
|
||||||
return curses.unctrl(ch).decode()
|
try:
|
||||||
|
return curses.unctrl(ch).decode()
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
logger.warning('cant uncrtl: %s', ch)
|
||||||
|
return 'UNKNOWN'
|
||||||
|
|
||||||
# self.stdscr.addstr(self.msgs.h, self.chats.w, ' ' * self.msgs.w-10)
|
def get_key_input(self, y, x):
|
||||||
# self.chats.win.addstr(self.msgs.h, self.chats.w +
|
ch = self.msgs.win.getch(y, x)
|
||||||
# 5, ' ' * self.msgs.w-10)
|
logger.info('raw ch without unctrl in msgs: %s', ch)
|
||||||
|
return ch
|
||||||
|
# return curses.unctrl(ch).decode()
|
||||||
|
|
||||||
# _input = self.stdscr.getstr(
|
def get_input(self):
|
||||||
# self.msgs.h, self.chats.w, self.max_read).decode()
|
curses.echo()
|
||||||
# return _input
|
curses.curs_set(1)
|
||||||
|
|
||||||
|
buff = ''
|
||||||
|
pos = 0
|
||||||
|
while True:
|
||||||
|
key = self.msgs.win.get_wch(self.msgs.h-1, pos)
|
||||||
|
key = ord(key)
|
||||||
|
logger.info('Pressed in send msg: "%s"', key)
|
||||||
|
# try:
|
||||||
|
logger.info('Trying to chr: %s', chr(key))
|
||||||
|
# except ValueError:
|
||||||
|
# logger.exception()
|
||||||
|
if key == 10:
|
||||||
|
logger.info('Sending msg: %s', buff)
|
||||||
|
break
|
||||||
|
elif key == 7:
|
||||||
|
logger.info('Not Sending msg: %s', buff)
|
||||||
|
buff = None
|
||||||
|
break
|
||||||
|
# elif (key >= 32 and key < 256):
|
||||||
|
elif chr(key).isprintable():
|
||||||
|
buff += chr(key)
|
||||||
|
pos += 1
|
||||||
|
|
||||||
|
# curses.cbreak()
|
||||||
|
curses.noecho()
|
||||||
|
curses.curs_set(0)
|
||||||
|
return buff
|
||||||
|
|
||||||
|
|
||||||
class StatusView:
|
class StatusView:
|
||||||
|
@ -66,6 +99,8 @@ emoji_pattern = re.compile(
|
||||||
"\U0001F300-\U0001F5FF" # symbols & pictographs
|
"\U0001F300-\U0001F5FF" # symbols & pictographs
|
||||||
"\U0001F680-\U0001F6FF" # transport & map symbols
|
"\U0001F680-\U0001F6FF" # transport & map symbols
|
||||||
"\U0001F1E0-\U0001F1FF" # flags (iOS)
|
"\U0001F1E0-\U0001F1FF" # flags (iOS)
|
||||||
|
"\U00002702-\U000027B0"
|
||||||
|
"\U000024C2-\U0001F251"
|
||||||
"]+",
|
"]+",
|
||||||
flags=re.UNICODE
|
flags=re.UNICODE
|
||||||
)
|
)
|
||||||
|
@ -73,8 +108,8 @@ emoji_pattern = re.compile(
|
||||||
|
|
||||||
class ChatView:
|
class ChatView:
|
||||||
def __init__(self, stdscr, p=0.5):
|
def __init__(self, stdscr, p=0.5):
|
||||||
self.h = curses.LINES - 1
|
self.h = 0
|
||||||
self.w = int((curses.COLS - 1) * p)
|
self.w = 0
|
||||||
self.win = stdscr.subwin(self.h, self.w, 0, 0)
|
self.win = stdscr.subwin(self.h, self.w, 0, 0)
|
||||||
|
|
||||||
def resize(self, p=0.25):
|
def resize(self, p=0.25):
|
||||||
|
@ -86,8 +121,9 @@ class ChatView:
|
||||||
self.win.clear()
|
self.win.clear()
|
||||||
# self.win.vline(0, self.w-1, curses.ACS_VLINE, self.h)
|
# self.win.vline(0, self.w-1, curses.ACS_VLINE, self.h)
|
||||||
for i, chat in enumerate(chats):
|
for i, chat in enumerate(chats):
|
||||||
msg = f'{get_date(chat)} {chat["title"]} {chat["unread_count"]}: {get_last_msg(chat)}'
|
msg = f'{get_date(chat)} {chat["title"]} [{chat["unread_count"]}]: {get_last_msg(chat)}'
|
||||||
msg = emoji_pattern.sub(r'', msg)[:self.w-1]
|
# msg = emoji_pattern.sub(r'', msg)[:self.w-1]
|
||||||
|
msg = msg[:self.w]
|
||||||
if len(msg) < self.w:
|
if len(msg) < self.w:
|
||||||
msg += ' ' * (self.w - len(msg) - 1)
|
msg += ' ' * (self.w - len(msg) - 1)
|
||||||
if i == current:
|
if i == current:
|
||||||
|
@ -101,21 +137,29 @@ class ChatView:
|
||||||
class MsgView:
|
class MsgView:
|
||||||
def __init__(self, stdscr, p=0.5):
|
def __init__(self, stdscr, p=0.5):
|
||||||
self.stdscr = stdscr
|
self.stdscr = stdscr
|
||||||
self.h = curses.LINES - 1
|
# self.h = curses.LINES - 1
|
||||||
self.w = curses.COLS - int((curses.COLS - 1) * p)
|
# self.w = curses.COLS - int((curses.COLS - 1) * p)
|
||||||
self.s = curses.COLS - self.w
|
# self.x = curses.COLS - self.w
|
||||||
self.win = stdscr.subwin(self.h, self.w, 0, self.s)
|
self.h = 0
|
||||||
|
self.w = 0
|
||||||
|
# self.x = curses.COLS - (curses.COLS - int((curses.COLS - 1) * p))
|
||||||
|
self.x = 0
|
||||||
|
# self.win = stdscr.subwin(self.h, self.w, 0, self.x)
|
||||||
|
self.win = None
|
||||||
|
# self.win.scrollok(True)
|
||||||
|
# self.win.idlok(True)
|
||||||
self.lines = 0
|
self.lines = 0
|
||||||
|
|
||||||
def resize(self, p=0.25):
|
def resize(self, p=0.5):
|
||||||
self.h = curses.LINES - 1
|
self.h = curses.LINES - 1
|
||||||
self.w = curses.COLS - int((curses.COLS - 1) * p)
|
self.w = curses.COLS - int((curses.COLS - 1) * p)
|
||||||
logger.info('msgs view width: %s', self.w)
|
self.x = curses.COLS - self.w
|
||||||
self.s = curses.COLS - self.w
|
|
||||||
|
|
||||||
self.win = self.stdscr.subwin(self.h, self.w, 0, self.s)
|
# if self.win is None:
|
||||||
self.win.mvwin(0, self.s)
|
self.win = self.stdscr.subwin(self.h, self.w, 0, self.x)
|
||||||
self.win.resize(self.h, self.w)
|
# else:
|
||||||
|
# self.win.resize(self.h, self.w)
|
||||||
|
# self.win.mvwin(0, self.x)
|
||||||
|
|
||||||
def draw(self, current, msgs):
|
def draw(self, current, msgs):
|
||||||
logger.info('Dwaring msgs')
|
logger.info('Dwaring msgs')
|
||||||
|
@ -183,14 +227,3 @@ def parse_content(content):
|
||||||
else:
|
else:
|
||||||
logger.debug('Unknown content: %s', content)
|
logger.debug('Unknown content: %s', content)
|
||||||
return f'[unknown type {_type}]'
|
return f'[unknown type {_type}]'
|
||||||
|
|
||||||
|
|
||||||
emoji_pattern = re.compile(
|
|
||||||
"["
|
|
||||||
"\U0001F600-\U0001F64F" # emoticons
|
|
||||||
"\U0001F300-\U0001F5FF" # symbols & pictographs
|
|
||||||
"\U0001F680-\U0001F6FF" # transport & map symbols
|
|
||||||
"\U0001F1E0-\U0001F1FF" # flags (iOS)
|
|
||||||
"]+",
|
|
||||||
flags=re.UNICODE
|
|
||||||
)
|
|
||||||
|
|
Loading…
Reference in a new issue