Exemplo n.º 1
0
 def OnDump(self, event):
     item = self.listCtrl.GetFocusedItem()
     prgname = self.listCtrl.GetItemText(item, col=1)
     print(f"{prgname}")
     patchdata = self.zipobj.read(self.proglist[item])
     print(common.flavour_to_product[common.patch_type(patchdata)] + " patch")
     dump.print_patch(patchdata)
     print_sep()
Exemplo n.º 2
0
def print_patch(patchdata):
    import copy

    patch = common.parse_patchdata(patchdata)
    if common.patch_type(patchdata) == "og":
        patch = og.normalise_og_patch(patch)

    patchcopy = copy.deepcopy(vars(patch))
    for key in patchcopy:
        val = patchcopy[key]
        if isinstance(val, (bytes, bytearray)) and len(val) > 12:
            patchcopy[key] = val.hex()
    pprint(patchcopy)
Exemplo n.º 3
0
 def LoadData(self, fileobj):
     self.zipobj = ZipFile(fileobj.name, "r", compression=ZIP_DEFLATED, compresslevel=9)
     self.proglist = common.zipread_progbins(self.zipobj)
     lc = self.listCtrl
     lc.ClearAll()
     lc.AppendColumn("id")
     lc.AppendColumn("name")
     lc.AppendColumn("md5:4")
     lc.SetColumnWidth(0, 40)
     lc.SetColumnWidth(1, 200)
     lc.SetColumnWidth(2, 50)
     for i, p in enumerate(self.proglist):
         patchdata = self.zipobj.read(p)
         hash = hashlib.md5(patchdata).hexdigest()
         flavour = common.patch_type(patchdata)
         if not common.is_init_patch(flavour, hash):
             prgname = common.program_name(patchdata, flavour)
             lc.Append([i+1, prgname, hash[:4]])
Exemplo n.º 4
0
def dump(filename, match_name, match_ident, verbose, md5):
    """Dump contents of FILENAME to stdout. Supports minilogue og and xd patch files.

    \b
    Examples
    --------
    dump og_program_bank.mnlgpreset
    dump xd_program_bank.mnlgxdlib
    dump OGProgName.mnlgprog
    dump XDProgName.mnlgxdprog
    dump -n OGProgName og_program_bank.mnlgpreset
    dump -n "OG Prog Name" og_program_bank.mnlgpreset
    dump -i 10 og_program_bank.mnlgpreset
    dump -i 10 -m og_program_bank.mnlgpreset

    """
    zipobj = zipfile.ZipFile(filename, "r")
    proglist = common.zipread_progbins(zipobj)

    if match_name is not None:
        match_ident = common.id_from_name(zipobj, match_name)

    if match_ident is not None:
        proglist = [proglist[match_ident - 1]]

    for p in proglist:
        patchdata = zipobj.read(p)
        flavour = common.patch_type(patchdata)
        prgname = common.program_name(patchdata, flavour)
        if common.is_init_program_name(prgname):
            continue
        checksum = ""
        if md5:
            checksum = hashlib.md5(patchdata).hexdigest()
        print(f"{int(p[5:8])+1:03d}: {prgname:12s} {checksum}")
        if verbose:
            print_patch(patchdata)
            print()
