Esempio n. 1
0
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)
Esempio n. 2
0
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)
Esempio n. 3
0
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)
Esempio n. 4
0
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