Fix incorrect window resizing

Add sending message functionality
This commit is contained in:
Paul Nameless 2019-02-18 16:09:42 +01:00
parent 473f96902f
commit d03866f0e3
4 changed files with 110 additions and 104 deletions

View file

@ -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}'
)

View file

@ -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
View 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
View file

@ -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
)