Exemplo n.º 5
0
def translate(filename, match_name, match_ident, verbose, unskip_init, force_preset):
    """Translate a minilogue program or program bank to the minilogue xd.

    \b
    Examples
    --------
    translate og_program_bank.mnlgpreset
    translate -n OGProgName og_program_bank.mnlgpreset
    translate -n "OG Prog Name" og_program_bank.mnlgpreset
    translate OGProgName.mnlgprog

    """
    input_file = pathlib.Path(filename)
    assert input_file.suffix in {
        ".mnlgprog", ".mnlgpreset", ".mnlglib",
        ".prlgprog", ".prlgpreset", ".prlglib",
        ".molgprog", ".molgpreset", ".molglib",
        ".mnlgxdpreset", ".mnlgxdlib",
        ".syx"
    }

    if input_file.suffix != ".syx":
        out_flavour = "xd"
        zipobj = ZipFile(filename, "r", compression=ZIP_DEFLATED, compresslevel=9)
        proglist = common.zipread_progbins(zipobj)

    if input_file.suffix in {".mnlgprog", ".syx"}:
        # single patch/program
        match_name = input_file
        match_ident = 1
    elif match_name is not None:
        # patch library/program pack
        match_ident = common.id_from_name(zipobj, match_name)

    if input_file.suffix == ".syx":
        stem = input_file.stem
        proglist = ["Prog_000.prog_bin"]
        out_flavour, patchdata = convert_from_syx(input_file)
        patch_ext = {
            "monologue":".molgprog",
            "xd":".mnlgxdprog",
            "og":".mnlgprog",
            "prologue":".prlgprog"
        }[out_flavour]

    elif match_ident is not None:
        proglist = [proglist[match_ident - 1]]
        # https://stackoverflow.com/a/13593932
        stem = re.sub(r"[^\w\-_\.]", "_", match_name.stem)
        patch_ext = ".mnlgxdprog"
    else:
        stem = input_file.stem
        patch_ext = ".mnlgxdlib"

    if force_preset:
        patch_ext = ".mnlgxdpreset"

    output_file = input_file.with_name(stem).with_suffix(patch_ext)

    # Read any information from preset if available
    dataid = stem
    name = stem
    version = None
    date = None
    prefix = None
    copyright = None
    author = None
    comment = None
    if input_file.suffix in {".mnlgxdpreset", ".mnlgpreset", ".prlgpreset", ".molgpreset"}:
        dataid, name, author, version, numofprog, date, prefix, copyright = common.all_from_presetinformation_xml(zipobj)
        if dataid is None:
            dataid = name

    non_init_patch_ids = []
    numofprog = 0
    with ZipFile(output_file, "w") as xdzip:
        for i, p in enumerate(proglist):
            if input_file.suffix != ".syx":
                patchdata = zipobj.read(p)
            flavour = common.patch_type(patchdata)
            if common.is_init_patch(flavour, hash):
                # Init Program identified based on hash; i.e. a "True" Init Program
                continue
            prgname = common.program_name(patchdata, flavour)
            if common.is_init_program_name(prgname) and not unskip_init:
                # Init Program found and option not to skip is unchecked
                continue
            non_init_patch_ids.append(i)
            print(f"{int(p[5:8])+1:03d}: {prgname}")

            if input_file.suffix != ".syx":
                if flavour == 'og': 
                    raw_patch = common.parse_patchdata(patchdata)
                    patch = og.normalise_og_patch(raw_patch)
                    patch_xd, patchdata = convert_to_xd(patch, flavour)
                elif flavour == 'prologue':
                    raw_patch = common.parse_patchdata(patchdata)
                    patch = prologue.normalise_patch(raw_patch)
                    patch_xd, patchdata = convert_to_xd(patch, flavour)
                elif flavour == 'monologue':
                    raw_patch = common.parse_patchdata(patchdata)
                    patch = monologue.normalise_patch(raw_patch)
                    patch_xd, patchdata = convert_to_xd(patch, flavour)

            # .prog_bin record/file
            xdzip.writestr(f"Prog_{i:03d}.prog_bin", patchdata)

            # .prog_info record/file
            prog_info_xd = common.prog_info_template_xml(out_flavour)
            xdzip.writestr(f"Prog_{i:03d}.prog_info", prog_info_xd)

            numofprog += 1

            if verbose:
                pprint(vars(patch))
                print()

        if len(proglist) > 1 and not force_preset:
            if out_flavour == "prologue":
                xdzip.writestr(f"LivesetData.lvs_data", getattr(globals()[out_flavour], "favorite_template"))
            else:
                # FavoriteData.fav_data record/file
                try:
                    xdzip.writestr(f"FavoriteData.fav_data", getattr(globals()[out_flavour], "favorite_template"))
                except:
                    pass

        if force_preset:
            xdzip.writestr(f"PresetInformation.xml", common.presetinfo_xml(out_flavour, dataid, name, author, version, str(numofprog), date, prefix, copyright))


        # FileInformation.xml record/file
        xdzip.writestr(f"FileInformation.xml", common.fileinfo_xml(out_flavour, non_init_patch_ids, force_preset))

        print("Wrote", output_file)
