#!/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()