Update uadf to support py3

This commit is contained in:
2019-06-30 16:53:16 +02:00
parent 2e50401a18
commit 6b8684b1d7

74
uadf
View File

@@ -1,11 +1,11 @@
#! /usr/bin/env python
#!/usr/bin/env python3
"""
UADF Virtual filesystem
This extfs provides quick and dirty read-only access to disk image files for
the Commodore Amiga adf or adz (gzipped adfs) and dms.
It requires the unadf utility (unfortunately there is no original sources,
It requires the unadf utility, unfortunately there is no original sources,
since authors page doesn't exists anymore. Luckily, there is a copy of the
source (and useful patches) in Debian repository:
http://packages.debian.org/sid/unadf
@@ -15,16 +15,19 @@ There should be one change made to the source of unadf, though. While using
However there is no way to distinguish where filename ends and comment starts,
if comment or filename already contains any comma.
The patched sources are available from: https://github.com/lclevy/ADFlib
It also requires xdms utility, for optional dms support.
Changelog:
1.3 Switch to Python3
1.2 Added failsafe for filenames in archive with spaces and nodos message.
1.1 Moved common code into extfslib library
1.0 Initial release
Author: Roman 'gryf' Dobosz <gryf73@gmail.com>
Date: 2013-05-16
Version: 1.2
Date: 2019-06-30
Version: 1.3
Licence: BSD
"""
@@ -43,17 +46,17 @@ class UAdf(Archive):
"""
Class for interact with c1541 program and MC
"""
LINE_PAT = re.compile('\s*(?P<size>\d+)?'
'\s{2}(?P<date>\d{4}/\d{2}/\d{2})'
'\s{2}\s?(?P<time>\d+:\d{2}:\d{2})'
'\s{2}(?P<fpath>.*)')
ARCHIVER = "unadf"
DMS = "xdms"
CMDS = {"list": "-lr",
"read": "r",
"write": "w",
"delete": "d"}
DATETIME = "%s-%s-%s %02d:%s"
LINE_PAT = re.compile(b'\s*(?P<size>\d+)?'
b'\s{2}(?P<date>\d{4}/\d{2}/\d{2})'
b'\s{2}\s?(?P<time>\d+:\d{2}:\d{2})'
b'\s{2}(?P<fpath>.*)')
ARCHIVER = b"unadf"
DMS = b"xdms"
CMDS = {"list": b"-lr",
"read": b"r",
"write": b"w",
"delete": b"d"}
DATETIME = b"%s-%s-%s %02d:%s"
def __init__(self, fname):
"""Prepare archive content for operations"""
@@ -78,8 +81,8 @@ class UAdf(Archive):
def _parse_dt(self, date, time):
"""Return parsed datetime which fulfill extfs standards date."""
year, month, day = date.split("/")
hours, minutes, _unused = time.split(":")
year, month, day = date.split(b"/")
hours, minutes, _unused = time.split(b":")
return self.DATETIME % (month, day, year, int(hours), minutes)
def _ungzip(self):
@@ -100,7 +103,7 @@ class UAdf(Archive):
os.close(fdesc)
try:
check_call([self.DMS, '-q', 'u', self._arch, "+" + tmp_fname])
check_call([self.DMS, b'-q', b'u', self._arch, "+" + tmp_fname])
self._arch = tmp_fname
self._clean = False
except (CalledProcessError, OSError):
@@ -116,20 +119,25 @@ class UAdf(Archive):
except CalledProcessError:
return contents
for line in out.split("\n"):
for line in out.split(b"\n"):
match = self.LINE_PAT.match(line)
if not match:
continue
entry = match.groupdict()
entry['perms'] = "-rw-r--r--"
if not entry['size']:
entry['perms'] = "drwxr-xr-x"
entry['size'] = "0"
entry['display_name'] = self._map_name(entry['fpath'])
entry['datetime'] = self._parse_dt(entry['date'], entry['time'])
entry['uid'] = self._uid
entry['gid'] = self._gid
match_entry = match.groupdict()
entry = {}
for key in match_entry:
entry[bytes(key, 'utf-8')] = match_entry[key]
del match_entry
entry[b'perms'] = b"-rw-r--r--"
if not entry[b'size']:
entry[b'perms'] = b"drwxr-xr-x"
entry[b'size'] = b"0"
entry[b'display_name'] = self._map_name(entry[b'fpath'])
entry[b'datetime'] = self._parse_dt(entry[b'date'], entry[b'time'])
entry[b'uid'] = bytes(str(self._uid), 'utf-8')
entry[b'gid'] = bytes(str(self._gid), 'utf-8')
contents.append(entry)
return contents
@@ -145,7 +153,7 @@ class UAdf(Archive):
return 1
for entry in self._contents:
sys.stdout.write(self.ITEM % entry)
sys.stdout.buffer.write(self.ITEM % entry)
return 0
def copyout(self, src, dst):
@@ -154,24 +162,26 @@ class UAdf(Archive):
if not real_src:
raise IOError("No such file or directory")
if " " in real_src:
if b" " in real_src:
sys.stderr.write("unadf is unable to operate on filepath with "
"space inside.\nUse affs to mount image and than"
" extract desired files.\n")
return 1
extract_dir = mkdtemp()
cmd = ["unadf", self._arch, real_src, "-d", extract_dir]
cmd = [self.ARCHIVER, self._arch, real_src, b"-d", extract_dir]
if check_call(cmd, stdout=open(os.devnull, 'wb'),
stderr=open(os.devnull, 'wb')) != 0:
shutil.rmtree(extract_dir)
sys.stderr.write("unadf returned with nonzero exit code\n")
return 1
shutil.move(os.path.join(extract_dir, real_src), dst)
shutil.move(os.path.join(bytes(extract_dir, "utf8"), real_src),
bytes(dst, "utf8"))
shutil.rmtree(extract_dir)
return 0
if __name__ == "__main__":
sys.exit(parse_args(UAdf))