Exemplo n.º 6
0
def explode(filename, match_name, match_ident, prepend_id, append_md5_4,
            append_version, unskip_init):
    """Explode a minilogue og or xd or prologue program bank or extract a program.

    \b
    Examples
    --------
    explode xd_program_bank.mnlgxdlib
    explode -n XDProgName xd_program_bank.mnlgxdlib

    """
    zipobj = ZipFile(filename, "r", compression=ZIP_DEFLATED, compresslevel=9)
    proglist = common.zipread_progbins(zipobj)
    proginfo_dict = common.zipread_all_prog_info(zipobj)

    if match_name is not None:
        match_ident = common.id_from_name(zipobj, match_name)

    if match_ident is not None:
        proglist = [proglist[match_ident - 1]]

    # Create directory based on the filename stem
    input_file = pathlib.Path(filename)
    dir_path = input_file.with_suffix("")
    dir_path.mkdir(exist_ok=True)
    if input_file.suffix in {".mnlgxdpreset", ".mnlgxdlib"}:
        suffix = ".mnlgxdprog"
        flavour = "xd"
    elif input_file.suffix in {".mnlgpreset", ".mnlglib"}:
        suffix = ".mnlgprog"
        flavour = "og"
    elif input_file.suffix in {".prlgpreset", ".prlglib"}:
        suffix = ".prlgprog"
        flavour = "prologue"
    elif input_file.suffix in {".molgpreset", ".molglib"}:
        suffix = ".molgprog"
        flavour = "monologue"
    elif input_file.suffix in {".kklib"}:
        suffix = ".kkprog"
        flavour = "kk"
    fileinfo_xml = common.fileinfo_xml(flavour, [0])

    # Read any copyright and author information if available
    copyright = None
    author = None
    comment = None
    if input_file.suffix in {
            ".mnlgxdpreset", ".mnlgpreset", ".prlgpreset", ".molgpreset"
    }:
        author, copyright = common.author_copyright_from_presetinformation_xml(
            zipobj)

    sanitise = common.sanitise_patchname()
    for i, p in enumerate(proglist):
        patchdata = zipobj.read(p)
        hash = hashlib.md5(patchdata).hexdigest()
        flavour = common.patch_type(patchdata)
        if common.is_init_patch(flavour, hash):
            # Init Program identified based on hash; i.e. a "True" Init Program
            continue
        prgname = common.program_name(patchdata, flavour)
        if common.is_init_program_name(prgname) and not unskip_init:
            # Init Program found and option not to skip is unchecked
            continue
        if prepend_id:
            prgname = f"{i+1:03d}_{prgname}"
        if append_md5_4:
            hash = hashlib.md5(patchdata).hexdigest()
            prgname = f"{prgname}-{hash[:4]}"
        if append_version:
            ver = version.__version__.replace(".", "")
            prgname = f"{prgname}-v{ver}"
        output_path = (dir_path / (sanitise(prgname) + suffix))
        with ZipFile(output_path, "w") as zip:
            binary = zipobj.read(p)

            # .prog_bin record/file
            zip.writestr(f"Prog_000.prog_bin", binary)

            # .prog_info record/file
            # Use any available presetinformation_xml author and copyright fields
            if author is not None:
                comment = f"Author: {author}"
            proginfo_comment = (proginfo_dict[p])['Comment']
            if proginfo_comment is not None:
                comment = f"{comment}, " + proginfo_comment
            prog_info_template = common.prog_info_template_xml(
                flavour, comment=comment, copyright=copyright)
            zip.writestr(f"Prog_000.prog_info", prog_info_template)

            # FileInformation.xml record/file
            zip.writestr(f"FileInformation.xml", fileinfo_xml)

        print(f"{int(p[5:8])+1:03d}: {prgname:<12s}  ->  {output_path}")
