From 870da15418b46c059bbb8aeb5684db5c10d842ae Mon Sep 17 00:00:00 2001 From: Marius Merschformann Date: Thu, 5 Dec 2024 01:33:12 +0100 Subject: [PATCH] Improve compatibility of CLI entrypoint, adding quick and dirty xinst to json conversion script --- Material/Scripts/convert.py | 64 +++++++++++++++++++++++++++++++++++++ SC.CLI/Program.cs | 22 +++++++++++-- 2 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 Material/Scripts/convert.py diff --git a/Material/Scripts/convert.py b/Material/Scripts/convert.py new file mode 100644 index 0000000..a3ab5cd --- /dev/null +++ b/Material/Scripts/convert.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python + +# This script converts old .xinst files into the new .json input format. +# It only supports the basics, thus, only works for basic inputs. + +import argparse +import json +import xml.etree.ElementTree as ET + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser() + parser.add_argument("--input", "-i", required=True, help="Input .xinst file") + parser.add_argument("--output", "-o", required=True, help="Output .json file") + return parser.parse_args() + + +def convert(input_file: str, output_file: str) -> None: + tree = ET.parse(input_file) + root = tree.getroot() + + # Convert the XML nodes to dictionaries + containers = [] + for container in root.findall(".//Container"): + container_dict = { + "id": int(container.get("ID")), + "length": float(container.find("Cube").get("Length")), + "width": float(container.find("Cube").get("Width")), + "height": float(container.find("Cube").get("Height")), + "maxWeight": float(container.get("MaxWeight") or 0), + } + containers.append(container_dict) + pieces = [] + for piece in root.findall(".//Piece"): + piece_dict = { + "id": int(piece.get("ID")), + "weight": float(piece.get("Weight") or 0), + "cubes": [ + { + "x": float(cube.find("Point").get("X")), + "y": float(cube.find("Point").get("Y")), + "z": float(cube.find("Point").get("Z")), + "length": float(cube.get("Length")), + "width": float(cube.get("Width")), + "height": float(cube.get("Height")), + } + for cube in piece.findall(".//Cube") + ], + } + pieces.append(piece_dict) + + # Combine and write data + data = {"containers": containers, "pieces": pieces} + with open(output_file, "w") as f: + json.dump(data, f, indent=4) + + +def main() -> None: + args = parse_args() + convert(args.input, args.output) + + +if __name__ == "__main__": + main() diff --git a/SC.CLI/Program.cs b/SC.CLI/Program.cs index eee6f82..f90a5c5 100644 --- a/SC.CLI/Program.cs +++ b/SC.CLI/Program.cs @@ -29,8 +29,26 @@ private static void Main(string[] args) private static void Execute(Options opts) { - // Read input file (either from file or from stdin) - var instance = JsonIO.From(string.IsNullOrWhiteSpace(opts.Input) ? Console.In.ReadToEnd() : File.ReadAllText(opts.Input)); + // Read the content fully first (either from file or from stdin) + var content = string.IsNullOrWhiteSpace(opts.Input) ? Console.In.ReadToEnd() : File.ReadAllText(opts.Input); + + // Try to parse the input as a calculation + var instance = JsonIO.From(content); + + // If nothing useful was found, try to parse it as an unnested instance (without a configuration) + if (instance == null || instance.Instance == null && instance.Configuration == null) + { + var inst = JsonIO.From(content); + if (inst != null) + instance = new JsonCalculation() { Instance = inst }; + } + + // If still nothing useful was found, abort + if (instance == null || instance.Instance == null) + { + Console.WriteLine("No 'instance' found in input file."); + return; + } // >> Run calculation Action logger = string.IsNullOrWhiteSpace(opts.Output) ? null : Console.Write;