#! /usr/bin/python3 # Copyright (C) 2018-2019 Merspieler, merspieler _at_ airmail.cc # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import socket import sys import json import os import re host = socket.gethostname() port = 12345 verbose = False sfile = "projects/worldbuild/status" argc = len(sys.argv) i = 1 while i < argc: if sys.argv[i] == "--port": i += 1 port = int(sys.argv[i]) elif sys.argv[i] == "--host": i += 1 host = sys.argv[i] elif sys.argv[i] == "-v": verbose = True elif sys.argv[i] == "-f" or sys.argv[i] == "--file": i += 1 sfile = sys.argv[i] elif sys.argv[i] == "-h" or sys.argv[i] == "--help": print("usage: wb-progress-logger.py [OPTIONS]") print("Logs progress of the worldbuild when run") print("with database strategies 'chunk' and 'mono'") print("") print("OPTIONS") # print(" -f, --file Status file to use") print(" -v, --verbose Verbose printouts") print(" , --host hostname or interface to bind to") print(" , --port Port to bind to") print(" -h, --help Shows this help and exit") else: print("Unknown option " + sys.argv[i]) sys.exit(1) i += 1 def norm(num, length): num = str(num) while len(num) < length: num = "0" + num return num if os.path.isfile(sfile): try: with open(sfile) as json_data: state = json.load(json_data) except ValueError: print("ERROR: Invalid status file") sys.exit(1) else: state = {} sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind((host, port)) sock.listen(5) print("Up and running...") try: while True: try: c, addr = sock.accept() msg = c.recv(128) c.close() name, status = msg.decode().split() if verbose: print(name + " set status to " + status) if status == "started" or status == "done": if name == "n-pole" or name == "s-pole": if not name in state: state[name] = {} state[name]["status"] = status else: match = re.match(r"([ew])(\d{3})([ns])(\d{2})", name) if match == None: print("WARNING: Recived status " + status + " from invalid tile '" + name + "'") else: ew = match.group(1) ew_val = int(match.group(2)) ns = match.group(3) ns_val = int(match.group(4)) ew_val_major = int(ew_val / 10) * 10 if ew == "w": if ew_val_major != ew_val: ew_val_major += 10 ns_val_major = int(ns_val / 10) * 10 if ns == "s": if ns_val_major != ns_val: ns_val_major += 10 name_major = ew + norm(ew_val_major, 3) + ns + norm(ns_val_major, 2) if not name_major in state: state[name_major] = {} if not name in state[name_major]: state[name_major][name] = {} state[name_major][name]["status"] = status state[name_major]["done"] = 0 state[name_major]["started"] = 0 for tile in state[name_major]: # Filter status of name_major if tile != "done" and tile != "started" and tile != "pending" and tile != "status" and tile != "rebuild": state[name_major][state[name_major][tile]["status"]] += 1 if state[name_major]["done"] == 100: state[name_major]["status"] = "done" elif state[name_major]["started"] > 0: state[name_major]["status"] = "started" else: state[name_major]["status"] = "pending" try: with open(sfile, 'w') as f: json.dump(state, f, indent=4) except IOError: print("WARNING: Failed to write to file") else: print("WARNING: Invalid status '" + status + "' recived from " + name) except IOError: print("WARNING: Recived invalid package") except KeyboardInterrupt: try: with open(sfile, 'w') as f: json.dump(state, f, indent=4) except IOError: print("WARNING: Failed to write to file") sock.close() print("Exiting...") sys.exit(0)