Exemplo n.º 7
0
def collapse(filename, unskip_init, force_preset):
    proglist = []
    for p in common.patch_suffixes:
        proglist.extend(glob.glob(join(filename, "*" + p)))

    (flavor, lib_ext, preset_ext) = {
        ".molgprog": ("monologue", ".molglib", ".molgpreset"),
        ".mnlgxdprog": ("xd", ".mnlgxdlib", ".mnlgxdpreset"),
        ".mnlgprog": ("og", ".mnlglib", ".mnlgpreset"),
        ".prlgprog": ("prologue", ".prlglib", ".prlgpreset")
    }[splitext(proglist[0])[1]]

    if force_preset:
        output_file = filename + preset_ext
    else:
        output_file = filename + lib_ext

    name = split(filename)[1]
    dataid = name
    version = None
    date = None
    prefix = None
    copyright = None
    author = None
    comment = None

    non_init_patch_ids = []
    numofprog = 0
    with ZipFile(output_file, "w") as xdzip:
        for i, p in enumerate(proglist):
            zipobj = ZipFile(p, "r", compression=ZIP_DEFLATED, compresslevel=9)
            patchdata = zipobj.read(common.zipread_progbins(zipobj)[0])
            flavour = common.patch_type(patchdata)
            if flavor != flavour:
                # actual patch type did not match with the first one
                continue
            if common.is_init_patch(flavour, hash):
                # Init Program identified based on hash; i.e. a "True" Init Program
                continue
            prgname = common.program_name(patchdata, flavour)
            if common.is_init_program_name(prgname) and not unskip_init:
                # Init Program found and option not to skip is unchecked
                continue
            non_init_patch_ids.append(i)
            print(f"{i+1:03d}: {prgname}")

            # .prog_bin record/file
            xdzip.writestr(f"Prog_{i:03d}.prog_bin", patchdata)

            # .prog_info record/file
            prog_info = common.prog_info_template_xml(flavor)
            xdzip.writestr(f"Prog_{i:03d}.prog_info", prog_info)

            numofprog += 1

        if force_preset:
            xdzip.writestr(
                f"PresetInformation.xml",
                common.presetinfo_xml(flavor, dataid, name, author, version,
                                      str(numofprog), date, prefix, copyright))
        elif flavor == "prologue":
            xdzip.writestr(f"LivesetData.lvs_data",
                           getattr(globals()[flavor], "favorite_template"))
        else:
            # FavoriteData.fav_data record/file
            try:
                xdzip.writestr(f"FavoriteData.fav_data",
                               getattr(globals()[flavor], "favorite_template"))
            except:
                pass

        # FileInformation.xml record/file
        xdzip.writestr(
            f"FileInformation.xml",
            common.fileinfo_xml(flavor, non_init_patch_ids, force_preset))

        print("Wrote", output_file)
Exemplo n.º 8
0
def translate(filename, match_name, match_ident, verbose, unskip_init):
    """Translate a minilogue program or program bank to the minilogue xd.

    \b
    Examples
    --------
    translate og_program_bank.mnlgpreset
    translate -n OGProgName og_program_bank.mnlgpreset
    translate -n "OG Prog Name" og_program_bank.mnlgpreset
    translate OGProgName.mnlgprog

    """
    zipobj = ZipFile(filename, "r", compression=ZIP_DEFLATED, compresslevel=9)
    proglist = common.zipread_progbins(zipobj)

    input_file = pathlib.Path(filename)
    assert input_file.suffix in {".mnlgprog", ".mnlgpreset", ".mnlglib"}
    if input_file.suffix == ".mnlgprog":
        # single patch/program
        match_name = input_file
        match_ident = 1
    elif match_name is not None:
        # patch library/program pack
        match_ident = common.id_from_name(zipobj, match_name)

    if match_ident is not None:
        proglist = [proglist[match_ident - 1]]
        # https://stackoverflow.com/a/13593932
        stem = re.sub(r"[^\w\-_\.]", "_", match_name.stem)
        patch_ext = ".mnlgxdprog"
    else:
        stem = input_file.stem
        patch_ext = ".mnlgxdlib"
    output_file = input_file.with_name(stem).with_suffix(patch_ext)

    # Read any copyright and author information if available
    copyright = None
    author = None
    comment = None
    if input_file.suffix == ".mnlgpreset":
        author, copyright = common.author_copyright_from_presetinformation_xml(zipobj)

    non_init_patch_ids = []
    with ZipFile(output_file, "w") as xdzip:
        for i, p in enumerate(proglist):
            patchdata = zipobj.read(p)
            flavour = common.patch_type(patchdata)
            if common.is_init_patch(flavour, hash):
                # Init Program identified based on hash; i.e. a "True" Init Program
                continue
            prgname = common.program_name(patchdata, flavour)
            if common.is_init_program_name(prgname) and not unskip_init:
                # Init Program found and option not to skip is unchecked
                continue
            non_init_patch_ids.append(i)
            print(f"{int(p[5:8])+1:03d}: {prgname}")

            raw_og_patch = common.parse_patchdata(patchdata)
            patch = og.normalise_og_patch(raw_og_patch)
            patch_xd, binary_xd = convert_og_to_xd(patch)

            # .prog_bin record/file
            xdzip.writestr(f"Prog_{i:03d}.prog_bin", binary_xd)

            # .prog_info record/file
            prog_info_xd = common.prog_info_template_xml("xd")
            xdzip.writestr(f"Prog_{i:03d}.prog_info", prog_info_xd)

            if verbose:
                pprint(vars(patch))
                print()

        if len(proglist) > 1:
            # FavoriteData.fav_data record/file
            xdzip.writestr(f"FavoriteData.fav_data", xd.favorite_template)

        # FileInformation.xml record/file
        xdzip.writestr(f"FileInformation.xml", common.fileinfo_xml("xd", non_init_patch_ids))

        print("Wrote", output_file)