mirror of
https://github.com/a2-4am/passport.py.git
synced 2024-06-10 03:29:29 +00:00
update to latest wozardry, copy as much metadata as possible when creating woz files
This commit is contained in:
parent
ae59d0d586
commit
5255a1a990
|
@ -31,7 +31,7 @@ class BaseCommand:
|
||||||
base, ext = os.path.splitext(args.file)
|
base, ext = os.path.splitext(args.file)
|
||||||
ext = ext.lower()
|
ext = ext.lower()
|
||||||
if ext == ".woz":
|
if ext == ".woz":
|
||||||
self.reader = wozardry.WozReader
|
self.reader = wozardry.WozDiskImage
|
||||||
elif ext == ".edd":
|
elif ext == ".edd":
|
||||||
self.reader = eddimage.EDDReader
|
self.reader = eddimage.EDDReader
|
||||||
elif ext == ".a2r":
|
elif ext == ".a2r":
|
||||||
|
@ -40,7 +40,8 @@ class BaseCommand:
|
||||||
print("unrecognized file type")
|
print("unrecognized file type")
|
||||||
if not self.logger:
|
if not self.logger:
|
||||||
self.logger = args.debug and DebugLogger or DefaultLogger
|
self.logger = args.debug and DebugLogger or DefaultLogger
|
||||||
self.processor(self.reader(args.file), self.logger)
|
with open(args.file, "rb") as f:
|
||||||
|
self.processor(args.file, self.reader(f), self.logger)
|
||||||
|
|
||||||
class CommandVerify(BaseCommand):
|
class CommandVerify(BaseCommand):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
|
@ -6,6 +6,8 @@ from passport.constants import *
|
||||||
from passport.util import *
|
from passport.util import *
|
||||||
from passport import wozardry
|
from passport import wozardry
|
||||||
import bitarray
|
import bitarray
|
||||||
|
import io
|
||||||
|
import json
|
||||||
import os.path
|
import os.path
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
@ -48,10 +50,12 @@ class PassportGlobals:
|
||||||
self.track = 0 # display purposes only
|
self.track = 0 # display purposes only
|
||||||
self.sector = 0 # display purposes only
|
self.sector = 0 # display purposes only
|
||||||
self.last_track = 0
|
self.last_track = 0
|
||||||
|
self.filename = None
|
||||||
|
|
||||||
class BasePassportProcessor: # base class
|
class BasePassportProcessor: # base class
|
||||||
def __init__(self, disk_image, logger_class=DefaultLogger):
|
def __init__(self, filename, disk_image, logger_class=DefaultLogger):
|
||||||
self.g = PassportGlobals()
|
self.g = PassportGlobals()
|
||||||
|
self.g.filename = filename
|
||||||
self.g.disk_image = disk_image
|
self.g.disk_image = disk_image
|
||||||
self.g.logger = logger_class(self.g)
|
self.g.logger = logger_class(self.g)
|
||||||
self.rwts = None
|
self.rwts = None
|
||||||
|
@ -571,7 +575,7 @@ class BasePassportProcessor: # base class
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.g.logger.PrintByID("header")
|
self.g.logger.PrintByID("header")
|
||||||
self.g.logger.PrintByID("reading", {"filename":self.g.disk_image.filename})
|
self.g.logger.PrintByID("reading", {"filename":self.g.filename})
|
||||||
supports_reseek = ("reseek" in dir(self.g.disk_image))
|
supports_reseek = ("reseek" in dir(self.g.disk_image))
|
||||||
|
|
||||||
# get raw track $00 data from the source disk
|
# get raw track $00 data from the source disk
|
||||||
|
@ -621,7 +625,7 @@ class BasePassportProcessor: # base class
|
||||||
|
|
||||||
if self.g.tried_univ:
|
if self.g.tried_univ:
|
||||||
if logical_track_num == 0x22 and (0x0F not in physical_sectors):
|
if logical_track_num == 0x22 and (0x0F not in physical_sectors):
|
||||||
self.g.logger.PrintByID("fail")
|
self.g.logger.PrintByID("fail", {"sector":0x0F})
|
||||||
self.g.logger.PrintByID("fatal220f")
|
self.g.logger.PrintByID("fatal220f")
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
|
@ -699,7 +703,7 @@ class Crack(Verify):
|
||||||
logical_sectors[patch.sector_num].decoded = b
|
logical_sectors[patch.sector_num].decoded = b
|
||||||
|
|
||||||
def postprocess(self):
|
def postprocess(self):
|
||||||
source_base, source_ext = os.path.splitext(self.g.disk_image.filename)
|
source_base, source_ext = os.path.splitext(self.g.filename)
|
||||||
output_filename = source_base + '.dsk'
|
output_filename = source_base + '.dsk'
|
||||||
self.g.logger.PrintByID("writing", {"filename":output_filename})
|
self.g.logger.PrintByID("writing", {"filename":output_filename})
|
||||||
with open(output_filename, "wb") as f:
|
with open(output_filename, "wb") as f:
|
||||||
|
@ -732,21 +736,26 @@ class Convert(BasePassportProcessor):
|
||||||
self.output_tracks[physical_track_num] = wozardry.Track(b, len(b))
|
self.output_tracks[physical_track_num] = wozardry.Track(b, len(b))
|
||||||
|
|
||||||
def postprocess(self):
|
def postprocess(self):
|
||||||
source_base, source_ext = os.path.splitext(self.g.disk_image.filename)
|
source_base, source_ext = os.path.splitext(self.g.filename)
|
||||||
output_filename = source_base + '.woz'
|
output_filename = source_base + '.woz'
|
||||||
self.g.logger.PrintByID("writing", {"filename":output_filename})
|
self.g.logger.PrintByID("writing", {"filename":output_filename})
|
||||||
woz_image = wozardry.WozWriter(STRINGS["header"].strip())
|
woz_image = wozardry.WozDiskImage()
|
||||||
woz_image.info["cleaned"] = self.g.found_and_cleaned_weakbits
|
json_string = self.g.disk_image.to_json()
|
||||||
woz_image.info["write_protected"] = self.g.protection_enforces_write_protected
|
woz_image.from_json(json_string)
|
||||||
|
j = json.loads(json_string)
|
||||||
|
root = [x for x in j.keys()].pop()
|
||||||
|
woz_image.info["creator"] = STRINGS["header"].strip()[:32]
|
||||||
|
woz_image.info["synchronized"] = j[root]["info"]["synchronized"]
|
||||||
|
woz_image.info["cleaned"] = True #self.g.found_and_cleaned_weakbits
|
||||||
|
woz_image.info["write_protected"] = self.g.protection_enforces_write_protected or j[root]["info"]["write_protected"]
|
||||||
woz_image.meta["image_date"] = time.strftime("%Y-%m-%dT%H:%M:%S.000Z", time.gmtime())
|
woz_image.meta["image_date"] = time.strftime("%Y-%m-%dT%H:%M:%S.000Z", time.gmtime())
|
||||||
for q in range(1 + (0x23 * 4)):
|
for q in range(1 + (0x23 * 4)):
|
||||||
physical_track_num = q / 4
|
physical_track_num = q / 4
|
||||||
if physical_track_num in self.output_tracks:
|
if physical_track_num in self.output_tracks:
|
||||||
woz_image.add_track(physical_track_num, self.output_tracks[physical_track_num])
|
woz_image.add_track(physical_track_num, self.output_tracks[physical_track_num])
|
||||||
with open(output_filename, 'wb') as f:
|
|
||||||
woz_image.write(f)
|
|
||||||
try:
|
try:
|
||||||
wozardry.WozReader(output_filename)
|
wozardry.WozDiskImage(io.BytesIO(bytes(woz_image)))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
os.remove(output_filename)
|
|
||||||
raise Exception from e
|
raise Exception from e
|
||||||
|
with open(output_filename, 'wb') as f:
|
||||||
|
f.write(bytes(woz_image))
|
||||||
|
|
|
@ -6,12 +6,14 @@ import collections
|
||||||
class A2RSeekError(a2rchery.A2RError): pass
|
class A2RSeekError(a2rchery.A2RError): pass
|
||||||
|
|
||||||
class A2RImage:
|
class A2RImage:
|
||||||
def __init__(self, filename=None, stream=None):
|
def __init__(self, iostream):
|
||||||
self.filename = filename
|
|
||||||
self.tracks = collections.OrderedDict()
|
self.tracks = collections.OrderedDict()
|
||||||
self.a2r_image = a2rchery.A2RReader(filename, stream)
|
self.a2r_image = a2rchery.A2RReader(stream=iostream)
|
||||||
self.speed = 32
|
self.speed = 32
|
||||||
|
|
||||||
|
def to_json(self):
|
||||||
|
return self.a2r_image.to_json()
|
||||||
|
|
||||||
def to_bits(self, flux_record):
|
def to_bits(self, flux_record):
|
||||||
"""|flux_record| is a dictionary of 'capture_type', 'data_length', 'tick_count', and 'data'"""
|
"""|flux_record| is a dictionary of 'capture_type', 'data_length', 'tick_count', and 'data'"""
|
||||||
bits = bitarray.bitarray()
|
bits = bitarray.bitarray()
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
from passport.wozardry import Track, raise_if
|
from passport.wozardry import Track, raise_if
|
||||||
import bitarray
|
import bitarray
|
||||||
|
import json
|
||||||
|
|
||||||
class EDDError(Exception): pass # base class
|
class EDDError(Exception): pass # base class
|
||||||
class EDDLengthError(EDDError): pass
|
class EDDLengthError(EDDError): pass
|
||||||
class EDDSeekError(EDDError): pass
|
class EDDSeekError(EDDError): pass
|
||||||
|
|
||||||
class EDDReader:
|
class EDDReader:
|
||||||
def __init__(self, filename=None, stream=None):
|
def __init__(self, iostream):
|
||||||
DiskImage.__init__(self, filename, stream)
|
|
||||||
with stream or open(filename, 'rb') as f:
|
|
||||||
for i in range(137):
|
for i in range(137):
|
||||||
raw_bytes = f.read(16384)
|
raw_bytes = iostream.read(16384)
|
||||||
raise_if(len(raw_bytes) != 16384, EDDLengthError, "Bad EDD file (did you image by quarter tracks?)")
|
raise_if(len(raw_bytes) != 16384, EDDLengthError, "Bad EDD file (did you image by quarter tracks?)")
|
||||||
bits = bitarray.bitarray(endian="big")
|
bits = bitarray.bitarray(endian="big")
|
||||||
bits.frombytes(raw_bytes)
|
bits.frombytes(raw_bytes)
|
||||||
|
@ -25,3 +24,15 @@ class EDDReader:
|
||||||
raise EDDSeekError("Invalid track %s" % track_num)
|
raise EDDSeekError("Invalid track %s" % track_num)
|
||||||
trk_id = int(track_num * 4)
|
trk_id = int(track_num * 4)
|
||||||
return self.tracks[trk_id]
|
return self.tracks[trk_id]
|
||||||
|
|
||||||
|
def to_json(self):
|
||||||
|
j = {"edd":
|
||||||
|
{"info":
|
||||||
|
{"synchronized":False,
|
||||||
|
"write_protected":False,
|
||||||
|
"cleaned":False
|
||||||
|
},
|
||||||
|
"meta":{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return json.dumps(j, indent=2)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
__date__ = "2019-02-17"
|
__date__ = "2019-03-03"
|
||||||
|
|
||||||
STRINGS = {
|
STRINGS = {
|
||||||
"header": "Passport.py by 4am (" + __date__ + ")\n", # max 32 characters
|
"header": "Passport.py by 4am (" + __date__ + ")\n", # max 32 characters
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user