122 lines
2.8 KiB
Python
Executable File
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()
|