__init__.py
1 # SPDX-FileCopyrightText: 2019 4am 2 # 3 # SPDX-License-Identifier: MIT 4 5 from .loggers import * 6 from .strings import * 7 from .util import * 8 from . import wozardry 9 import bitarray 10 import io 11 import json 12 import os.path 13 import time 14 15 class PassportGlobals: 16 def __init__(self): 17 # things about the disk 18 self.track = 0 # display purposes only 19 self.sector = 0 # display purposes only 20 self.last_track = 0 21 self.filename = None 22 23 class BasePassportProcessor: # base class 24 def __init__(self, filename, disk_image, logger_class=DefaultLogger, output_filename=None): 25 self.g = PassportGlobals() 26 self.g.filename = filename 27 self.g.output_filename = output_filename 28 self.g.disk_image = disk_image 29 self.g.logger = logger_class(self.g) 30 self.rwts = None 31 self.output_tracks = {} 32 self.burn = 0 33 if self.preprocess(): 34 if self.run(): 35 self.postprocess() 36 37 def preprocess(self): 38 return True 39 40 def run(self): 41 return True 42 43 def postprocess(self): 44 pass 45 46 class RawConvert(BasePassportProcessor): 47 def run(self): 48 self.g.logger.PrintByID("reading", {"filename":self.g.filename}) 49 50 self.tracks = {} 51 52 # main loop - loop through disk from track $22 down to track $00 53 for logical_track_num in range(0x22, -1, -1): 54 self.g.track = logical_track_num # for display purposes only 55 self.g.logger.debug("Seeking to track %s" % hex(self.g.track)) 56 57 for fractional_track in (0, .25, .5, .75): 58 59 physical_track_num = logical_track_num + fractional_track 60 track = self.g.disk_image.seek(physical_track_num) 61 if track and track.bits: 62 track.fix() 63 self.g.logger.debug("Writing to track %s + %.2f for %d bits" % (hex(self.g.track), fractional_track, len(track.bits))) 64 self.output_tracks[physical_track_num] = wozardry.Track(track.bits, len(track.bits)) 65 66 return True 67 68 def postprocess(self): 69 output_filename = self.g.output_filename 70 if output_filename is None: 71 source_base, source_ext = os.path.splitext(self.g.filename) 72 output_filename = source_base + '.woz' 73 self.g.logger.PrintByID("writing", {"filename":output_filename}) 74 75 woz_image = wozardry.WozDiskImage() 76 json_string = self.g.disk_image.to_json() 77 woz_image.from_json(json_string) 78 j = json.loads(json_string) 79 root = [x for x in j.keys()].pop() 80 woz_image.info["creator"] = STRINGS["header"].strip()[:32] 81 woz_image.info["synchronized"] = j[root]["info"]["synchronized"] 82 woz_image.info["cleaned"] = True #self.g.found_and_cleaned_weakbits 83 woz_image.info["write_protected"] = j[root]["info"]["write_protected"] 84 woz_image.meta["image_date"] = time.strftime("%Y-%m-%dT%H:%M:%S.000Z", time.gmtime()) 85 for q in range(1 + (0x23 * 4)): 86 physical_track_num = q / 4 87 if physical_track_num in self.output_tracks: 88 woz_image.add_track(physical_track_num, self.output_tracks[physical_track_num]) 89 try: 90 wozardry.WozDiskImage(io.BytesIO(bytes(woz_image))) 91 except Exception as e: 92 raise Exception from e 93 with open(output_filename, 'wb') as f: 94 f.write(bytes(woz_image))