Example #1
0
class LhaHandler(object):

    def __init__(self, path):
        self.path = path
        self.zip = LhaFile(self.path, "r")

    def list_files(self, sub_path):
        if sub_path:
            return
        for name in self.zip.namelist():
            # if name.endswith(str("/")):
            #     continue
            yield self.decode_name(name)

    def open(self, name):
        name = self.encode_name(name)
        # LhaFile does not have open method
        data = self.zip.read(name)
        return io.BytesIO(data)

    def exists(self, name):
        name = self.encode_name(name)
        items = self.zip.infolist()
        for item in items:
            if item.filename == name:
                return True
        return False

        # try:
        #     self.zip.getinfo(name)
        # except KeyError:
        #     return False
        # else:
        #     return True

    def encode_name(self, name):
        name = name.replace("\\", "/")
        name = name.replace("%5f", "\\")
        name = name.replace("%25", "%")

        # FIXME: a little hack here, LhaFile uses os.sep
        # as path separator
        name = name.replace("/", os.sep)

        # name = name.encode("ISO-8859-1")
        return name

    def decode_name(self, name):
        # print("decode_name", name)

        # name = name.decode("ISO-8859-1")
        # FIXME: a little hack here, LhaFile uses os.sep
        # as path separator, normalizing to /
        name = name.replace(os.sep, "/")

        name = name.replace("%", "%25")
        name = name.replace("\\", "%5f")
        name = name.replace("/", os.sep)
        return name
Example #2
0
def lha_extract(arcpath, outpath):
    arc = LhaFile(arcpath)
    for filename in [info.filename for info in arc.infolist()]:
        path = filename.replace("\\", "/")
        dirname = os.path.dirname(path)
        basename = os.path.basename(path)
        if dirname:
            make_dir(os.path.join(outpath, dirname))
        if basename:
            make_dir(os.path.join(outpath, dirname))
            open(os.path.join(outpath, dirname, basename), "wb").write(arc.read(filename))
Example #3
0
def index_whdload_archives(basedir):
    basedir += os.sep
    print("enumerating archives..", end="", flush=True)
    count = 0
    d = {}
    for r, _, f in os.walk(basedir):
        for file in f:
            if file.endswith(".lha"):
                count += 1
                if count % 100 == 0:
                    print(".", end="", flush=True)
                path = util.path(r, file)
                db_path = path.split(basedir)[1]
                slave_category = db_path.split(os.sep)[0]

                if slave_category in ["game", "demo", "mags"]:
                    arc = LhaFile(path)
                    for n in arc.namelist():
                        n = n.replace("\\", "/")
                        if n.lower().endswith(".slave"):
                            if len(n.split("/")) > 2:
                                pass  # skip slaves beneath root
                            else:
                                slave_id = slave_category + "--" + n[:-6].replace(
                                    "/", "--").lower()
                                slave_ver = "v1.0"
                                try:
                                    verstr = file[:-4].split("_")[1]
                                    if verstr.startswith("v"):
                                        slave_ver = verstr
                                except Exception:
                                    pass
                                d[slave_id] = {
                                    "id": slave_id,
                                    "archive_path": db_path,
                                    "slave_path": n,
                                    "slave_version": slave_ver
                                }

                elif slave_category in [
                        "game-notwhdl", "demo-notwhdl", "mags-notwhdl"
                ]:
                    slave_id = slave_category + "--" + os.path.splitext(
                        os.path.basename(path))[0].lower()
                    if util.is_file(path.replace(".lha", ".run")):
                        d[slave_id] = {
                            "id": slave_id,
                            "archive_path": db_path,
                            "slave_path": None,
                            "slave_version": None
                        }

    print("\n", flush=True)
    return d
