#!/usr/bin/env -S python3 -u # Note that running python with the `-u` flag is required on Windows, # in order to ensure that stdin and stdout are opened in binary, rather # than text, mode. import sys import json import struct import subprocess import os import logging # Read a message from stdin and decode it. def getMessage(): rawLength = sys.stdin.buffer.read(4) if len(rawLength) == 0: sys.exit(0) messageLength = struct.unpack('@I', rawLength)[0] message = sys.stdin.buffer.read(messageLength).decode('utf-8') return json.loads(message) # Encode a message for transmission, # given its content. def encodeMessage(messageContent): # https://docs.python.org/3/library/json.html#basic-usage # To get the most compact JSON representation, you should specify # (',', ':') to eliminate whitespace. # We want the most compact representation because the browser rejects # messages that exceed 1 MB. encodedContent = json.dumps(messageContent, separators=(',', ':')).encode('utf-8') encodedLength = struct.pack('@I', len(encodedContent)) return {'length': encodedLength, 'content': encodedContent} # Send an encoded message to stdout def sendMessage(encodedMessage): sys.stdout.buffer.write(encodedMessage['length']) sys.stdout.buffer.write(encodedMessage['content']) sys.stdout.buffer.flush() counter = 0 logging.basicConfig(filename="/tmp/librejs.log", filemode='a', format='%(asctime)s.%(msecs)d %(name)s %(levelname)s %(message)s', datefmt='%H:%M:%S', level=logging.DEBUG) while True: receivedMessage = getMessage() devnull = open(os.devnull, 'w') counter += 1 logging.info(f'[{counter}] {receivedMessage}') sendMessage(encodeMessage(f'Logged message No. {counter}'))