diff --git a/scripts/killswitch_test.py b/scripts/killswitch_test.py new file mode 100644 index 00000000..314e3344 --- /dev/null +++ b/scripts/killswitch_test.py @@ -0,0 +1,125 @@ +"""Print information about killswitch json files.""" +import json +import sys + +# Yes this is gross. No I cant fix it. EDMC doesn't use python modules currently and changing that would be messy. +sys.path.append('.') +from killswitch import KillSwitchSet, SingleKill, parse_kill_switches # noqa: E402 + +KNOWN_KILLSWITCH_NAMES: list[str] = [ + # edsm + 'plugins.edsm.worker', + 'plugins.edsm.worker.$event', + 'plugins.edsm.journal', + 'plugins.edsm.journal.event.$event', + + # inara + 'plugins.inara.journal', + 'plugins.inara.journal.event.$event', + 'plugins.inara.worker', + 'plugins.inara.worker.$event', + + # eddn + 'plugins.eddn.send', + 'plugins.eddn.journal', + 'plugins.eddn.journal.event.$event', + + # eddb + 'plugins.eddb.journal', + 'plugins.eddb.journal.event.$event' +] + +SPLIT_KNOWN_NAMES = list(map(lambda x: x.split('.'), KNOWN_KILLSWITCH_NAMES)) + + +def match_exists(match: str) -> tuple[bool, str]: + """Check that a match matching the above defined known list exists.""" + split_match = match.split('.') + highest_match = 0 + closest = [] + + for known_split in SPLIT_KNOWN_NAMES: + if len(known_split) != len(split_match): + continue # couldn't possibly match this + + if known_split == split_match: + return True, "" + + matched_fields = sum(len(k) for k, s in zip(known_split, split_match) if k == s or k[0] == '$') + if highest_match < matched_fields: + matched_fields = highest_match + closest = list(known_split) + + if matched_fields == len(known_split): + return True, "" + + return False, ".".join(closest) + + +def show_killswitch_set_info(ks: KillSwitchSet) -> None: + """Show information about the given KillSwitchSet.""" + for kill_version in ks.kill_switches: + print(f'Kills matching version mask {kill_version.version}') + for kill in kill_version.kills.values(): + print_singlekill_info(kill) + + +def print_singlekill_info(s: SingleKill): + """Print info about a single SingleKill instance.""" + ok, closest_match = match_exists(s.match) + if ok: + print(f'\t- {s.match}') + + else: + print( + f'\t- {s.match} -- Does not match existing killswitches! ' + f'Typo or out of date script? (closest: {closest_match!r})' + ) + + print(f'\t\tReason specified is: {s.reason!r}') + print() + + if not s.has_rules: + print(f'\t\tDoes not set, redact, or delete fields. This will always stop execution for {s.match}') + return + + print(f'\t\tThe folowing changes are required for {s.match} execution to continue') + if s.set_fields: + max_field_len = max(len(f) for f in s.set_fields) + 3 + print(f'\t\tSets {len(s.set_fields)} fields:') + for f, c in s.set_fields.items(): + print(f'\t\t\t- {f.ljust(max_field_len)} -> {c}') + + print() + + if s.redact_fields: + max_field_len = max(len(f) for f in s.redact_fields) + 3 + print(f'\t\tRedacts {len(s.redact_fields)} fields:') + for f in s.redact_fields: + print(f'\t\t\t- {f.ljust(max_field_len)} -> "REDACTED"') + + print() + + if s.delete_fields: + print(f'\t\tDeletes {len(s.delete_fields)} fields:') + for f in s.delete_fields: + print(f'\t\t\t- {f}') + + print() + + +if __name__ == '__main__': + if len(sys.argv) == 1: + print("killswitch_test.py [file or - for stdin]") + sys.exit(1) + + file_name = sys.argv[1] + if file_name == '-': + file = sys.stdin + else: + file = open(file_name) + + res = json.load(file) + file.close() + + show_killswitch_set_info(KillSwitchSet(parse_kill_switches(res)))