147 lines
4.4 KiB
Python
147 lines
4.4 KiB
Python
#!/usr/bin/env python3
|
|
|
|
from textwrap import TextWrapper as wrap
|
|
from threading import Thread
|
|
import signal
|
|
from time import sleep, time
|
|
import os.path as path
|
|
from os.path import getmtime as gt
|
|
import curses
|
|
from curses import wrapper
|
|
import curses.textpad as textpad
|
|
import sys
|
|
import re
|
|
|
|
|
|
class Viewport:
|
|
def __init__(self, screen):
|
|
curses.curs_set(0)
|
|
self.user_path = path.expanduser('~')
|
|
self.username = path.split(self.user_path)[-1]
|
|
self.screen = screen
|
|
self.width = curses.COLS - 1
|
|
self.height = curses.LINES - 1
|
|
self.last_update = 0.0
|
|
self.last_msg = ''
|
|
self.update = False
|
|
self.path = '/home/sloum/Documents/code/python/colorchat/chatlog'
|
|
self.screen.nodelay(True)
|
|
self.screen.clear()
|
|
self.c_out = self.screen.subwin(self.height - 3, self.width,0,0)
|
|
self.c_in = self.screen.subwin(3,self.width,self.height - 3,0)
|
|
self.text_buffer = ''
|
|
self.watcher = Thread(target=self.watch, args=(self.path,), daemon=True)
|
|
self.main()
|
|
|
|
|
|
def main(self):
|
|
self.watcher.start()
|
|
while True:
|
|
self.text_input()
|
|
if self.update:
|
|
self.flash_log()
|
|
self.update = False
|
|
sleep(0.05)
|
|
|
|
|
|
def watch(self,filepath):
|
|
while True:
|
|
filetime = gt(filepath)
|
|
elapsedtime = self.elapsed_time(filetime)
|
|
if elapsedtime:
|
|
self.last_msg = elapsedtime
|
|
if filetime > self.last_update:
|
|
self.last_update = filetime
|
|
self.update = True
|
|
else:
|
|
self.update = False
|
|
sleep(0.5)
|
|
|
|
|
|
def flash_log(self):
|
|
with open(self.path, 'r') as f:
|
|
temp = f.read()
|
|
temp_list = self.wrap_text(temp)
|
|
rows = len(temp_list)
|
|
max_rows = self.height - 2
|
|
self.c_out.erase()
|
|
self.c_out.hline(0,0,'.',self.width)
|
|
title = '_colorchat_'
|
|
position = self.width // 2 - len(title) // 2
|
|
self.c_out.addstr(0,position,title)
|
|
if rows < max_rows:
|
|
for x in range(rows - 1):
|
|
self.c_out.addstr(max_rows - rows + x, 0, temp_list[x])
|
|
else:
|
|
counter = 1
|
|
for x in temp_list[-(max_rows-2):]:
|
|
self.c_out.addstr(counter, 0, x)
|
|
counter += 1
|
|
self.c_out.refresh()
|
|
|
|
|
|
# takes in a string and outputs a list of strings
|
|
def wrap_text(self, string):
|
|
ob = wrap(width=self.width - 2, tabsize=4, replace_whitespace=False)
|
|
text = [ob.fill(x) for x in string.split('\n')]
|
|
text = '\n'.join(text).split('\n')
|
|
return text
|
|
|
|
|
|
def text_input(self):
|
|
self.c_in.erase()
|
|
c = self.screen.getch()
|
|
if c in (curses.KEY_ENTER, 10, 13):
|
|
self.send_msg()
|
|
elif c == curses.KEY_BACKSPACE:
|
|
if len(self.text_buffer) > 0:
|
|
self.text_buffer = self.text_buffer[:-1]
|
|
elif c != -1 and not c in [curses.KEY_UP, curses.KEY_LEFT, curses.KEY_DOWN, curses.KEY_RIGHT]:
|
|
character = chr(c)
|
|
if re.match(r'^[\S ]+$',character):
|
|
self.text_buffer += chr(c)
|
|
self.c_in.hline(0,0,'-',self.width)
|
|
self.c_in.addstr(1,1,self.text_buffer[-(self.width * 2 - 10):] + '_')
|
|
self.c_in.addstr(2,self.width - 1 - len(self.last_msg),self.last_msg)
|
|
self.c_in.refresh()
|
|
|
|
|
|
def send_msg(self):
|
|
if self.text_buffer in ['q','quit','exit']:
|
|
sys.exit(0)
|
|
|
|
with open(self.path, 'a') as f:
|
|
f.write('{} > {}\n'.format(self.username,self.text_buffer))
|
|
self.text_buffer = ''
|
|
|
|
|
|
def elapsed_time(self,last_time):
|
|
if not last_time:
|
|
return False
|
|
current = time()
|
|
elapsed = int(current - last_time)
|
|
unit = 's'
|
|
if elapsed >= 60:
|
|
elapsed = elapsed // 60
|
|
unit = 'm'
|
|
if elapsed >= 60:
|
|
elapsed = elapsed // 60
|
|
unit = 'h'
|
|
if elapsed >= 24:
|
|
elapsed = elapsed // 24
|
|
unit = 'd'
|
|
return 'Time since last post: {}{}'.format(elapsed,unit)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
signal.signal(signal.SIGINT,signal.SIG_IGN)
|
|
try:
|
|
wrapper(Viewport)
|
|
except KeyboardInterrupt:
|
|
curses.echo()
|
|
curses.nocbreak()
|
|
curses.endwin()
|
|
finally:
|
|
sys.exit(1)
|
|
|