diff options
-rwxr-xr-x | backend/raw_write.py | 271 | ||||
-rwxr-xr-x | lib/isodumper.py | 740 | ||||
-rwxr-xr-x | lib/raw_format.py | 40 |
3 files changed, 698 insertions, 353 deletions
diff --git a/backend/raw_write.py b/backend/raw_write.py index fe0fda9..b30f759 100755 --- a/backend/raw_write.py +++ b/backend/raw_write.py @@ -1,4 +1,4 @@ -#coding:utf-8 +# coding:utf-8 #!/usr/bin/python3 # @@ -27,6 +27,7 @@ import gettext import hashlib import io import logging + ########### # imports # ########### @@ -38,17 +39,16 @@ from subprocess import Popen, PIPE class Dumper(object): - - def _do_write(self,source,target, b, backup_mode, uid, gid): + def _do_write(self, source, target, b, backup_mode, uid, gid): # Writing step - #Dump mode - self.returncode=0 - self.operation=True - bs=4096*128 + # Dump mode + self.returncode = 0 + self.operation = True + bs = 4096 * 128 try: - ifc=io.open(source, "rb",1) + ifc = io.open(source, "rb", 1) except: - message = _('Reading error.')+ source + message = _("Reading error.") + source logging.debug(message) self.return_state = False self.return_message = message @@ -56,27 +56,29 @@ class Dumper(object): return else: try: - ofc= io.open(target, 'wb',0) + ofc = io.open(target, "wb", 0) except: - message = _("You don't have permission to write to the device {}").format(target) - logging.error(message) - self.return_state = False - self.return_message = message - self.finished.set() - return + message = _( + "You don't have permission to write to the device {}" + ).format(target) + logging.error(message) + self.return_state = False + self.return_message = message + self.finished.set() + return else: - self.operation=True - steps=list(range(0, b+1, int(b/100))) + self.operation = True + steps = list(range(0, b + 1, int(b / 100))) steps.append(b) - indice=1 - written=0 - ncuts=int(b/bs) + indice = 1 + written = 0 + ncuts = int(b / bs) while ncuts <= 100: - bs=int(bs/2) - ncuts=int(b/bs) - for i in range(0,int(ncuts)+1): + bs = int(bs / 2) + ncuts = int(b / bs) + for i in range(0, int(ncuts) + 1): try: - buf=ifc.read(bs) + buf = ifc.read(bs) except: message = _("Reading error.") logging.error(message) @@ -93,31 +95,31 @@ class Dumper(object): self.return_message = message self.finished.set() return - written+=len(buf) + written += len(buf) if written > steps[indice]: - if indice%1==0: + if indice % 1 == 0: self._progress = indice - indice +=1 + indice += 1 try: os.fsync(ofc) except: - message = _("Writing error.") - logging.debug(message) - self.return_state = False - self.return_message = message - self.finished.set() - return + message = _("Writing error.") + logging.debug(message) + self.return_state = False + self.return_message = message + self.finished.set() + return if backup_mode: # Restore user as owner os.chown(target, uid, gid) try: ofc.close() except: - message = _("Writing error.") - logging.error(message) - self.return_message = message - self.return_state = False - return + message = _("Writing error.") + logging.error(message) + self.return_message = message + self.return_state = False + return ifc.close() self._progress = 100 self.return_state = True @@ -131,106 +133,115 @@ class Dumper(object): self.return_message = "" b = os.path.getsize(source) # Compute the sum from the written device - steps=list(range(0, b+1, int(b/100))) + steps = list(range(0, b + 1, int(b / 100))) steps.append(b) - indice=0 - checked=0 - sha512func=hashlib.sha3_512() - ncuts=int(b/1024) - with open(target, 'rb') as f: - for x in range(0,ncuts): + indice = 0 + checked = 0 + sha512func = hashlib.sha3_512() + ncuts = int(b / 1024) + with open(target, "rb") as f: + for x in range(0, ncuts): block = f.read(1024) sha512func.update(block) if checked > steps[indice]: self._progress = indice - indice +=1 - checked+=1024 - logging.debug("last read %d"%(b-ncuts*1024)) - block = f.read(b-ncuts*1024) + indice += 1 + checked += 1024 + logging.debug("last read %d" % (b - ncuts * 1024)) + block = f.read(b - ncuts * 1024) sha512func.update(block) - sha512sumcalc=sha512func.hexdigest().upper() + sha512sumcalc = sha512func.hexdigest().upper() self.sum_check = "" sum_type = "sha3" sum_file = f"{source}.{sum_type}" try: # Look for sum files in the same directory as source - with open(sum_file,'r') as fs: + with open(sum_file, "r") as fs: # Read the sum in the file - self.sum_check=(fs.readline()).split()[0] + self.sum_check = (fs.readline()).split()[0] self.sum_file = True except: logging.info(_("Sum file {} not found\n").format(sum_file)) self.sum_file = False self.return_state = True - if (self.sum_check == "") : # Can't get stored sum - self.return_message += _('SHA3 sum: {}').format(sha512sumcalc) + if self.sum_check == "": # Can't get stored sum + self.return_message += _("SHA3 sum: {}").format(sha512sumcalc) # compare the sums - elif (sha512sumcalc == self.sum_check) : - #, keep the bracket, this is the place for sum type - self.return_message +="\n" + _("The {} sum check is OK").format(sum_type) + elif sha512sumcalc == self.sum_check: + # , keep the bracket, this is the place for sum type + self.return_message += "\n" + _("The {} sum check is OK").format(sum_type) else: - self.return_message +="\n" + _("/!\\The computed and stored sums don't match") + self.return_message += "\n" + _( + "/!\\The computed and stored sums don't match" + ) self.return_state = False self._progress = 100 logging.info(self.return_message) self.finished.set() def udev_wait(self, operation): - wait = Popen(["udevadm","settle","--timeout=15"], stderr=PIPE) + wait = Popen(["udevadm", "settle", "--timeout=15"], stderr=PIPE) wait.communicate() - working=True + working = True while working: time.sleep(0.5) wait.poll() - rc=wait.returncode + rc = wait.returncode if not (rc is None): wait = None - working= False + working = False if rc != 0: self.return_state = False self.return_message = _("Timeout reached when {}".format(operation)) return False return True - def _do_persistence(self, target, label, key): logging.debug("Start doing persistence partition") - p = Popen(["fdisk",target], stdin = PIPE, stderr=PIPE) - outs, errs = p.communicate(input=b'n\np\n3\n\n\nw\n') - working=True + p = Popen(["fdisk", target], stdin=PIPE, stderr=PIPE) + outs, errs = p.communicate(input=b"n\np\n3\n\n\nw\n") + working = True while working: time.sleep(0.5) p.poll() - rc=p.returncode + rc = p.returncode if rc is None: - working=True + working = True else: process = None - working= False + working = False if rc != 0: if rc == 1: # the error is Re-reading the partition table failed.: Device or resource busy - logging.error(_("Error {} while doing persistent partition: {}").format(rc, errs.decode('utf-8'))) + logging.error( + _("Error {} while doing persistent partition: {}").format( + rc, errs.decode("utf-8") + ) + ) logging.error(_("Try reloading partition table")) - p = Popen(["partprobe",target], stdin = PIPE, stderr=PIPE) + p = Popen(["partprobe", target], stdin=PIPE, stderr=PIPE) outs, errs = p.communicate() - working=True + working = True while working: time.sleep(0.5) p.poll() - rc=p.returncode + rc = p.returncode if not (rc is None): process = None - working= False + working = False else: self.return_state = False - self.return_message = _("Unable to reload the partition table: {}").format(errs.decode('utf-8')) + self.return_message = _( + "Unable to reload the partition table: {}" + ).format(errs.decode("utf-8")) logging.error(self.return_message) self.finished.set() return else: self.return_state = False - self.return_message = _("Error {} while doing persistent partition: {}").format(rc, errs.decode('utf-8')) + self.return_message = _( + "Error {} while doing persistent partition: {}" + ).format(rc, errs.decode("utf-8")) logging.error(self.return_message) self.finished.set() return @@ -243,25 +254,29 @@ class Dumper(object): if key == "": # example mkfs.ext4 -L mgalive-persist /dev/sdf3 self.return_message = _("Persistent partition added. Formatting...") - process = Popen(['mkfs.ext4', "-q",'-F','-L', label, target+"3"],stderr=PIPE) + process = Popen( + ["mkfs.ext4", "-q", "-F", "-L", label, target + "3"], stderr=PIPE + ) outs, errs = process.communicate() - working=True + working = True while working: time.sleep(0.5) process.poll() - rc=process.returncode + rc = process.returncode if rc is None: - working=True + working = True else: process = None - working= False + working = False if rc == 0: self.return_state = True self._progress = 100 self.return_message = _("Persistent partition done") else: self.return_state = False - self.return_message = _("Error {} while doing persistent partition: {}").format(rc, errs.decode('utf-8')) + self.return_message = _( + "Error {} while doing persistent partition: {}" + ).format(rc, errs.decode("utf-8")) self.finished.set() return logging.info("Persistent partition done") @@ -271,21 +286,27 @@ class Dumper(object): # example cryptsetup luksFormat /dev/sdb3 self.return_message = _("Persistent partition added. Encrypting...") base_target = os.path.basename(target) + "3" - process = Popen(['cryptsetup','luksFormat','-q', target+"3", '-d', '-'],stdin=PIPE, stderr=PIPE) - outs, errs = process.communicate(input=key.encode('utf-8')) - working=True + process = Popen( + ["cryptsetup", "luksFormat", "-q", target + "3", "-d", "-"], + stdin=PIPE, + stderr=PIPE, + ) + outs, errs = process.communicate(input=key.encode("utf-8")) + working = True while working: time.sleep(0.5) process.poll() - rc=process.returncode + rc = process.returncode if rc is None: - working=True + working = True else: process = None - working= False + working = False if rc != 0: self.return_state = False - self.return_message = _("Error {} while doing persistent partition: {}").format(rc, errs.decode('utf-8')) + self.return_message = _( + "Error {} while doing persistent partition: {}" + ).format(rc, errs.decode("utf-8")) logging.error(self.return_message) self.finished.set() return @@ -295,21 +316,34 @@ class Dumper(object): if not self.udev_wait("creating encrypted partition"): return - process = Popen(['cryptsetup','luksOpen', target + "3", 'crypt_' + base_target ,'-d','-'],stdin=PIPE, stderr=PIPE) - outs, errs = process.communicate(input=key.encode('utf-8')) - working=True + process = Popen( + [ + "cryptsetup", + "luksOpen", + target + "3", + "crypt_" + base_target, + "-d", + "-", + ], + stdin=PIPE, + stderr=PIPE, + ) + outs, errs = process.communicate(input=key.encode("utf-8")) + working = True while working: time.sleep(0.5) process.poll() - rc=process.returncode + rc = process.returncode if rc is None: - working=True + working = True else: process = None - working= False + working = False if rc != 0: self.return_state = False - self.return_message = _("Error {} while doing persistent partition: {}").format(rc, errs.decode('utf-8')) + self.return_message = _( + "Error {} while doing persistent partition: {}" + ).format(rc, errs.decode("utf-8")) logging.error(self.return_message) self.finished.set() return @@ -319,21 +353,33 @@ class Dumper(object): self._progress = 60 self.return_message = _("Persistent partition opened. Formatting...") # mkfs.ext4 -L mgalive-persist /dev/mapper/crypt_sdb3 - process = Popen(['mkfs.ext4','-q','-F','-L', label, '/dev/mapper/crypt_' + base_target],stderr=PIPE) + process = Popen( + [ + "mkfs.ext4", + "-q", + "-F", + "-L", + label, + "/dev/mapper/crypt_" + base_target, + ], + stderr=PIPE, + ) outs, errs = process.communicate() - working=True + working = True while working: time.sleep(0.5) process.poll() - rc=process.returncode + rc = process.returncode if rc is None: - working=True + working = True else: process = None - working= False + working = False if rc != 0: self.return_state = False - self.return_message = _("Error {} while doing persistent partition: {}").format(rc, errs.decode('utf-8')) + self.return_message = _( + "Error {} while doing persistent partition: {}" + ).format(rc, errs.decode("utf-8")) logging.error(self.return_message) self.finished.set() return @@ -342,21 +388,23 @@ class Dumper(object): if not self.udev_wait(_("formatting encrypted partition")): return - process = Popen(['cryptsetup','luksClose', 'crypt_' + base_target ]) + process = Popen(["cryptsetup", "luksClose", "crypt_" + base_target]) outs, errs = process.communicate() - working=True + working = True while working: time.sleep(0.5) process.poll() - rc=process.returncode + rc = process.returncode if rc is None: - working=True + working = True else: process = None - working= False + working = False if rc != 0: self.return_state = False - self.return_message = _("Error {} while doing persistent partition: {}").format(rc, errs.decode('utf-8')) + self.return_message = _( + "Error {} while doing persistent partition: {}" + ).format(rc, errs.decode("utf-8")) logging.error(self.return_message) else: self.return_state = True @@ -368,8 +416,7 @@ class Dumper(object): self.finished.set() logging.debug("Finished") - def __init__(self): - gettext.install('isodumper', localedir='/usr/share/locale') + gettext.install("isodumper", localedir="/usr/share/locale") # Operation running - self.operation=False + self.operation = False diff --git a/lib/isodumper.py b/lib/isodumper.py index aef0f93..2df00fa 100755 --- a/lib/isodumper.py +++ b/lib/isodumper.py @@ -28,6 +28,7 @@ import sys import importlib + try: from isodumper import version except: @@ -63,9 +64,9 @@ class NoUDisks2(Exception): class UDisks2(object): - BLOCK = 'org.freedesktop.UDisks2.Block' - DRIVE = 'org.freedesktop.UDisks2.Drive' - SERVICE = 'org.freedesktop.UDisks2' + BLOCK = "org.freedesktop.UDisks2.Block" + DRIVE = "org.freedesktop.UDisks2.Drive" + SERVICE = "org.freedesktop.UDisks2" def __init__(self): self.bus = SystemBus() @@ -79,31 +80,40 @@ class UDisks2(object): objects = self._udisks2_obj_manager.GetManagedObjects() re_drive = re.compile("(?P<path>.*?/drives/(?P<id>.*))") re_block = re.compile("(?P<path>.*?/block_devices/(?P<id>.*))") - devs = [m.groupdict() for m in - [re_drive.match(path) for path in (objects.keys())] - if m] - blocks = [m.groupdict() for m in - [re_block.match(path) for path in (objects.keys())] - if m] + devs = [ + m.groupdict() + for m in [re_drive.match(path) for path in (objects.keys())] + if m + ] + blocks = [ + m.groupdict() + for m in [re_block.match(path) for path in (objects.keys())] + if m + ] list = [] for block in blocks: - if not (self.SERVICE + '.Partition' in objects[block['path']]): # we skip partition blocks + if not ( + self.SERVICE + ".Partition" in objects[block["path"]] + ): # we skip partition blocks for dev in devs: - if dev['path'] == objects[block['path']][self.BLOCK]['Drive']: + if dev["path"] == objects[block["path"]][self.BLOCK]["Drive"]: # we look for device which is referenced in Drive attribute of the current block - dev_obj = objects[dev['path']][self.DRIVE] - if (dev_obj['ConnectionBus'] == 'usb' or dev_obj['ConnectionBus'] == 'sdio') and \ - (dev_obj['Removable'] == 1 or dev_obj[ - 'MediaRemovable'] == 1): # we keep only blocks where device ConnectionBus is sdio or usb + dev_obj = objects[dev["path"]][self.DRIVE] + if ( + dev_obj["ConnectionBus"] == "usb" + or dev_obj["ConnectionBus"] == "sdio" + ) and ( + dev_obj["Removable"] == 1 or dev_obj["MediaRemovable"] == 1 + ): # we keep only blocks where device ConnectionBus is sdio or usb item = [] - vend = dev_obj['Vendor'] + vend = dev_obj["Vendor"] if vend == "": - name = dev_obj['Model'] + name = dev_obj["Model"] else: - name = vend + " " + dev_obj['Model'] - path = '/dev/' + block['path'].split('/')[-1] - size = dev_obj['Size'] + name = vend + " " + dev_obj["Model"] + path = "/dev/" + block["path"].split("/")[-1] + size = dev_obj["Size"] item.append(name) item.append(path) item.append(size) @@ -114,76 +124,110 @@ class UDisks2(object): # keep only the end, like sdb target = os.path.basename(target) objects = self._udisks2_obj_manager.GetManagedObjects() - re_block = re.compile('(?P<path>.*?/block_devices/(?P<id>.*))') - blocks = [m.groupdict() for m in - [re_block.match(path) for path in (objects.keys())] - if m] + re_block = re.compile("(?P<path>.*?/block_devices/(?P<id>.*))") + blocks = [ + m.groupdict() + for m in [re_block.match(path) for path in (objects.keys())] + if m + ] for block in blocks: - if (self.SERVICE + '.Partition' in objects[block['path']]): # we skip non partition blocks + if ( + self.SERVICE + ".Partition" in objects[block["path"]] + ): # we skip non partition blocks # Table should be something like '/org/freedesktop/UDisks2/block_devices/sdb' - if objects[block['path']][self.SERVICE + '.Partition']['Table'].split('/')[-1] == target: - if (self.SERVICE + '.Encrypted' in objects[block['path']]): # Is the partition encrypted ? - path_to_encrypted = objects[block['path']][self.SERVICE + '.Encrypted']['CleartextDevice'] - if path_to_encrypted != '/': + if ( + objects[block["path"]][self.SERVICE + ".Partition"]["Table"].split( + "/" + )[-1] + == target + ): + if ( + self.SERVICE + ".Encrypted" in objects[block["path"]] + ): # Is the partition encrypted ? + path_to_encrypted = objects[block["path"]][ + self.SERVICE + ".Encrypted" + ]["CleartextDevice"] + if path_to_encrypted != "/": iface = self.bus.get(self.SERVICE, path_to_encrypted) - fs = iface[self.SERVICE + '.Filesystem'] + fs = iface[self.SERVICE + ".Filesystem"] if fs.MountPoints: # partition is mounted try: fs.Unmount({}) except GLib.GError as e: print(str(e)) - return False, _("A partition is busy. Try to free it before starting again.") + return False, _( + "A partition is busy. Try to free it before starting again." + ) except: raise Exception(str(e)) - iface = self.bus.get(self.SERVICE, block['path']) - fs = iface[self.SERVICE + '.Encrypted'] + iface = self.bus.get(self.SERVICE, block["path"]) + fs = iface[self.SERVICE + ".Encrypted"] fs.Lock({}) logging.debug(f"Unmounting encryted {block['path']}") else: - iface = self.bus.get(self.SERVICE, block['path']) - if self.SERVICE + '.Filesystem' in objects[block['path']]: - fs = iface[self.SERVICE + '.Filesystem'] + iface = self.bus.get(self.SERVICE, block["path"]) + if self.SERVICE + ".Filesystem" in objects[block["path"]]: + fs = iface[self.SERVICE + ".Filesystem"] if fs.MountPoints: # partition is mounted logging.debug(f"Unmounting {block['path']}") try: fs.Unmount({}) except GLib.GError as e: print(str(e)) - return False, _("A partition is busy. Try to free it before starting again.") + return False, _( + "A partition is busy. Try to free it before starting again." + ) except: raise Exception(str(e)) else: logging.debug(f"Not mounted {block['path']}") return True, "" - def get_partitions(self, target): # keep only the end, like sdb target = os.path.basename(target) partitions = [] objects = self._udisks2_obj_manager.GetManagedObjects() - re_block = re.compile('(?P<path>.*?/block_devices/(?P<id>.*))') - blocks = [m.groupdict() for m in - [re_block.match(path) for path in (objects.keys())] - if m] + re_block = re.compile("(?P<path>.*?/block_devices/(?P<id>.*))") + blocks = [ + m.groupdict() + for m in [re_block.match(path) for path in (objects.keys())] + if m + ] for block in blocks: - if (self.SERVICE + '.Partition' in objects[block['path']]): # we skip non partition blocks + if ( + self.SERVICE + ".Partition" in objects[block["path"]] + ): # we skip non partition blocks # Table should be something like '/org/freedesktop/UDisks2/block_devices/sdb' - if objects[block['path']][self.SERVICE + '.Partition']['Table'].split('/')[-1] == target: - partition = objects[block['path']][self.SERVICE + '.Block'] - partitions.append( {'device': bytes(partition['Device']).decode("UTF-8", "replace").strip("\0"), - 'label': partition['IdLabel'], - 'type': partition['IdType']}) + if ( + objects[block["path"]][self.SERVICE + ".Partition"]["Table"].split( + "/" + )[-1] + == target + ): + partition = objects[block["path"]][self.SERVICE + ".Block"] + partitions.append( + { + "device": bytes(partition["Device"]) + .decode("UTF-8", "replace") + .strip("\0"), + "label": partition["IdLabel"], + "type": partition["IdType"], + } + ) return partitions def eject(self, device): - ''' device is expected like /dev/sda''' + """device is expected like /dev/sda""" block = os.path.basename(device) - iface = self.bus.get(self.SERVICE, '/org/freedesktop/UDisks2/block_devices/' + block) + iface = self.bus.get( + self.SERVICE, "/org/freedesktop/UDisks2/block_devices/" + block + ) drive = iface.Get(self.BLOCK, "Drive") i_drive = self.bus.get(self.SERVICE, drive) i_drive.Eject({}) + class Info(object): def __init__(self, title, richtext, text): self.title = title @@ -197,7 +241,6 @@ class ParseCLI(args.AppArgs): class IsoDumper(basedialog.BaseDialog): - def get_devices(self, selected=None): self.list = self.u.find_devices() while len(self.list) == 0: @@ -246,7 +289,7 @@ class IsoDumper(basedialog.BaseDialog): def update_list_on_event(self): selitem = self.devicelist.selectedItem().label() self.devicelist.deleteAllItems() - self.get_devices(selected = selitem) + self.get_devices(selected=selitem) if self.devicelist.selectedItem().label() != selitem: self.restore() @@ -265,18 +308,24 @@ class IsoDumper(basedialog.BaseDialog): for name, path, size in self.list: if self.dev == self.device_label(name, path, size): self.deviceSize = size - self.device_name = name.rstrip().replace(' ', '') - message = _('Target Device: {}').format(self.dev) + self.device_name = name.rstrip().replace(" ", "") + message = _("Target Device: {}").format(self.dev) self.logger(message) logging.info(message) - partitions = self.u.get_partitions(self.dev.split('(')[1].split(')')[0]) + partitions = self.u.get_partitions( + self.dev.split("(")[1].split(")")[0] + ) # I18N: verb in singular 3rd person self.logger(_("Contains this/these partition(s)")) # I18N: don't translate keywords inside braces {} for partition in partitions: - self.logger(_("{device}: Type={type}, Label={label}").format(device=partition['device'], - type=partition['type'], - label=partition['label'],)) + self.logger( + _("{device}: Type={type}, Label={label}").format( + device=partition["device"], + type=partition["type"], + label=partition["label"], + ) + ) if len(partitions) == 0: # I18N: None refers to partition (no partitions on the selected device) self.logger(_("None")) @@ -300,17 +349,19 @@ class IsoDumper(basedialog.BaseDialog): @staticmethod def sizeof_fmt(num): # I18N these are units for files size - for unit in [_('B'), _('KiB'), _('MiB'), _('GiB'), _('TiB')]: + for unit in [_("B"), _("KiB"), _("MiB"), _("GiB"), _("TiB")]: if abs(num) < 1024.0: return "%3.3f %s" % (num, unit) num /= 1024.0 - return "%.1f %s" % (num, _('TiB')) + return "%.1f %s" % (num, _("TiB")) def backup_choosed(self): # Add .img if not specified - self.backup_img_name = yui.YUI.app().askForSaveFileName("", "*.img", _("Backup to:")) - if self.backup_img_name != '': - if not self.backup_img_name.lower().endswith('.img'): + self.backup_img_name = yui.YUI.app().askForSaveFileName( + "", "*.img", _("Backup to:") + ) + if self.backup_img_name != "": + if not self.backup_img_name.lower().endswith(".img"): self.backup_img_name = self.backup_img_name + ".img" head, tail = os.path.split(self.backup_img_name) self.backup_dest = self.backup_img_name @@ -327,10 +378,10 @@ class IsoDumper(basedialog.BaseDialog): logging.debug("Starting getting sum") # Check if the sum file has a valid signature gpg = gnupg.GPG() - gpg.encoding = 'utf-8' + gpg.encoding = "utf-8" # Use Mageia public key mageia_keyid = "835E41F4EDCA7A90" - self.sum_type = 'sha3' + self.sum_type = "sha3" sig_file = "{}.{}.gpg".format(source, self.sum_type) self.source_file = "{}.{}".format(source, self.sum_type) try: @@ -340,10 +391,12 @@ class IsoDumper(basedialog.BaseDialog): logging.error(str(e)) logging.info(_("GPG signatures database can not be read")) return - key_present = False + key_present = False for entry in keys_list: - if (mageia_keyid == entry['keyid']): - if entry['expires'] and (datetime.datetime.now().timestamp() > float(entry['expires'])): + if mageia_keyid == entry["keyid"]: + if entry["expires"] and ( + datetime.datetime.now().timestamp() > float(entry["expires"]) + ): logging.info("Mageia key expired, reloading") else: logging.info("Mageia key already present") @@ -351,9 +404,9 @@ class IsoDumper(basedialog.BaseDialog): break try: if not key_present: - gpg.recv_keys('keyserver.ubuntu.com', mageia_keyid) + gpg.recv_keys("keyserver.ubuntu.com", mageia_keyid) self.sum_check_searched = True - with open(sig_file, 'rb') as g: + with open(sig_file, "rb") as g: self.signature_found = True verified = gpg.verify_file(g, close_file=False) if verified: @@ -372,34 +425,46 @@ class IsoDumper(basedialog.BaseDialog): except Exception as e: self.signature_found = False logging.error(str(e)) - logging.info(_("Signature file {} not found\n" + _("or key expired")).format(sig_file)) + logging.info( + _("Signature file {} not found\n" + _("or key expired")).format( + sig_file + ) + ) def do_format(self): - #code, format_type, name = self.ask_format() + # code, format_type, name = self.ask_format() if self.partition_cb.value() != "": self.operation = True - format_type = list(self.format_type.keys())[list(self.format_type.values()).index(self.partition_cb.value())] - if format_type == 'persist': - self.emergency(_("Persistence partition is to use when writing a Live ISO image.")) + format_type = list(self.format_type.keys())[ + list(self.format_type.values()).index(self.partition_cb.value()) + ] + if format_type == "persist": + self.emergency( + _("Persistence partition is to use when writing a Live ISO image.") + ) return - target = self.dev.split('(')[1].split(')')[0] - info = Info(_("Formatting confirmation in {}".format(self.partition_cb.value())), True, self.warning) + target = self.dev.split("(")[1].split(")")[0] + info = Info( + _("Formatting confirmation in {}".format(self.partition_cb.value())), + True, + self.warning, + ) if self.ask_YesOrNo(info): name = self.partition_label.value() - if format_type == 'fat32': + if format_type == "fat32": name = name.upper()[:11] - elif format_type == 'exfat' or format_type == 'ntfs': + elif format_type == "exfat" or format_type == "ntfs": name = name[:32] rc = self.raw_format(target, format_type, name) self.operation = False if rc == 0: - return True, _('The device was formatted successfully.') + return True, _("The device was formatted successfully.") elif rc == 5: return False, _("An error occurred while creating a partition.") elif rc == 127: - return False, _('Authentication error.') + return False, _("Authentication error.") else: - return False, _('An error {} occurred.'.format(rc)) + return False, _("An error {} occurred.".format(rc)) def initial_state(self): self.update_list() @@ -432,16 +497,49 @@ class IsoDumper(basedialog.BaseDialog): self.udev_wait(_("unmounting")) self.operation = True if os.geteuid() > 0: - launcher = 'pkexec' + launcher = "pkexec" self.process = Popen( - [launcher, '/usr/bin/python3', '-u', '/usr/lib/isodumper/raw_format.py', '-d', usb_path, '-f', fstype, - '-l', label, '-u', str(os.geteuid()), '-g', str(os.getgid())], shell=False, stdout=PIPE, - preexec_fn=os.setsid) + [ + launcher, + "/usr/bin/python3", + "-u", + "/usr/lib/isodumper/raw_format.py", + "-d", + usb_path, + "-f", + fstype, + "-l", + label, + "-u", + str(os.geteuid()), + "-g", + str(os.getgid()), + ], + shell=False, + stdout=PIPE, + preexec_fn=os.setsid, + ) else: self.process = Popen( - ['/usr/bin/python3', '-u', '/usr/lib/isodumper/raw_format.py', '-d', usb_path, '-f', fstype, '-l', - label, '-u', str(os.geteuid()), '-g', str(os.getgid())], shell=False, stdout=PIPE, - preexec_fn=os.setsid) + [ + "/usr/bin/python3", + "-u", + "/usr/lib/isodumper/raw_format.py", + "-d", + usb_path, + "-f", + fstype, + "-l", + label, + "-u", + str(os.geteuid()), + "-g", + str(os.getgid()), + ], + shell=False, + stdout=PIPE, + preexec_fn=os.setsid, + ) working = True while working: time.sleep(0.5) @@ -461,7 +559,9 @@ class IsoDumper(basedialog.BaseDialog): self.progress.setLabel(_("Backup")) dest = self.backup_img_name if os.path.exists(dest): - info = Info(_("Backup confirmation"), True, _("Do you want to overwrite the file?")) + info = Info( + _("Backup confirmation"), True, _("Do you want to overwrite the file?") + ) if not (self.ask_YesOrNo(info)): self.returncode = 1 return False @@ -469,7 +569,9 @@ class IsoDumper(basedialog.BaseDialog): free = st.f_bavail * st.f_frsize if free < self.deviceSize: sizeM = str(self.deviceSize / (1024 * 1024)) - message = _("The destination directory is too small to receive the backup (%s Mb needed)") % (sizeM) + message = _( + "The destination directory is too small to receive the backup (%s Mb needed)" + ) % (sizeM) self.logger(message) logging.warning(message) self.emergency(message) @@ -478,8 +580,8 @@ class IsoDumper(basedialog.BaseDialog): else: self.operation = True self.returncode = 0 - source = self.dev.split('(')[1].split(')')[0] - message = _('Backup to: {}').format(dest) + source = self.dev.split("(")[1].split(")")[0] + message = _("Backup to: {}").format(dest) self.logger(message) logging.info(message) # Writing step @@ -491,14 +593,16 @@ class IsoDumper(basedialog.BaseDialog): progress = self.iface.progress self.progress.setValue(progress) self.dialog.pollEvent() - time.sleep(.2) + time.sleep(0.2) success, message = self.iface.end() if not success: self.emergency(message) self.initial_state() return False, message # I18N: don't translate source nor target - return True, _('{source} successfully written to {target}').format(source=source.split('/')[-1], target=dest) + return True, _("{source} successfully written to {target}").format( + source=source.split("/")[-1], target=dest + ) def do_write(self): self.init_iface() @@ -506,10 +610,10 @@ class IsoDumper(basedialog.BaseDialog): self.progress.setEnabled() self.progress.setLabel("Writing") source = self.img_name - target = self.dev.split('(')[1].split(')')[0] + target = self.dev.split("(")[1].split(")")[0] b = os.path.getsize(source) if b > (self.deviceSize): - message = _('The device is too small to contain the ISO file.') + message = _("The device is too small to contain the ISO file.") self.logger(message) logging.error(message) self.emergency(message) @@ -517,16 +621,26 @@ class IsoDumper(basedialog.BaseDialog): info = Info(_("Writing confirmation"), True, self.warning) if self.ask_YesOrNo(info): if self.deviceSize > 1024 * 1024 * 1024 * 32: - info = Info(_("Warning"), True, - _('The device is bigger than 32 Gbytes. Are you sure you want use it?')) + info = Info( + _("Warning"), + True, + _( + "The device is bigger than 32 Gbytes. Are you sure you want use it?" + ), + ) if self.ask_YesOrNo(info): pass else: return # I18N: don't translate source nor target - self.progress.setLabel(_('Writing {source} to {target}').format(source=source.split('/')[-1], - target=target.split('/')[-1])) - message = _('Executing copy from {source} to {target}').format(source=source, target=target) + self.progress.setLabel( + _("Writing {source} to {target}").format( + source=source.split("/")[-1], target=target.split("/")[-1] + ) + ) + message = _("Executing copy from {source} to {target}").format( + source=source, target=target + ) self.operation = True self.logger(message) logging.info(message) @@ -540,16 +654,17 @@ class IsoDumper(basedialog.BaseDialog): progress = self.iface.progress self.progress.setValue(progress) self.dialog.pollEvent() - time.sleep(.5) + time.sleep(0.5) success, message = self.iface.end() if success: # I18N: don't translate source nor target - message = _('Image {source} written to {target}').format(source=source.split('/')[-1], - target=target) - message += "\n" + _('Bytes written: {}').format(str(b)) + message = _("Image {source} written to {target}").format( + source=source.split("/")[-1], target=target + ) + message += "\n" + _("Bytes written: {}").format(str(b)) self.logger(message) logging.info(message) - self.progress.setLabel(_('Checking ') + target.split('/')[-1]) + self.progress.setLabel(_("Checking ") + target.split("/")[-1]) self.progress.setValue(0) self.dialog.pollEvent() # Checking @@ -558,44 +673,61 @@ class IsoDumper(basedialog.BaseDialog): while progress < 100: self.progress.setValue(progress) self.dialog.pollEvent() - time.sleep(.5) + time.sleep(0.5) progress = self.iface.progress nowarning, message = self.iface.end() self.progress.setEnabled() self.logger(message) logging.info(message) # Add persistent partition if asked - if self.partition_cbox.isChecked() and self.partition_cb.value() == "ext4": + if ( + self.partition_cbox.isChecked() + and self.partition_cb.value() == "ext4" + ): self.progress.setLabel(_("Adding persistent partition")) self.progress.setValue(0) if self.cryptcb.isChecked(): if self.cryptkey.value() == "": - message = _("No key for encrypted partition provided. Adding the partition aborted.") + message = _( + "No key for encrypted partition provided. Adding the partition aborted." + ) self.logger(message) logging.warning(message) else: - self.iface.do_persistence(target, self.partition_label.value(), self.cryptkey.value()) + self.iface.do_persistence( + target, + self.partition_label.value(), + self.cryptkey.value(), + ) while not self.iface.done: progress = self.iface.progress self.progress.setValue(progress) self.progress.setLabel(self.iface.message) self.dialog.pollEvent() - time.sleep(.5) + time.sleep(0.5) if self.iface.state: - message = _("Added encrypted persistent partition") + message = _( + "Added encrypted persistent partition" + ) self.logger(message) logging.warning(message) else: - self.logger(_("Adding encrypted persistent partition failed")) + self.logger( + _( + "Adding encrypted persistent partition failed" + ) + ) self.logger(self.iface.message) nowarning = False else: - self.iface.do_persistence(target, self.partition_label.value(), "") + self.iface.do_persistence( + target, self.partition_label.value(), "" + ) while not self.iface.done: progress = self.iface.progress self.progress.setValue(progress) self.dialog.pollEvent() - time.sleep(.5) + time.sleep(0.5) if self.iface.state: message = _("Added persistent partition") else: @@ -611,7 +743,7 @@ class IsoDumper(basedialog.BaseDialog): self.udev_wait(_("unmounting")) if success: self.u.eject(target) - if nowarning : + if nowarning: self.success() else: self.warn() @@ -631,21 +763,39 @@ class IsoDumper(basedialog.BaseDialog): def success(self): self.operation = False self.final_unsensitive() - info = Info(_("Success"), True, _("The operation completed successfully.") + "\n"\ - + _("You are free to unplug it now, a logfile \n\ -/home/-user-/.isodumper/isodumper.log has been saved.")+ "\n"\ - + _("You may also consult /var/log/magiback.log")) + info = Info( + _("Success"), + True, + _("The operation completed successfully.") + + "\n" + + _( + "You are free to unplug it now, a logfile \n\ +/home/-user-/.isodumper/isodumper.log has been saved." + ) + + "\n" + + _("You may also consult /var/log/magiback.log"), + ) if self.ask_OK(info): return def warn(self): self.operation = False self.final_unsensitive() - info = Info(_("Warning"), True, _("The operation completed, but with anomalies.\n\ - Check carefully the messages in log view") + "\n"\ -+ _("You are free to unplug it now, a logfile \n\ -/home/-user-/.isodumper/isodumper.log has been saved.") + "\n"\ - + _("You may also consult /var/log/magiback.log")) + info = Info( + _("Warning"), + True, + _( + "The operation completed, but with anomalies.\n\ + Check carefully the messages in log view" + ) + + "\n" + + _( + "You are free to unplug it now, a logfile \n\ +/home/-user-/.isodumper/isodumper.log has been saved." + ) + + "\n" + + _("You may also consult /var/log/magiback.log"), + ) if self.ask_OK(info): return @@ -653,9 +803,15 @@ class IsoDumper(basedialog.BaseDialog): if not self.operation: # no writing , backup nor format running self.close() else: # writing , backup or format running - info = Info(_("Warning"), True, _("Writing is in progress. Exiting during writing \n\ + info = Info( + _("Warning"), + True, + _( + "Writing is in progress. Exiting during writing \n\ will make the device or the backup unusable.\n\ - Are you sure you want to quit during writing?")) + Are you sure you want to quit during writing?" + ), + ) if self.ask_YesOrNo(info): return True else: @@ -700,43 +856,74 @@ class IsoDumper(basedialog.BaseDialog): def activate_devicelist(self): self.devicelist.setEnabled() - message = _('ISO Image to copy: ') + self.img_name + message = _("ISO Image to copy: ") + self.img_name self.logger(message) logging.warning(message) # self.chooser.set_tooltip_text(self.img_name) def help_dialog(self): - info = Info(_("IsoDumper"), True, _("Mageia IsoDumper") + "<BR />\ -----------------<BR />" + - _("This GUI program is primarily for safely writing a bootable ISO image to a USB flash drive, \ + info = Info( + _("IsoDumper"), + True, + _("Mageia IsoDumper") + + "<BR />\ +----------------<BR />" + + _( + "This GUI program is primarily for safely writing a bootable ISO image to a USB flash drive, \ an operation devious & potentially hazardous when done by hand. As a bonus, it can also back up the \ entire previous contents of the flash drive onto the hard disc, and restore the flash drive \ -to its previous state subsequently.") + "<BR />" + - _("It gives also a feature for formatting the USB device.") + "<BR /><BR />" + - _( - "IsoDumper can be launched either from the menus, or a user console with the command 'isodumper'.") + "<BR />" + - _( - "The root password is solicited when this is necessary for the program's operation.") + " <BR />" + - _("The flash drive can be inserted beforehand or once the program is started. In the latter case, a \ +to its previous state subsequently." + ) + + "<BR />" + + _("It gives also a feature for formatting the USB device.") + + "<BR /><BR />" + + _( + "IsoDumper can be launched either from the menus, or a user console with the command 'isodumper'." + ) + + "<BR />" + + _( + "The root password is solicited when this is necessary for the program's operation." + ) + + " <BR />" + + _( + "The flash drive can be inserted beforehand or once the program is started. In the latter case, a \ dialogue will say that there is no flash drive inserted, and allow a 'retry' to find it once it is. <BR />\ -(You may have to close any automatically opened File Manager window).") + "<BR /><BR />" + - _("The fields of the main window are as follows:<BR />\ +(You may have to close any automatically opened File Manager window)." + ) + + "<BR /><BR />" + + _( + "The fields of the main window are as follows:<BR />\ - Device to work on: the device of the USB flash drive, a drop-down list to choose from.<BR />\ - Write Image: to choose the source ISO image *.iso (or flash drive backup file *.img) to write out.<BR />\ -- Write to device: This button launches the operation - with a prior warning dialogue.") + "<BR />" + - _( - "- Add a persistent partition: the remaining space will be used in a new partition where data from the Live system can be written and recovered between sessions.") + "<BR />" + - _( - "- Encrypt: the persistent partition will be encrypted with the key provided in <i>Key</i> field.") + "<BR />" + - _("The operation is shown in the progress bar beneath.") + "<BR />" + - _("- Backup to: define the name and placement of the backup image file. The current flash drive \ +- Write to device: This button launches the operation - with a prior warning dialogue." + ) + + "<BR />" + + _( + "- Add a persistent partition: the remaining space will be used in a new partition where data from the Live system can be written and recovered between sessions." + ) + + "<BR />" + + _( + "- Encrypt: the persistent partition will be encrypted with the key provided in <i>Key</i> field." + ) + + "<BR />" + + _("The operation is shown in the progress bar beneath.") + + "<BR />" + + _( + "- Backup to: define the name and placement of the backup image file. The current flash drive \ will be backed up to a disc file. Note that the entire flash drive is preserved, regardless of its \ actual contents; ensure that you have the necessary free disc space (the same size as the USB device). \ -This backup file can be used later to restore the flash drive by selecting it as the source *.img file to write out.") + "<BR />" + - _("- Backup the device: launch the backup operation.") + "<BR />" + - _("- Format the device: create an unique partition on the entire volume in the specified format in FAT, \ -exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog box.") + "<BR />") +This backup file can be used later to restore the flash drive by selecting it as the source *.img file to write out." + ) + + "<BR />" + + _("- Backup the device: launch the backup operation.") + + "<BR />" + + _( + "- Format the device: create an unique partition on the entire volume in the specified format in FAT, \ +exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog box." + ) + + "<BR />", + ) if self.ask_OK(info): return @@ -758,7 +945,11 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog proc_iter = psutil.process_iter(attrs=["pid", "name"]) for p in proc_iter: if (p.info["name"] == APP) and (p.info["pid"] != current_pid): - info = Info(_("Error"), True, _("There is another instance of Isodumper already running.")) + info = Info( + _("Error"), + True, + _("There is another instance of Isodumper already running."), + ) self.ask_OK(info) yui.YUILoader.deleteUI() self._running = False @@ -766,12 +957,14 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog # TODO Read log level from command line level = logging.DEBUG if debug else logging.ERROR - logpath = os.path.join(os.path.expanduser('~'), '.isodumper') + logpath = os.path.join(os.path.expanduser("~"), ".isodumper") if not (os.path.isdir(logpath)): os.mkdir(logpath) - logging.basicConfig(filename=os.path.join(logpath,"isodumper.log"), - format='%(asctime)s %(levelname)-8s %(message)s', - level=level) + logging.basicConfig( + filename=os.path.join(logpath, "isodumper.log"), + format="%(asctime)s %(levelname)-8s %(message)s", + level=level, + ) # define size of the selected device self.deviceSize = 0 @@ -780,15 +973,24 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog self.operation = False self.ChooseImage = _("Choose an image") - self.warning = _("Warning\nThis will destroy all data on the target device,\n\ + self.warning = _( + "Warning\nThis will destroy all data on the target device,\n\ are you sure you want to proceed?\n\ If you say ok here, please <b>do not unplug</b>\ - the device during the following operation.") + the device during the following operation." + ) """ Init/Constructor for the 'widgets' """ - self.dialog = basedialog.BaseDialog.__init__(self, _("Isodumper {}").format(version.RELEASE), "", basedialog.DialogType.POPUP, 100, 10) + self.dialog = basedialog.BaseDialog.__init__( + self, + _("Isodumper {}").format(version.RELEASE), + "", + basedialog.DialogType.POPUP, + 100, + 10, + ) yui.YUI.app().setApplicationIcon("/usr/share/icons/isodumper.png") def UIlayout(self, layout): @@ -810,67 +1012,99 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog # +---------------------+ # | refreshbt | aboutbt | helpbt | quitbt | # +---------------------+ - #self.ancrage = self.factory.createReplacePoint(self.dialog) + # self.ancrage = self.factory.createReplacePoint(self.dialog) self.box = self.factory.createVBox(layout) self.bannerbox = self.factory.createHBox(self.box) - self.banner = self.factory.createImage(self.bannerbox, "/usr/share/isodumper/header.svg") + self.banner = self.factory.createImage( + self.bannerbox, "/usr/share/isodumper/header.svg" + ) self.devicebox = self.factory.createHBox(self.box) - self.devicelist = self.factory.createComboBox(self.devicebox, _("Select the device to work on:"), False) + self.devicelist = self.factory.createComboBox( + self.devicebox, _("Select the device to work on:"), False + ) self.devicelist.setNotify() self.devicelist.setStretchable(0, True) self.refreshbt = self.factory.createPushButton(self.devicebox, _("Update list")) self.refreshbt.setStretchable(0, True) - self.operation_frame = self.factory.createFrame(self.box, _("Select operations")) + self.operation_frame = self.factory.createFrame( + self.box, _("Select operations") + ) self.operationbox = self.factory.createVBox(self.operation_frame) self.labelbox = self.factory.createHBox(self.operationbox) self.labelbox.setStretchable(0, True) - self.factory.createLabel(self.labelbox, _("The selected operations will be executed in order from top to bottom.\nIf both write image and create partition are selected, the partition\nwill be created in the free space after the image.")).setStretchable(0, True) + self.factory.createLabel( + self.labelbox, + _( + "The selected operations will be executed in order from top to bottom.\nIf both write image and create partition are selected, the partition\nwill be created in the free space after the image." + ), + ).setStretchable(0, True) self.backupbox = self.factory.createHBox(self.operationbox) - self.backup_cbox = self.factory.createCheckBox(self.backupbox, _("Backup the device to:")) + self.backup_cbox = self.factory.createCheckBox( + self.backupbox, _("Backup the device to:") + ) self.backup_cbox.setNotify() # add file picker for backup file name - self.backup_select = self.factory.createPushButton(self.backupbox, self.ChooseImage) + self.backup_select = self.factory.createPushButton( + self.backupbox, self.ChooseImage + ) self.backup_select.setStretchable(0, True) self.factory.createHStretch(self.backupbox) self.writebox = self.factory.createHBox(self.operationbox) - self.write_cbox = self.factory.createCheckBox(self.writebox, _("Write Image from:")) + self.write_cbox = self.factory.createCheckBox( + self.writebox, _("Write Image from:") + ) self.write_cbox.setNotify() # add file picker for image file self.ima = self.factory.createPushButton(self.writebox, self.ChooseImage) self.ima.setStretchable(0, True) self.factory.createHStretch(self.writebox) - #self.writebt = self.factory.createPushButton(self.writebox, _("&Write to device")) + # self.writebt = self.factory.createPushButton(self.writebox, _("&Write to device")) self.partitionbox = self.factory.createHBox(self.operationbox) - self.partition_cbox = self.factory.createCheckBox(self.partitionbox, _("Create partition of type:")) + self.partition_cbox = self.factory.createCheckBox( + self.partitionbox, _("Create partition of type:") + ) self.partition_cbox.setNotify() self.partition_cb = self.factory.createComboBox(self.partitionbox, _("Type:")) self.partition_cb.addItem("", True) - self.format_type = {'fat32': _("FAT32"), - 'ext4': _("ext4"), - 'ntfs': _("NTFS"), - 'exfat': _("exFAT"), - 'persist': _("Persistent partition"), - } + self.format_type = { + "fat32": _("FAT32"), + "ext4": _("ext4"), + "ntfs": _("NTFS"), + "exfat": _("exFAT"), + "persist": _("Persistent partition"), + } for key in self.format_type: self.partition_cb.addItem(self.format_type[key], False) self.partition_cb.setNotify() - self.partition_label = self.factory.createInputField(self.partitionbox, _("Label:")) + self.partition_label = self.factory.createInputField( + self.partitionbox, _("Label:") + ) self.partition_label.setStretchable(0, True) self.persistencebox = self.factory.createHBox(self.operationbox) - #self.persistencecb = self.factory.createCheckBox(self.persistencecol1, + # self.persistencecb = self.factory.createCheckBox(self.persistencecol1, # _("Add a persistent partition in the remaining space")) - self.cryptcb = self.factory.createCheckBox(self.persistencebox, _("Encrypt partition using LUKS, with key:")) + self.cryptcb = self.factory.createCheckBox( + self.persistencebox, _("Encrypt partition using LUKS, with key:") + ) self.cryptcb.setNotify() - self.cryptkey = self.factory.createInputField(self.persistencebox, _("Key:"), passwordMode=True) + self.cryptkey = self.factory.createInputField( + self.persistencebox, _("Key:"), passwordMode=True + ) self.cryptkey.setStretchable(0, True) - #self.formatbt = self.factory.createPushButton(self.formatbox, _("Format the device")) + # self.formatbt = self.factory.createPushButton(self.formatbox, _("Format the device")) self.execute_frame = self.factory.createFrame(self.box, _("Execution")) self.execute_framevb = self.factory.createVBox(self.execute_frame) - self.execute_label = self.factory.createLabel(self.execute_framevb, _("When you are sure all options are correct, start:")) - self.start_bt = self.factory.createPushButton(self.execute_framevb, _("Execute")) + self.execute_label = self.factory.createLabel( + self.execute_framevb, _("When you are sure all options are correct, start:") + ) + self.start_bt = self.factory.createPushButton( + self.execute_framevb, _("Execute") + ) self.start_bt.setNotify() self.progressbox = self.factory.createHBox(self.execute_framevb) - self.progress = self.factory.createProgressBar(self.progressbox, _("Progress"), 100) + self.progress = self.factory.createProgressBar( + self.progressbox, _("Progress"), 100 + ) self.progress.setStretchable(0, True) self.reportbox = self.factory.createHBox(self.box) self.reportbox.setWeight(1, 30) @@ -898,41 +1132,55 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog self.eventManager.addWidgetEvent(self.helpbt, self.help_dialog) self.eventManager.addWidgetEvent(self.aboutbt, self.aboutDialog) # Set the initial state, active, disabled - #self.initial_state() + # self.initial_state() self.dialog.recalcLayout() self.uEventQueue = SimpleQueue() if yui.YUI.app().isTextMode(): self.glib_loop = GLib.MainLoop() - self.glib_thread = threading.Thread(target=self.glib_mainloop, args=(self.glib_loop,)) + self.glib_thread = threading.Thread( + target=self.glib_mainloop, args=(self.glib_loop,) + ) self.glib_thread.start() - self.u.iface["org.freedesktop.DBus.ObjectManager"].InterfacesAdded.connect(self.device_changed) - self.u.iface["org.freedesktop.DBus.ObjectManager"].InterfacesRemoved.connect(self.device_changed) + self.u.iface["org.freedesktop.DBus.ObjectManager"].InterfacesAdded.connect( + self.device_changed + ) + self.u.iface["org.freedesktop.DBus.ObjectManager"].InterfacesRemoved.connect( + self.device_changed + ) def glib_mainloop(self, loop): - ''' + """ thread function for glib main loop - ''' + """ loop.run() - def device_changed(self, a, b): logging.debug(f"Signal {a}") if not self.operation: - if 'drives' in a.split('/'): - logging.debug('device-changed') - self.uEventQueue.put({'event': "device-changed", 'value': True}) + if "drives" in a.split("/"): + logging.debug("device-changed") + self.uEventQueue.put({"event": "device-changed", "value": True}) def ask_image(self): - self.img_name = yui.YUI.app().askForExistingFile("", "*.iso *.img", self.ChooseImage) + self.img_name = yui.YUI.app().askForExistingFile( + "", "*.iso *.img", self.ChooseImage + ) if self.img_name != "": # Check if the image has a signed checksum self.get_sum(self.img_name) if self.signature_found: if not self.signature_checked: - info = Info(_("Warning"), True, - _("The validation of the GPG signature of the checksum file failed !") + "\n" + _("Do you want to continue?")) + info = Info( + _("Warning"), + True, + _( + "The validation of the GPG signature of the checksum file failed !" + ) + + "\n" + + _("Do you want to continue?"), + ) if self.ask_YesOrNo(info): pass else: @@ -941,8 +1189,13 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog else: self.logger(_("The checksum file is signed")) else: - info = Info(_("Warning"), True, - _('No GPG signature has been found or the key is expired. Are you sure you want to use this image?')) + info = Info( + _("Warning"), + True, + _( + "No GPG signature has been found or the key is expired. Are you sure you want to use this image?" + ), + ) if self.ask_YesOrNo(info): pass else: @@ -973,7 +1226,9 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog backup_ready = self.backup_cbox.isChecked() and (self.backup_dest != "") write_ready = self.write_cbox.isChecked() and (self.img_name != "") - partition_ready = self.partition_cbox.isChecked() and (self.partition_cb.value() in self.format_type.values()) + partition_ready = self.partition_cbox.isChecked() and ( + self.partition_cb.value() in self.format_type.values() + ) crypt_ready = self.cryptcb.isChecked() and (self.cryptkey.value() != "") start_active = backup_ready or write_ready or partition_ready if start_active: @@ -986,7 +1241,6 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog self.cryptcb.setDisabled() self.cryptkey.setDisabled() - def select_backup(self): if self.backup_cbox.isChecked(): self.backup_select.setEnabled() @@ -1012,18 +1266,17 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog def select_partition_type(self): print(f"Selected {self.partition_cb.value()}") - if self.partition_cb.value() in (_("ext4") ,_("Persistent partition")): + if self.partition_cb.value() in (_("ext4"), _("Persistent partition")): self.cryptcb.setEnabled() if self.partition_cb.value() == _("Persistent partition"): self.partition_label.setValue("mgalive-persist") - self.partition_cb.setValue('ext4') + self.partition_cb.setValue("ext4") else: self.cryptcb.setDisabled() self.cryptcb.setDisabled() self.cryptkey.setDisabled() self.interface_active_state() - def check_encryt(self): if self.cryptcb.isChecked(): self.cryptkey.setEnabled() @@ -1074,7 +1327,6 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog self.success() self.initial_state() - def ask_format(self): atelier = yui.YUI.widgetFactory() dialog = atelier.createPopupDialog() @@ -1083,13 +1335,21 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog cr = atelier.createRadioButtonGroup(vb) vb_c = atelier.createVBox(cr) vb_c1 = atelier.createHBox(vb_c) - format_fat = atelier.createRadioButton(atelier.createLeft(vb_c1), _("FAT32 (Windows)")) + format_fat = atelier.createRadioButton( + atelier.createLeft(vb_c1), _("FAT32 (Windows)") + ) vb_c4 = atelier.createHBox(vb_c) - format_exfat = atelier.createRadioButton(atelier.createLeft(vb_c4), _("exFAT (Windows)")) + format_exfat = atelier.createRadioButton( + atelier.createLeft(vb_c4), _("exFAT (Windows)") + ) vb_c2 = atelier.createHBox(vb_c) - format_ntfs = atelier.createRadioButton(atelier.createLeft(vb_c2), _("NTFS (Windows)")) + format_ntfs = atelier.createRadioButton( + atelier.createLeft(vb_c2), _("NTFS (Windows)") + ) vb_c3 = atelier.createHBox(vb_c) - format_ext = atelier.createRadioButton(atelier.createLeft(vb_c3), _("ext4 (Linux)")) + format_ext = atelier.createRadioButton( + atelier.createLeft(vb_c3), _("ext4 (Linux)") + ) bb = atelier.createHBox(vb) executebt = atelier.createPushButton(bb, _("Execute")) cancelbt = atelier.createPushButton(bb, _("Cancel")) @@ -1102,19 +1362,19 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog break if event.widget() == executebt: if format_fat.value(): - format_type = 'fat32' + format_type = "fat32" format_label = label.value().upper()[:11] break if format_exfat.value(): - format_type = 'exfat' + format_type = "exfat" format_label = label.value()[:32] break if format_ntfs.value(): - format_type = 'ntfs' + format_type = "ntfs" format_label = label.value()[:32] break if format_ext.value(): - format_type = 'ext4' + format_type = "ext4" format_label = label.value() break if event.widget() == cancelbt: @@ -1128,7 +1388,9 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog def ask_OK(self, info): yui.YUI.widgetFactory - mgafactory = yui.YMGAWidgetFactory.getYMGAWidgetFactory(yui.YExternalWidgets.externalWidgetFactory("mga")) + mgafactory = yui.YMGAWidgetFactory.getYMGAWidgetFactory( + yui.YExternalWidgets.externalWidgetFactory("mga") + ) dlg = mgafactory.createDialogBox(yui.YMGAMessageBox.B_ONE) dlg.setTitle(info.title) dlg.setText(info.text, info.richtext) @@ -1138,7 +1400,9 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog def ask_YesOrNo(self, info): yui.YUI.widgetFactory - mgafactory = yui.YMGAWidgetFactory.getYMGAWidgetFactory(yui.YExternalWidgets.externalWidgetFactory("mga")) + mgafactory = yui.YMGAWidgetFactory.getYMGAWidgetFactory( + yui.YExternalWidgets.externalWidgetFactory("mga") + ) dlg = mgafactory.createDialogBox(yui.YMGAMessageBox.B_TWO) dlg.setTitle(info.title) dlg.setText(info.text, info.richtext) @@ -1149,19 +1413,32 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog def aboutDialog(self): yui.YUI.widgetFactory - mgafactory = yui.YMGAWidgetFactory.getYMGAWidgetFactory(yui.YExternalWidgets.externalWidgetFactory("mga")) - dlg = mgafactory.createAboutDialog("Isodumper", version.RELEASE, "GPLv2", - _("Oliver Grawert<BR />Papoteur<BR />Pictures : Timothée Giet"), _( - "A tool for writing ISO images to a device") + "<BR />http://gitweb.mageia.org/software/isodumper", "") + mgafactory = yui.YMGAWidgetFactory.getYMGAWidgetFactory( + yui.YExternalWidgets.externalWidgetFactory("mga") + ) + dlg = mgafactory.createAboutDialog( + "Isodumper", + version.RELEASE, + "GPLv2", + _("Oliver Grawert<BR />Papoteur<BR />Pictures : Timothée Giet"), + _("A tool for writing ISO images to a device") + + "<BR />http://gitweb.mageia.org/software/isodumper", + "", + ) dlg.show() def nodevDialog(self): yui.YUI.widgetFactory - mgafactory = yui.YMGAWidgetFactory.getYMGAWidgetFactory(yui.YExternalWidgets.externalWidgetFactory("mga")) + mgafactory = yui.YMGAWidgetFactory.getYMGAWidgetFactory( + yui.YExternalWidgets.externalWidgetFactory("mga") + ) dlg = mgafactory.createDialogBox(yui.YMGAMessageBox.B_TWO) dlg.setTitle("IsoDumper") - dlg.setText(_( - "Warning\nNo target devices were found.\nYou need to plug in a USB Key to which the image can be written.")) + dlg.setText( + _( + "Warning\nNo target devices were found.\nYou need to plug in a USB Key to which the image can be written." + ) + ) dlg.setButtonLabel(_("Refresh"), yui.YMGAMessageBox.B_ONE) dlg.setButtonLabel(_("Cancel"), yui.YMGAMessageBox.B_TWO) dlg.setMinSize(60, 8) @@ -1169,16 +1446,16 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog def doSomethingIntoLoop(self): self.traitement = None - #if event.eventType() == yui.YEvent.CancelEvent: - #self.confirm_close() - #break + # if event.eventType() == yui.YEvent.CancelEvent: + # self.confirm_close() + # break if self._start: self._start = False self.initial_state() try: item = self.uEventQueue.get_nowait() logging.debug(f"Dealing with {item['event']}") - if item['event'] == "device-changed": + if item["event"] == "device-changed": self.update_list_on_event() except Exception as e: pass @@ -1189,7 +1466,7 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog try: self.u = UDisks2() except: - message = _('UDisks2 is not available on your system') + message = _("UDisks2 is not available on your system") logging.error(message) self.emergency(message) self._running = False @@ -1206,10 +1483,11 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog self._handleEvents() except Exception: import traceback + traceback.print_exc() yui.YDialog.deleteAllDialogs() # Closing - #restore old application title + # restore old application title yui.YUI.app().setApplicationTitle(self.backupTitle) self.dialog.destroy() self.dialog = None @@ -1221,8 +1499,10 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog if __name__ == "__main__": # Send the yui logging outside of the console log = yui.YUILog.setLogFileName("/dev/null") - parser = ParseCLI('isodumper') - parser.parser.add_argument('--debug', help=_('allow debug information'), action='store_true') + parser = ParseCLI("isodumper") + parser.parser.add_argument( + "--debug", help=_("allow debug information"), action="store_true" + ) if parser.args.version: print(version.RELEASE) else: diff --git a/lib/raw_format.py b/lib/raw_format.py index bf57ba5..6dc6d91 100755 --- a/lib/raw_format.py +++ b/lib/raw_format.py @@ -27,7 +27,8 @@ import getopt from subprocess import call -sys.path.append('/usr/lib/isodumper') +sys.path.append("/usr/lib/isodumper") + def raw_format(device_path, fstype, volume_label, uid, gid): import parted @@ -38,7 +39,7 @@ def raw_format(device_path, fstype, volume_label, uid, gid): device = parted.getDevice(device_path) # Create a default partition set up - disk = parted.freshDisk(device, 'msdos') + disk = parted.freshDisk(device, "msdos") try: disk.commit() except: @@ -72,7 +73,9 @@ def raw_format(device_path, fstype, volume_label, uid, gid): fs = parted.FileSystem(type=_fstype, geometry=geometry) # Create partition - partition = parted.Partition(disk=disk, type=parted.PARTITION_NORMAL, geometry=geometry, fs=fs) + partition = parted.Partition( + disk=disk, type=parted.PARTITION_NORMAL, geometry=geometry, fs=fs + ) constraint = parted.Constraint(exactGeom=geometry) disk.addPartition(partition=partition, constraint=constraint) disk.commit() @@ -85,15 +88,27 @@ def raw_format(device_path, fstype, volume_label, uid, gid): elif fstype == "ntfs": call(["mkntfs", "-f", "-L", volume_label, partition.path]) elif fstype == "ext4": - call(["mkfs.ext4", "-E", "root_owner=%s:%s" % (uid, gid), "-L", volume_label, partition.path]) + call( + [ + "mkfs.ext4", + "-E", + "root_owner=%s:%s" % (uid, gid), + "-L", + volume_label, + partition.path, + ] + ) sys.exit(0) def main(): # parse command line options try: - opts, args = getopt.getopt(sys.argv[1:], "hd:f:l:u:g:", - ["help", "device=", "filesystem=", "label=", "uid=", "gid="]) + opts, args = getopt.getopt( + sys.argv[1:], + "hd:f:l:u:g:", + ["help", "device=", "filesystem=", "label=", "uid=", "gid="], + ) except getopt.error as msg: print(msg) print("for help use --help") @@ -101,13 +116,16 @@ def main(): for o, a in opts: if o in ("-h", "--help"): - print("Usage: %s -d device -f filesystem -l volume_label\n"% sys.argv[0]) + print("Usage: %s -d device -f filesystem -l volume_label\n" % sys.argv[0]) print("-d|--device : device path") print("-f|--filesystem : filesystem\n") print("-l|--label : volume label\n") print("-u|--uid : uid of user\n") print("-g|--gid : gid of user\n") - print("Example : %s -d /dev/sdj -f fat32 -l \"USB Stick\" -u 1000 -g 1000" % sys.argv[0]) + print( + 'Example : %s -d /dev/sdj -f fat32 -l "USB Stick" -u 1000 -g 1000' + % sys.argv[0] + ) sys.exit(0) elif o in ("-d"): device = a @@ -125,9 +143,9 @@ def main(): argc = len(sys.argv) if argc < 11: - print("Too few arguments") - print("for help use --help") - exit(2) + print("Too few arguments") + print("for help use --help") + exit(2) raw_format(device, fstype, label, uid, gid) |