Example #4
0
class LhaHandler(object):
    def __init__(self, path):
        self.path = path
        self._lhafile = LhaFile(self.path, "r")

    def decode_name(self, name):
        # FIXME: a little hack here, LhaFile uses os.sep
        # as path separator, normalizing to /
        name = name.replace(os.sep, "/")

        name = name.replace("%", "%25")
        name = name.replace("\\", "%5c")
        name = name.replace("/", os.sep)
        return name

    def encode_name(self, name):
        name = name.replace("\\", "/")
        name = name.replace("%5c", "\\")
        name = name.replace("%25", "%")
        # FIXME: Legacy workaround for existing entries with incorrect escape.
        name = name.replace("%5f", "\\")

        # FIXME: a little hack here, LhaFile uses os.sep
        # as path separator
        name = name.replace("/", os.sep)
        return name

    def exists(self, name):
        # FIXME: Maybe look up in NameToInfo instead for quicker lookups
        name = self.encode_name(name)
        items = self._lhafile.infolist()
        for item in items:
            if item.filename == name:
                return True
        return False

    def getinfo(self, name):
        # FIXME: Should instead add getinfo to LhaFile...
        return self._lhafile.NameToInfo[self.encode_name(name)]

    def list_files(self, sub_path):
        if sub_path:
            return
        for name in self._lhafile.namelist():
            # if name.endswith(str("/")):
            #     continue
            yield self.decode_name(name)

    def open(self, name):
        # LhaFile does not have open method
        data = self._lhafile.read(self.encode_name(name))
        return io.BytesIO(data)
Example #5
0
 def __init__(self, path):
     self.path = path
     self.zip = LhaFile(self.path, "r")
 def __init__(self, path):
     self.path = path
     self._lhafile = LhaFile(self.path, "r")
class LhaHandler(object):
    def __init__(self, path):
        self.path = path
        self._lhafile = LhaFile(self.path, "r")

    def decode_name(self, name):
        # FIXME: a little hack here, LhaFile uses os.sep
        # as path separator, normalizing to /
        name = name.replace(os.sep, "/")

        name = name.replace("%", "%25")
        name = name.replace("\\", "%5c")
        name = name.replace("/", os.sep)
        return name

    def encode_name(self, name):
        name = name.replace("\\", "/")
        name = name.replace("%5c", "\\")
        name = name.replace("%25", "%")
        # FIXME: a little hack here, LhaFile uses os.sep
        # as path separator
        name = name.replace("/", os.sep)
        return name

    def exists(self, name):
        # FIXME: Maybe look up in NameToInfo instead for quicker lookups
        name = self.encode_name(name)
        items = self._lhafile.infolist()
        for item in items:
            if item.filename == name:
                return True
        return False

    def _formatinfo(self, info):
        comment = info.comment
        if comments_as_bytes and isinstance(comment, str):
            # It might have been a mistake for LhaFile to decode the comment
            # as ISO-8859-1. We encode back and keep it as bytes, for
            # consistency with the ZipFile module... maybe. Alternatively,
            # decode zipfile comments as ISO-8859-1 instead...
            comment = comment.encode("ISO-8859-1")
        return ArchiveFileInfo(
            filename=info.filename,
            file_size=info.file_size,
            comment=comment,
        )

    def getinfo(self, name):
        # FIXME: Should instead add getinfo to LhaFile...
        info = self._lhafile.NameToInfo[self.encode_name(name)]
        return self._formatinfo(info)

    def infolist(self):
        result = []
        for info in self._lhafile.infolist():
            result.append(self._formatinfo(info))
        return result

    def list_files(self, sub_path):
        if sub_path:
            return
        for name in self._lhafile.namelist():
            # if name.endswith(str("/")):
            #     continue
            yield self.decode_name(name)

    def open(self, name):
        # LhaFile does not have open method
        data = self._lhafile.read(self.encode_name(name))
        return io.BytesIO(data)
Example #8
0
 def __init__(self, path):
     self.path = path
     self.zip = LhaFile(self.path, "r")
Example #9
0
outputFile = args.output
if (outputFile == None):
    outputFile = os.path.splitext(args.input)[0] + ".vgm"

try:
    f = open(args.input, 'rb')
except FileNotFoundError:
    print("File not found: " + args.input)
    sys.exit()
data = f.read()
f.close()
fileHeader = checkFileHeader(data)
if fileHeader == fileTypes.Garbage:  # File isn't already decompressed
    try:
        archive = LhaFile(args.input)
    except BadLhafile:
        print(
            "Unable to decompress the file. Try decompressing it in 7Zip or another archive tool"
        )
        sys.exit()
    # Read first file out of archive (they only ever have 1 file)
    data = archive.read(archive.infolist()[0].filename)
    fileHeader = checkFileHeader(data)
    if fileHeader == fileTypes.Garbage:
        print(
            "File was a valid LHA archive, but it didn't contain a valid YM file"
        )
        sys.exit()
    elif fileHeader == fileTypes.Unsupported:
        print("Error: Unsupported file type")
Example #10
0
def generateFile(file):
    collectedErrors = []
    merger = PdfFileMerger()
    ios = file
    lf = LhaFile(ios)
    appended = False
    loextensions = ('.odt', '.ods')
    for name in lf.namelist():
        content = lf.read(name)
        _, extension = os.path.splitext(name)
        if content[0:5] == b'%PDF-':
            merger.append(io.BytesIO(content))
            appended = True
        elif content[0:5] == b'{\\rtf' or (content[0:4]
                                           == bytes.fromhex('504B0304')
                                           and extension in loextensions):
            with tempdir() as tmpdir:
                tmpfile = os.sep.join([tmpdir, "temp" + extension])
                pdffile = tmpdir + os.sep + "temp.pdf"
                with open(tmpfile, "wb") as f:
                    f.write(content)
                command = '"' + " ".join([
                    '"' + self._librepath + '"', "--convert-to pdf",
                    "--outdir", '"' + tmpdir + '"', '"' + tmpfile + '"'
                ]) + '"'
                if os.system(command) == 0:
                    try:
                        with open(pdffile, "rb") as f:
                            merger.append(io.BytesIO(f.read()))

                        appended = True
                    except:
                        err = "%s: Fehler beim Öffnen der konvertierten PDF-Datei '%s' (konvertiert aus '%s')" % (
                            file['beschreibung'], pdffile, tmpfile)
                        collectedErrors.append(err)
                else:
                    err = "%s: Fehler beim Ausführen des Kommandos: '%s'" % (
                        file['beschreibung'], command)
                    collectedErrors.append(err)
        elif name == "message.eml":
            # eArztbrief
            eml = email.message_from_bytes(content)
            errors = []
            for part in eml.get_payload():
                fnam = part.get_filename()
                partcont = part.get_payload(decode=True)
                if partcont[0:5] == b'%PDF-':
                    merger.append(io.BytesIO(partcont))
                    appended = True
                else:
                    errors.append(
                        "%s: eArztbrief: nicht unterstütztes Anhangsformat in Anhang '%s'"
                        % (file["beschreibung"], fnam))

            if not appended and len(errors) > 0:
                err = '\n'.join(errors)
                collectedErrors.append(err)
        else:
            try:
                if content[0:4] == bytes.fromhex('FFD8FFE0'):
                    img = Image.fromarray(pylibjpeg.decode(content))
                    outbuffer = io.BytesIO()
                    img.save(outbuffer, 'PDF')
                    merger.append(outbuffer)
                    appended = True
                #elif self._config.getValue('useImg2pdf', True):
                #    LOGGER.debug("Using img2pdf for file conversion")
                #    merger.append(io.BytesIO(img2pdf.convert(content)))
                #    appended = True
                else:
                    if content[0:3] == b'II*':
                        #with open('tmp.tif', 'wb') as f:
                        #    f.write(content)
                        infile = 'tmp.tif'
                        outfile = 'tmp.pdf'
                        batchscript = '(let* ((image (car (gimp-file-load RUN-NONINTERACTIVE "{infile}" "{infile}")))(drawable (car (gimp-image-get-active-layer image))))\
                            (file-pdf-save2 RUN-NONINTERACTIVE image drawable "{outfile}" "{outfile}" FALSE TRUE TRUE TRUE FALSE)(gimp-image-delete image) (gimp-quit 0))'.format(
                            infile=infile, outfile=outfile)
                        gimp_path = 'C:\\Program Files\\GIMP 2\\bin\\gimp-2.10.exe'
                        subprocess.run([gimp_path, '-i', '-b', batchscript],
                                       check=True,
                                       stdout=PIPE,
                                       stderr=PIPE)
                        merger.append(outfile)
                        appended = True
            except Exception as e:
                err = "Dateiinhalt '%s' ist kein unterstützter Dateityp -> wird nicht an PDF angehängt (%s)" % (
                    name, type(e))
                collectedErrors.append(err)
                traceback.print_exc(e)

    #if appended:
    #    try:
    #        merger.write(filename)
    #    except Exception as e:
    #        err = "{}: Fehler beim Schreiben der Ausgabedatei '{}': {}".format(file["beschreibung"], filename, e)
    #        if errorSlot:
    #            errorSlot.emit(err)
    #        else:
    #            self._av.displayErrorMessage(err)
    print('\n'.join(collectedErrors))

    merger.close()
Example #11
0
def convert(filename, ofilename):
    try:
        lha = LhaFile(filename)
        files = lha.namelist()
        # print(files)
        assert (len(files) == 1)
        ymdata = lha.read(files[0])
    except:
        raise LhaArchiveError

    # print(ymdata[0:200])
    ym = {}
    ym['tag'] = to_string(ymdata[0:4])
    if not ym['tag'] in ['YM2!', 'YM3!', 'YM3b', 'YM4!', 'YM5!', 'YM6!']:
        raise YmHeaderTypeError

    if ym['tag'] in ['YM2!', 'YM3!']:
        assert ((len(ymdata) - 4) % 14 == 0)
        ym['frames'] = (len(ymdata) - 4) // 14

        ym['clock'] = 2000000
        ym['rate'] = 50
        ym['song_name'] = ''
        ym['author_name'] = ''
        ym['song_comment'] = ''
        ym['attributes'] = 1
        ym['samples'] = 0
        ym['loop'] = 0
        ym['additions'] = 0

        n = ym['frames']
        ym['data'] = [[0] * 16 for i in range(n)]
        for f in range(n):
            for r in range(14):
                ym['data'][f][r] = to_byte(ymdata[4 + r * n + f])

        # cant_handle_custom_frequencies(ym)
        cant_handle_dd_or_ts_effects(ym)
        # cant_handle_loop(ym)

    if ym['tag'] in ['YM3b']:
        assert ((len(ymdata) - 8) % 14 == 0)
        ym['frames'] = (len(ymdata) - 8) // 14
        ym['loop'] = to_dword(ymdata[-4:])
        if ym['loop'] >= ym['frames']:
            ym['loop'] = to_dword_littleendian(ymdata[-4:])
        assert (ym['loop'] < ym['frames'])

        ym['clock'] = 2000000
        ym['rate'] = 50
        ym['song_name'] = ''
        ym['author_name'] = ''
        ym['song_comment'] = ''
        ym['attributes'] = 1
        ym['samples'] = 0
        ym['additions'] = 0

        n = ym['frames']
        ym['data'] = [[0] * 16 for i in range(n)]
        for f in range(n):
            for r in range(14):
                ym['data'][f][r] = to_byte(ymdata[4 + r * n + f])

        # cant_handle_custom_frequencies(ym)
        cant_handle_dd_or_ts_effects(ym)
        # cant_handle_loop(ym)

    elif ym['tag'] in ['YM4!']:
        ym['check'] = to_string(ymdata[4:12])
        assert (ym['check'] == 'LeOnArD!')
        ym['frames'] = to_dword(ymdata[12:16])
        ym['attributes'] = to_dword(ymdata[16:20])
        ym['samples'] = to_dword(ymdata[20:24])
        ym['loop'] = to_dword(ymdata[24:28])
        assert (ym['loop'] < ym['frames'])
        song_name_end = ymdata.index(b'\0', 28)
        author_name_end = ymdata.index(b'\0', song_name_end + 1)
        song_comment_end = ymdata.index(b'\0', author_name_end + 1)
        ym['song_name'] = to_string(ymdata[28:song_name_end])
        ym['author_name'] = to_string(ymdata[song_name_end +
                                             1:author_name_end])
        ym['song_comment'] = to_string(ymdata[author_name_end +
                                              1:song_comment_end])

        ym['clock'] = 2000000
        ym['rate'] = 50
        ym['additions'] = 0

        n = ym['frames']
        ym['tagend'] = to_string(ymdata[song_comment_end + 1 + 16 * n:])
        assert (ym['tagend'] == 'End!')
        # print(ym)
        #
        ym['data'] = [[0] * 16 for i in range(n)]

        f0 = song_comment_end + 1
        if ym['attributes'] == 1:
            for f in range(n):
                for r in range(16):
                    ym['data'][f][r] = to_byte(ymdata[f0 + r * n + f])
        elif ym['attributes'] == 0:
            for f in range(n):
                for r in range(16):
                    ym['data'][f][r] = to_byte(ymdata[f0 + 16 * f + r])

        # cant_handle_custom_frequencies(ym)
        cant_handle_dd_or_ts_effects(ym)
        # cant_handle_loop(ym)

    elif ym['tag'] in ['YM5!', 'YM6!']:
        ym['check'] = to_string(ymdata[4:12])
        assert (ym['check'] == 'LeOnArD!')
        ym['frames'] = to_dword(ymdata[12:16])
        ym['attributes'] = to_dword(ymdata[16:20])
        ym['samples'] = to_word(ymdata[20:22])
        ym['clock'] = to_dword(ymdata[22:26])
        ym['rate'] = to_word(ymdata[26:28])
        ym['loop'] = to_dword(ymdata[28:32])
        assert (ym['loop'] < ym['frames'])
        ym['additions'] = to_word(ymdata[32:34])
        song_name_end = ymdata.index(b'\0', 34)
        author_name_end = ymdata.index(b'\0', song_name_end + 1)
        song_comment_end = ymdata.index(b'\0', author_name_end + 1)
        ym['song_name'] = to_string(ymdata[34:song_name_end])
        ym['author_name'] = to_string(ymdata[song_name_end +
                                             1:author_name_end])
        ym['song_comment'] = to_string(ymdata[author_name_end +
                                              1:song_comment_end])

        n = ym['frames']
        ym['tagend'] = to_string(ymdata[song_comment_end + 1 + 16 * n:])

        assert (ym['tagend'] == 'End!')
        # print(ym)
        #
        ym['data'] = [[0] * 16 for i in range(n)]

        f0 = song_comment_end + 1
        if ym['attributes'] == 1:
            for f in range(n):
                for r in range(16):
                    ym['data'][f][r] = to_byte(ymdata[f0 + r * n + f])
        elif ym['attributes'] == 0:
            for f in range(n):
                for r in range(16):
                    ym['data'][f][r] = to_byte(ymdata[f0 + 16 * f + r])

        # cant_handle_custom_frequencies(ym)
        cant_handle_dd_or_ts_effects(ym)
        # cant_handle_loop(ym)

    with open(ofilename, 'wb') as of:
        of.write('YMR1'.encode())
        of.write(struct.pack('<L', ym['frames']))
        of.write(struct.pack('<L', ym['clock']))
        of.write(struct.pack('<H', ym['rate']))
        of.write(ym['song_name'].encode())
        of.write(b'\0')
        of.write(ym['author_name'].encode())
        of.write(b'\0')
        of.write(ym['song_comment'].encode())
        of.write(b'\0')
        for f in range(n):
            for r in range(14):
                of.write(from_byte(ym['data'][f][r]))
        of.write('End!'.encode())
Example #12
0
    def _cli_slaves_add_archive(self, source_file: BinaryIO,
                                source_root_path: str,
                                installed_root_path: str):
        file_path = source_file.name
        file_dir = os.path.dirname(file_path)
        file_name = os.path.basename(file_path)
        file_ext = os.path.splitext(file_name)[1].lower()

        if file_ext == ".lha":
            lha_file = None
            try:
                lha_file = LhaFile(source_file)
            except BadLhafile:
                DataSet.logger.error(
                    f"Unable to open LHA file '{file_name}'. Skipping.")

            if lha_file is not None:
                archived_files = [x for x in lha_file.infolist()]
                for archived_file in archived_files:
                    archived_file_path = archived_file.filename
                    archived_file_name = os.path.basename(archived_file_path)
                    archived_file_ext = os.path.splitext(
                        archived_file_path)[1].lower()
                    archived_file_dir = archived_file.directory
                    archived_file_datetime = archived_file.date_time
                    if archived_file_ext == ".slave":
                        with tempfile.TemporaryDirectory() as temp_dir:
                            extracted_dir = None
                            try:
                                extracted_dir = os.path.join(
                                    temp_dir, archived_file_dir)
                            except TypeError:
                                DataSet.logger.error(
                                    f"Unable to extract archive '{file_name}'. Skipping."
                                )

                            if extracted_dir is not None:
                                extracted_file_path = os.path.join(
                                    extracted_dir, archived_file_name)
                                os.makedirs(extracted_dir)
                                open(extracted_file_path, "wb").write(
                                    lha_file.read(archived_file_path))
                                with open(extracted_file_path,
                                          "rb") as temp_file:
                                    installed_dir = file_dir.replace(
                                        source_root_path, "")
                                    installed_path = self._reformat_amiga_path(
                                        installed_root_path,
                                        f"{installed_dir}/{archived_file_path}"
                                    )
                                    self._add_slave(
                                        temp_file,
                                        file_datetime=archived_file_datetime,
                                        installed_path=installed_path)
                                slave = self._get_slave_by_file_path(
                                    extracted_file_path)
                                if slave is not None:
                                    fake_file_path = os.path.join(
                                        file_dir, archived_file_path)
                                    slave.file_path = fake_file_path
                                    slave.file_datetime = archived_file_datetime
                                    self.save()
        else:
            DataSet.logger.error(f"Unsupported file '{file_name}'.")