def main(args=tuple(sys.argv[1:])): """args: sequence of command line argument strings""" parser = build_argparser() parsed_args = parser.parse_args(args) # get all input paths, or exit with an error if there aren't any all_inpaths = glob_all(parsed_args.input_imxfiles) argparse_exit_if_no_paths(all_inpaths, progname=parser.prog) # create outdir if it doesn't exist (now that we know we have at least 1 input file) outdir = parsed_args.directory if outdir: os.makedirs(outdir, exist_ok=True) # process all input paths for inpath in all_inpaths: # print first part of the verbose message if parsed_args.verbose: print(f"converting {inpath!r} -> ", end="") with open(inpath, "rb") as imxfile: pixfmt = fast_imx_pixfmt(imxfile) newext = f"{_d}{pixfmt}{PNG_EXT}" outname = replaceext(os.path.basename(inpath), newext) outpath = os.path.join(outdir, outname) # print rest of the verbose message, now that we know outpath if parsed_args.verbose: print(f"{outpath!r}") imximage = read_imx(imxfile) write_to_png(imximage, outpath)
def read_toml(tomlpath: AnyStr) -> XgmContainer: """read an XgmContainer from a toml file and its content files :param tomlpath: path to the toml file :return: XgmContainer instance read from tomlpath """ tomldir = os.path.dirname(tomlpath) with open(tomlpath, "rt", encoding="utf-8") as tomlfile: tomldoc = tomlkit.parse(tomlfile.read()) if not ("ImageItem" in tomldoc or "ModelItem" in tomldoc): return XgmContainer([], []) imageitems = [] for tomlimage in tomldoc["ImageItem"]: # 1. read ImageItem info from TOML name16 = tomlimage["name16"] filepath = tomlimage.get("file-path") if filepath is None: filepath = name16 # 2. read file data with open(os.path.join(tomldir, filepath), "rb") as itemfile: filedata = itemfile.read() # 3. Convert to XgmImageItem imageitems.append(XgmImageItem(name16, filedata)) modelitems = [] for tomlmodel in tomldoc["ModelItem"]: # 1. read ImageItem info from TOML name16 = tomlmodel["name16"] filepath = tomlmodel.get("file-path") if filepath is None: filepath = name16 animseppath = tomlmodel.get("animsep-path") if animseppath is None: animseppath = replaceext(filepath, ANIMSEP_EXT) # 2. read file data with open(os.path.join(tomldir, filepath), "rb") as itemfile: filedata = itemfile.read() with open(os.path.join(tomldir, animseppath), "rb") as animsepfile: animsepdata = animsepfile.read() # 3. Convert to XgmModelItem modelitems.append(XgmModelItem(name16, filedata, animsepdata)) return XgmContainer(imageitems, modelitems)
def main(args=tuple(sys.argv[1:])): """args: sequence of command line argument strings""" parser = build_argparser() parsed_args = parser.parse_args(args) # get all input paths, convert all dirs to *.XGM.toml paths if they contain any all_inpaths = glob_all(parsed_args.input_paths) all_inpaths_toml = glob_all_dirs_to_wildcards(all_inpaths, XGMTOML_EXT_GLOB) # or exit with an error if there aren't any matching paths errormessage = ( f"error: No {XGMTOML_EXT} files to process. You may have specified directories " "that don't contain any, or a wildcard that doesn't match any.") argparse_exit_if_no_paths(all_inpaths_toml, progname=parser.prog, errormessage=errormessage) # create outdir if it doesn't exist (now that we know we have at least 1 input file) outdir = parsed_args.directory if outdir: os.makedirs(outdir, exist_ok=True) if parsed_args.verbose: # noinspection PyUnusedLocal def verbosefunc(contentsidx, num_contents, contentfile): print(f" {contentfile.name16!r} ->") else: verbosefunc = None # process all input paths for inpath in all_inpaths_toml: # goal: in.XGM.toml -> in.XGM output_name = replaceext(os.path.basename(inpath), XGM_EXT, XGMTOML_EXT) output_path = os.path.join(outdir, output_name) # pack XGM container file if parsed_args.verbose: print(f"packing {inpath!r} -> {output_path!r}") xgm = read_toml(inpath) write_xgm(xgm, output_path, progressfunc=verbosefunc)
def write_toml( xgm: XgmContainer, output_dirpath: str, output_tomlbase: str, progressfunc: Callable = None, ) -> None: """write an XgmContainer to a plaintext toml file and extracted contents :param xgm: XgmContainer instance :param output_dirpath: new directory to create and to unpack XGM contents to :param output_tomlbase: base filename to which to write the .XGM.toml file (will be put in output_dirpath) :param progressfunc: function to run whenever an item of the XgmContainer is about to be processed. It must accept three arguments: an int item index, an int total number of items, and an xgmitem.XgmImageItem/XgmModelItem instance """ # prepare toml dir and toml file. writing a bit early here, but if dir/file can't be # written, it's better to error before the time-consuming part instead of after tomldir = output_dirpath tomlpath = os.path.join(tomldir, output_tomlbase) os.makedirs(tomldir, exist_ok=True) num_imageitems, num_modelitems = len(xgm.imageitems), len(xgm.modelitems) with open(tomlpath, "wt", encoding="utf-8") as tomlfile: try: tomldoc = tomlkit.parse(_toml_header) tomldoc.add("ImageItem", tomlkit.aot()) for idx, imageitem in enumerate(xgm.imageitems): if progressfunc is not None: progressfunc(idx, num_imageitems, imageitem) # Extract image item to file imageitem_outname = imageitem.name16.replace(os.path.sep, "_") # sanitize with open(os.path.join(tomldir, imageitem_outname), "wb") as itemfile: itemfile.write(imageitem.filedata) # Gather & add this image item's info to toml document tomlimage = tomlkit.table() tomlimage["name16"] = imageitem.name16 if imageitem_outname != imageitem.name16: tomlimage["file-path"] = imageitem_outname # noinspection PyArgumentList tomldoc["ImageItem"].append(tomlimage) if xgm.modelitems: tomldoc.add(tomlkit.nl()) tomldoc.add("ModelItem", tomlkit.aot()) for idx, modelitem in enumerate(xgm.modelitems): if progressfunc is not None: progressfunc(idx, num_modelitems, modelitem) # Extract model item to file modelitem_outname = modelitem.name16.replace(os.path.sep, "_") # sanitize with open(os.path.join(tomldir, modelitem_outname), "wb") as itemfile: itemfile.write(modelitem.filedata) # Extract animation entry data to file animsep_outname = replaceext(modelitem_outname, ANIMSEP_EXT) with open(os.path.join(tomldir, animsep_outname), "wb") as animsepfile: animsepfile.write(modelitem.animdata) # Gather & add this model item's info to toml document tomlmodel = tomlkit.table() tomlmodel["name16"] = modelitem.name16 if modelitem_outname != modelitem.name16: tomlimage["file-path"] = modelitem_outname # noinspection PyArgumentList tomldoc["ModelItem"].append(tomlmodel) tomlfile.write(tomldoc.as_string()) except Exception: # noinspection PyBroadException try: # For debug output, try to write current tomldoc + error traceback import traceback tb = traceback.format_exc() tomlfile.write(tomldoc.as_string()) tomlfile.write( "\n\n# == ERROR ENCOUNTERED DURING WRITING ==\n#") tomlfile.write("\n#".join(tb.split("\n"))) except Exception: pass raise