-
-
Save cspiegel/48794734d41a2c17f53adf50a418d1e1 to your computer and use it in GitHub Desktop.
Convert fdo XML to Haiku resources
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
resource(0, "BEOS:TYPE") #'MIMS' "application/x-vnd.Be-meta-mime"; | |
resource(1, "META:TYPE") "application/x-adrift"; | |
resource(2, "META:SNIFF_RULE") #'MSIG' "0.50 (\"\\074\\102\\077\\311\\152\\207\\302\\317\")"; | |
resource(3, "META:S:DESC") #'MDSC' "Adrift game data"; | |
resource(4, "META:EXTENS") message(234) { | |
"extensions" = "taf", | |
"type" = "application/x-adrift" | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
resource(0, "BEOS:TYPE") #'MIMS' "application/x-vnd.Be-meta-mime"; | |
resource(1, "META:TYPE") "application/x-blorb"; | |
resource(2, "META:SNIFF_RULE") #'MSIG' "0.50 (\"FORM\")([8] \"IFRS\")"; | |
resource(3, "META:S:DESC") #'MDSC' "Blorb interactive fiction data"; | |
resource(4, "META:EXTENS") message(234) { | |
"extensions" = "blb", | |
"extensions" = "blorb", | |
"extensions" = "gblorb", | |
"extensions" = "glb", | |
"extensions" = "zblorb", | |
"extensions" = "zlb", | |
"type" = "application/x-blorb" | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
resource(0, "BEOS:TYPE") #'MIMS' "application/x-vnd.Be-meta-mime"; | |
resource(1, "META:TYPE") "application/x-zmachine"; | |
resource(2, "META:S:DESC") #'MDSC' "Z-machine game data"; | |
resource(3, "META:EXTENS") message(234) { | |
"extensions" = "z1", | |
"extensions" = "z2", | |
"extensions" = "z3", | |
"extensions" = "z4", | |
"extensions" = "z5", | |
"extensions" = "z6", | |
"extensions" = "z7", | |
"extensions" = "z8", | |
"type" = "application/x-zmachine" | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
from typing import Dict, Any | |
import re | |
import sys | |
import xmltodict | |
class Error(Exception): pass | |
with open(sys.argv[1]) as f: | |
d = xmltodict.parse(f.read()) | |
def process_mime_type(mt: Dict[str, Any], mimetype: str): | |
resources = { | |
"BEOS:TYPE": "#'MIMS' \"application/x-vnd.Be-meta-mime\";", | |
"META:TYPE": f"\"{mimetype}\";", | |
} | |
try: | |
magic = mt["magic"] | |
if not isinstance(magic, dict): | |
raise Error("Multiple matches not supported") | |
match = magic["match"] | |
priority = float(magic["@priority"]) | |
except KeyError: | |
pass | |
else: | |
priority /= 100.0 | |
# Matches can be nested to be additive so use a recursive function. | |
def handle_match(match): | |
if not isinstance(match, dict): | |
raise Error("Sum matches not supported") | |
offset = match["@offset"] | |
value = match["@value"] | |
offstr = "" | |
if offset != "0": | |
offstr = f"[{offset}] " | |
# Replace hex escapes with octal (is hex supported?) | |
def replace(match): | |
byte = int(match.group(1), 16) | |
return f"\\\\{byte:03o}" | |
value = re.sub(r"\\x([0-9a-fA-F][0-9a-fA-F])", replace, value) | |
string = f"({offstr}\\\"{value}\\\")" | |
try: | |
string += handle_match(match["match"]) | |
except KeyError: | |
pass | |
return string | |
matchstr = handle_match(match) | |
resources["META:SNIFF_RULE"] = f"#'MSIG' \"{priority:.2f} {matchstr}\";" | |
try: | |
# There can be comments in various languages; those with lang | |
# attributes are dicts, so filter them out, then pick the first | |
# value from the result, if any. | |
comments = mt["comment"] | |
if isinstance(comments, str): | |
comments = [comments] | |
comment = next(comment for comment in comments if isinstance(comment, str)) | |
except (KeyError, StopIteration): | |
pass | |
else: | |
resources["META:S:DESC"] = f"#'MDSC' \"{comment}\";" | |
try: | |
globs = mt["glob"] | |
except KeyError: | |
pass | |
else: | |
if isinstance(globs, dict): | |
globs = [globs] | |
globs = [glob["@pattern"][2:] for glob in globs] | |
# Hack for Z-machine | |
if globs == ["z[1-8]"]: | |
globs = [f"z{v}" for v in range(1, 9)] | |
extensions = "\n".join(f" \"extensions\" = \"{glob}\"," for glob in globs) | |
resources["META:EXTENS"] = f"""message(234) {{ | |
{extensions} | |
"type" = "{mimetype}" | |
}};""" | |
with open(f"MIME/{re.sub('/', '-', mimetype)}", "w") as f: | |
for (i, (name, value)) in enumerate(resources.items()): | |
f.write(f"resource({i}, \"{name}\") {value}\n\n") | |
for mt in d["mime-info"]["mime-type"]: | |
try: | |
mimetype = mt["@type"] | |
except KeyError: | |
print("No MIME type given") | |
continue | |
try: | |
process_mime_type(mt, mimetype) | |
except Error as e: | |
print(f"Can't handle match for {mimetype}: {e}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment