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
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
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)
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)
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()
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())