misc/python/pychat.py
2018-08-05 18:53:07 +02:00

122 lines
2.8 KiB
Python
Executable File

#!/usr/bin/env nix-script
#!>python3
## write to a file in a chat-like fashion
import subprocess
import time
import threading
import readline
import sys
import os
def sprint(*args, **kwargs):
'''
Safe print
Write automagically to stdout while reading
from stdin without mixing any text.
'''
line_length = len(readline.get_line_buffer())+2
sys.stdout.write('\r' + ' ' * line_length +'\r')
print(*args, **kwargs)
sys.stdout.write(prompt() + readline.get_line_buffer())
sys.stdout.flush()
def clear():
'''Clear the screen'''
cmd = 'cls' if sys.platform == 'win32' else "clear && printf '\e[3J'"
subprocess.call(cmd, shell=True)
def terminal_size():
'''Get size of terminal window (lines, columns)'''
def ioctl_GWINSZ(fd):
try:
import fcntl, termios, struct, os
cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
'1234'))
except:
return
return cr
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
if not cr:
try:
fd = os.open(os.ctermid(), os.O_RDONLY)
cr = ioctl_GWINSZ(fd)
os.close(fd)
except:
pass
if not cr:
env = os.environ
cr = (env.get('LINES', 25), env.get('COLUMNS', 80))
return list(map(int, cr))
def timestamp(message):
'''Add timestamp to a message'''
stamp = time.strftime('%d.%m.%y - %H:%M:%S')
return '{} {}: {}\n'.format(stamp, username, message)
def update():
'''Keep the console output updated'''
global previous
while True:
time.sleep(0.1)
file.seek(0)
current = file.read()
if current == previous:
pass
else:
clear()
sprint(current)
previous = current
def read():
'''Prompt user for input'''
global previous
global username
text = input(prompt())
if text.startswith('/'):
command = text[1:].split()
if command[0] == 'quit':
sys.exit()
elif command[0] == 'setname':
username = ' '.join(command[1:])
elif command[0] == 'clear':
file.seek(0)
file.truncate()
clear()
elif text != '':
file.write(timestamp(text))
file.write('\n')
else:
previous=file.read()
mod = lambda x: (0 if x<0 else x)
previous = ''
username = 'Michele'
chat_size = lambda: sum(1 for _ in open('log.txt'))
offset = lambda: '\n' * mod(terminal_size()[0] - chat_size() - 2)
prompt = lambda: offset() + username + '>> '
file = open('log.txt', 'a+')
thread = threading.Thread(target=update, daemon=True)
if __name__ == '__main__':
try:
thread.start()
clear()
while True:
read()
except KeyboardInterrupt:
print()