diff options
Diffstat (limited to 'lib')
-rwxr-xr-x | lib/isodumper.py | 384 |
1 files changed, 194 insertions, 190 deletions
diff --git a/lib/isodumper.py b/lib/isodumper.py index 9bde522..2f58d6b 100755 --- a/lib/isodumper.py +++ b/lib/isodumper.py @@ -53,6 +53,8 @@ from gi.repository import GLib from queue import SimpleQueue import psutil import manatools.args as args +import manatools.ui.common as common +import manatools.ui.basedialog as basedialog class NoUDisks2(Exception): @@ -149,7 +151,6 @@ class UDisks2(object): i_drive = self.bus.get(self.SERVICE, drive) i_drive.Eject({}) - class Info(object): def __init__(self, title, richtext, text): self.title = title @@ -162,7 +163,7 @@ class ParseCLI(args.AppArgs): super().__init__(command) -class IsoDumper(object): +class IsoDumper(basedialog.BaseDialog): def get_devices(self, selected=None): self.list = self.u.find_devices() @@ -180,6 +181,16 @@ class IsoDumper(object): self.devicelist.addItem(label, sel) return True + def active_signal(self): + print("Active") + self.u.iface["org.freedesktop.DBus.ObjectManager"].InterfacesAdded.connect(self.refresh_signal) + self.u.iface["org.freedesktop.DBus.ObjectManager"].InterfacesRemoved.connect(self.refresh_signal) + + def deactive_signal(self): + print("Désactive") + #self.u.iface["org.freedesktop.DBus.ObjectManager"].onInterfacesAdded = None + #self.u.iface["org.freedesktop.DBus.ObjectManager"].onInterfacesRemoved = None + def udev_wait(self, operation): wait = Popen(["udevadm", "settle", "--timeout=15"], stderr=PIPE) wait.communicate() @@ -206,12 +217,19 @@ class IsoDumper(object): self.dialog.recalcLayout() self.restore() +<<<<<<< HEAD + def refresh_signal(self, device, params): + print("Refresh ", device) + self.devicelist.deleteAllItems() + self.get_devices() +======= def update_list_on_event(self): selitem = self.devicelist.selectedItem().label() self.devicelist.deleteAllItems() self.get_devices(selected = selitem) if self.devicelist.selectedItem().label() != selitem: self.restore() +>>>>>>> master self.dialog.recalcLayout() def device_selected(self): @@ -222,7 +240,9 @@ class IsoDumper(object): if self.dev.startswith(name + ' (' + path.lstrip()): self.deviceSize = size self.device_name = name.rstrip().replace(' ', '') - self.logger(_('Target Device: ') + self.dev) + message = _('Target Device: {}').format(self.dev) + self.logger(message) + logging.info(message) self.formatbt.setEnabled() self.ima.setEnabled() self.backup_select.setEnabled() @@ -239,35 +259,40 @@ class IsoDumper(object): def backup_choosed(self): # Add .img if not specified - 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 - self.backup_select.setLabel(tail) - self.dialog.recalcLayout() - self.backupbt.setEnabled() - - def do_format(self, format_type, name): - target = self.dev.split('(')[1].split(')')[0] - info = Info(_("Formatting confirmation"), True, self.warning) - if self.ask_YesOrNo(info): - rc = self.raw_format(target, format_type, name) - self.operation = False - if rc == 0: - message = _('The device was formatted successfully.') - self.logger(message) - self.success() - elif rc == 5: - message = _("An error occurred while creating a partition.") - self.logger(message) - self.emergency(message) - elif rc == 127: - message = _('Authentication error.') - self.logger(message) - self.emergency(message) - else: - message = _('An error occurred.') - self.emergency(message) + 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 + self.backup_select.setLabel(tail) + self.dialog.recalcLayout() + self.backupbt.setEnabled() + + def do_format(self): + code, format_type, name = self.ask_format() + if code: + target = self.dev.split('(')[1].split(')')[0] + info = Info(_("Formatting confirmation"), True, self.warning) + if self.ask_YesOrNo(info): + rc = self.raw_format(target, format_type, name) + self.operation = False + if rc == 0: + message = _('The device was formatted successfully.') + self.logger(message) + self.success() + elif rc == 5: + message = _("An error occurred while creating a partition.") + self.logger(message) + self.emergency(message) + elif rc == 127: + message = _('Authentication error.') + self.logger(message) + self.emergency(message) + else: + message = _('An error occurred.') + self.emergency(message) + self.restore() def restore(self): self.backup_select.setDisabled() @@ -286,11 +311,6 @@ class IsoDumper(object): self.cryptcb.setDisabled() self.cryptkey.setDisabled() - def onProgress(self, frac): - self.logger(_('Wrote: {}% '.format(frac))) - self.progress.setValue(frac) - self.dialog.pollEvent() - def raw_format(self, usb_path, fstype, label): self.u.do_unmount(usb_path) self.udev_wait(_("unmounting")) @@ -319,6 +339,7 @@ class IsoDumper(object): return rc def backup_go(self): + self.wip_unsensitive() dest = self.backup_img_name if os.path.exists(dest): info = Info(_("Backup confirmation"), True, _("Do you want to overwrite the file?")) @@ -331,11 +352,14 @@ class IsoDumper(object): sizeM = str(self.deviceSize / (1024 * 1024)) message = _("The destination directory is too small to receive the backup (%s Mb needed)") % (sizeM) self.logger(message) + logging.warning(message) self.emergency(message) else: self.returncode = 0 source = self.dev.split('(')[1].split(')')[0] - self.logger(_('Backup to:') + ' ' + dest) + message = _('Backup to: {}').format(dest) + self.logger(message) + logging.info(message) bus = SystemBus() iface = bus.get("org.mageia.Magiback", "Isodumper") # Writing step @@ -347,17 +371,23 @@ class IsoDumper(object): time.sleep(.2) success, message = iface.end() if success: - self.logger( - _('{source} successfully written to {target}').format(source=source.split('/')[-1], target=dest)) + #: don't translate source or target + message = _('{source} successfully written to {target}').format(source=source.split('/')[-1], target=dest) + self.logger(message) + logging.info(message) self.progress.setEnabled() self.progress.setValue(100) self.dialog.pollEvent() self.logger(message) + logging.info(message) self.success() + self.restore() else: self.emergency(message) + self.restore() def do_write(self): + self.wip_unsensitive() self.writebt.setDisabled() self.devicelist.setDisabled() self.formatbt.setDisabled() @@ -370,6 +400,7 @@ class IsoDumper(object): if b > (self.deviceSize): message = _('The device is too small to contain the ISO file.') self.logger(message) + logging.error(message) self.emergency(message) else: info = Info(_("Writing confirmation"), True, self.warning) @@ -383,9 +414,13 @@ class IsoDumper(object): return self.ima.setDisabled() self.writebt.setDisabled() + #: don't translate source or target self.progress.setLabel(_('Writing {source} to {target}').format(source=source.split('/')[-1], target=target.split('/')[-1])) - self.logger(_('Executing copy from ') + source + _(' to ') + target) + message = _('Executing copy from {source} to {target}').format(source=source, target=target) + self.logger(message) + logging.info(message) + self.deactive_signal() bus = SystemBus() iface = bus.get("org.mageia.Magiback", "Isodumper") success, message = self.u.do_unmount(target) @@ -402,10 +437,12 @@ class IsoDumper(object): time.sleep(.5) success, message = iface.end() if success: - self.logger( - _('Image {source} successfully written to {target}').format(source=source.split('/')[-1], - target=target)) - self.logger(_('Bytes written: ') + str(b)) + #: don't translate source or target + message = _('Image {source} successfully 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.setValue(0) self.dialog.pollEvent() @@ -420,14 +457,16 @@ class IsoDumper(object): nowarning, message = iface.end() self.progress.setEnabled() self.logger(message) + logging.info(message) # Add persistent partition if asked if self.persistencecb.isChecked(): self.progress.setLabel(_("Adding persistent partition")) self.progress.setValue(0) if self.cryptcb.isChecked(): if self.cryptkey.value() == "": - self.logger( - _("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: iface.do_persistence(target, "mgalive-persist", self.cryptkey.value()) while not iface.done: @@ -437,7 +476,9 @@ class IsoDumper(object): self.dialog.pollEvent() time.sleep(.5) if iface.state: - self.logger(_("Added encrypted persistent partition")) + message = _("Added encrypted persistent partition") + self.logger(message) + logging.warning(message) else: self.logger(iface.message) else: @@ -447,7 +488,9 @@ class IsoDumper(object): self.progress.setValue(progress) self.dialog.pollEvent() time.sleep(.5) - self.logger(_("Added persistent partition")) + message = _("Added persistent partition") + self.logger(message) + logging.warning(message) # Unmount if partitions are automatically mounted and then eject self.progress.setValue(100) self.dialog.pollEvent() @@ -469,14 +512,14 @@ class IsoDumper(object): self.restore() else: self.restore() + self.active_signal() 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- or /root)/.isodumper/isodumper.log will be saved when\n\ - you close the application.")) +(/home/-user- or /root)/.isodumper/isodumper.log has be saved.")) if self.ask_OK(info): return @@ -527,28 +570,19 @@ class IsoDumper(object): self.persistencecb.setDisabled() def close(self): - self.write_logfile() self.dialog.destroy() self.dialog = None self.glib_loop.quit() self.glib_thread.join() - def write_logfile(self): - logpath = os.path.join(os.path.expanduser('~'), '.isodumper') - if not (os.path.isdir(logpath)): - os.mkdir(logpath) - logfile = open(logpath + '/isodumper.log', "w", encoding="utf-8") - logfile.write(self.logview.logText()) - logfile.close() - - print((self.logview.logText())) - def logger(self, text): self.logview.appendLines(text + "\n") def activate_devicelist(self): self.devicelist.setEnabled() - self.logger(_('Image ') + ": " + self.img_name) + message = _('Image ') + ": " + self.img_name + self.logger(message) + logging.warning(message) # self.chooser.set_tooltip_text(self.img_name) @@ -587,6 +621,7 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog return def __init__(self, debug=False): + #: placeholder for release number APP = "isodumper" DIR = "/usr/share/locale" # Call translation catalog @@ -607,7 +642,7 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog logpath = os.path.join(os.path.expanduser('~'), '.isodumper') if not (os.path.isdir(logpath)): os.mkdir(logpath) - logging.basicConfig(filename=os.path.join(logpath,"isodumper2.log"), + logging.basicConfig(filename=os.path.join(logpath,"isodumper.log"), format='%(asctime)s %(levelname)-8s %(message)s', level=level) @@ -625,10 +660,10 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog """ Init/Constructor for the 'widgets' """ - yui.YUI.app().setApplicationTitle(_("IsoDumper") + " " + version.RELEASE) + self.dialog = basedialog.BaseDialog.__init__(self, _("Isodumper {}").format(version.RELEASE), "", basedialog.DialogType.POPUP, 100, 20) yui.YUI.app().setApplicationIcon("/usr/share/icons/isodumper.png") - self.atelier = yui.YUI.widgetFactory() - self.dialog = self.atelier.createPopupDialog() + + def UIlayout(self, layout): # create the main gui # +---+-----------------+ # + banner + @@ -647,97 +682,122 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog # +---------------------+ # | refreshbt | aboutbt | helpbt | quitbt | # +---------------------+ - self.ancrage = self.atelier.createReplacePoint(self.dialog) - self.box = self.atelier.createVBox(self.ancrage) - self.bannerbox = self.atelier.createHBox(self.box) - self.banner = self.atelier.createImage(self.bannerbox, "/usr/share/isodumper/header.svg") - self.devicebox = self.atelier.createHBox(self.box) - self.devicelist = self.atelier.createComboBox(self.devicebox, _("Device to work on:"), False) + #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.devicebox = self.factory.createHBox(self.box) + self.devicelist = self.factory.createComboBox(self.devicebox, _("Device to work on:"), False) self.devicelist.setNotify() self.devicelist.setStretchable(0, True) - self.writebox = self.atelier.createHBox(self.box) - self.atelier.createLabel(self.writebox, _("Write Image:")) + self.writebox = self.factory.createHBox(self.box) + self.factory.createLabel(self.writebox, _("Write Image:")) # add file picker for image file - self.ima = self.atelier.createPushButton(self.writebox, self.ChooseImage) + self.ima = self.factory.createPushButton(self.writebox, self.ChooseImage) self.ima.setStretchable(0, True) self.ima.setDisabled() - self.atelier.createHStretch(self.writebox) - self.writebt = self.atelier.createPushButton(self.writebox, _("&Write to device")) + self.factory.createHStretch(self.writebox) + self.writebt = self.factory.createPushButton(self.writebox, _("&Write to device")) self.writebt.setDisabled() - self.persistencebox = self.atelier.createHBox(self.box) - self.persistencecol1 = self.atelier.createVBox(self.persistencebox) - self.persistencecol2 = self.atelier.createVBox(self.persistencebox) - self.persistencecb = self.atelier.createCheckBox(self.persistencecol1, + self.persistencebox = self.factory.createHBox(self.box) + self.persistencecol1 = self.factory.createVBox(self.persistencebox) + self.persistencecol2 = self.factory.createVBox(self.persistencebox) + self.persistencecb = self.factory.createCheckBox(self.persistencecol1, _("Add a persistent partition in the remaining space")) - self.persistencebox2 = self.atelier.createHBox(self.box) - self.cryptcb = self.atelier.createCheckBox(self.persistencecol1, _("Encrypt partition")) - self.cryptkey = self.atelier.createInputField(self.persistencecol2, _("Key:"), passwordMode=True) + self.persistencebox2 = self.factory.createHBox(self.box) + self.cryptcb = self.factory.createCheckBox(self.persistencecol1, _("Encrypt partition")) + self.cryptkey = self.factory.createInputField(self.persistencecol2, _("Key:"), passwordMode=True) self.persistencecb.setDisabled() self.persistencecb.setNotify() self.cryptcb.setDisabled() self.cryptcb.setNotify() self.cryptkey.setDisabled() - self.backupbox = self.atelier.createHBox(self.box) - self.atelier.createLabel(self.backupbox, _("Backup to:")) + self.backupbox = self.factory.createHBox(self.box) + self.factory.createLabel(self.backupbox, _("Backup to:")) # add file picker for backup file name - self.backup_select = self.atelier.createPushButton(self.backupbox, self.ChooseImage) + self.backup_select = self.factory.createPushButton(self.backupbox, self.ChooseImage) self.backup_select.setStretchable(0, True) self.backup_select.setDisabled() - self.atelier.createHStretch(self.backupbox) - self.backupbt = self.atelier.createPushButton(self.backupbox, _("Backup the device")) + self.factory.createHStretch(self.backupbox) + self.backupbt = self.factory.createPushButton(self.backupbox, _("Backup the device")) self.backupbt.setDisabled() - self.formatbox = self.atelier.createHBox(self.box) - self.atelier.createLabel(self.formatbox, _("Format the device in FAT, exFAT, NTFS or ext:")) - self.atelier.createHStretch(self.formatbox) - self.formatbt = self.atelier.createPushButton(self.formatbox, _("Format the device")) + self.formatbox = self.factory.createHBox(self.box) + self.factory.createLabel(self.formatbox, _("Format the device in FAT, exFAT, NTFS or ext:")) + self.factory.createHStretch(self.formatbox) + self.formatbt = self.factory.createPushButton(self.formatbox, _("Format the device")) self.formatbt.setDisabled() - self.progressbox = self.atelier.createHBox(self.box) - self.progress = self.atelier.createProgressBar(self.progressbox, _("Progress"), 100) + self.progressbox = self.factory.createHBox(self.box) + self.progress = self.factory.createProgressBar(self.progressbox, _("Progress"), 100) self.progress.setStretchable(0, True) - self.reportbox = self.atelier.createHBox(self.box) + self.reportbox = self.factory.createHBox(self.box) self.reportbox.setWeight(1, 30) - self.logview = self.atelier.createLogView(self.reportbox, _("Report"), 10) + self.logview = self.factory.createLogView(self.reportbox, _("Report"), 10) self.logview.setStretchable(0, True) - self.buttonsbox = self.atelier.createHBox(self.box) - self.refreshbt = self.atelier.createPushButton(self.devicebox, _("Refresh")) + self.buttonsbox = self.factory.createHBox(self.box) + self.refreshbt = self.factory.createPushButton(self.devicebox, _("Refresh")) self.refreshbt.setStretchable(0, True) - self.aboutbt = self.atelier.createPushButton(self.buttonsbox, _("About")) + self.aboutbt = self.factory.createPushButton(self.buttonsbox, _("About")) self.aboutbt.setStretchable(0, True) - self.helpbt = self.atelier.createPushButton(self.buttonsbox, _("Help")) + self.helpbt = self.factory.createPushButton(self.buttonsbox, _("Help")) self.helpbt.setStretchable(0, True) - self.quitbt = self.atelier.createPushButton(self.buttonsbox, _("Quit")) + self.quitbt = self.factory.createPushButton(self.buttonsbox, _("Quit")) self.quitbt.setStretchable(0, True) + # Connect events + self.eventManager.addWidgetEvent(self.quitbt, self.confirm_close) + self.eventManager.addWidgetEvent(self.ima, self.ask_image) + self.eventManager.addWidgetEvent(self.persistencecb, self.check_persistence) + self.eventManager.addWidgetEvent(self.writebt, self.do_write) + self.eventManager.addWidgetEvent(self.cryptcb, self.check_encryt) + self.eventManager.addWidgetEvent(self.backupbt, self.backup_go) + self.eventManager.addWidgetEvent(self.backup_select, self.backup_choosed) + self.eventManager.addWidgetEvent(self.formatbt, self.do_format) + self.eventManager.addWidgetEvent(self.devicelist, self.device_selected) + self.eventManager.addWidgetEvent(self.refreshbt, self.update_list) + self.eventManager.addWidgetEvent(self.helpbt, self.help_dialog) + self.eventManager.addWidgetEvent(self.aboutbt, self.aboutDialog) self.u = None try: self.u = UDisks2() except: message = _('UDisks2 is not available on your system') - self.logger(message) + logging.error(message) self.emergency(message) if not self.get_devices(): self.dialog.destroy() yui.YUILoader.deleteUI() exit() + self.active_signal() self.device_selected() self.dialog.recalcLayout() - self.ancrage.showChild() + self.uEventQueue = SimpleQueue() self.glib_loop = GLib.MainLoop() self.glib_thread = threading.Thread(target=self.glib_mainloop, args=(self.glib_loop,)) self.glib_thread.start() + def ask_image(self): + self.img_name = yui.YUI.app().askForExistingFile("", "*.iso *.img", self.ChooseImage) + if self.img_name != "": + self.ima.setLabel(os.path.basename(self.img_name)) + self.dialog.recalcLayout() + self.writebt.setEnabled() + self.activate_devicelist() + self.persistencecb.setEnabled() + + def check_persistence(self): + if self.persistencecb.isChecked(): + self.cryptcb.setEnabled() + else: + self.cryptcb.setDisabled() + self.cryptkey.setDisabled() + self.cryptcb.setChecked(False) - def glib_mainloop(self, loop): - ''' - thread function for glib main loop - listen to signal from udisks - ''' - self.u.iface["org.freedesktop.DBus.ObjectManager"].InterfacesAdded.connect(self.device_changed) - loop.run() + def check_encryt(self): + if self.cryptcb.isChecked(): + self.cryptkey.setEnabled() + else: + self.cryptkey.setDisabled() - def device_changed(self, a, b): - self.uEventQueue.put({'event': "device-changed", 'value': True}) - def ask_format(self): atelier = yui.YUI.widgetFactory() dialog = atelier.createPopupDialog() @@ -830,83 +890,27 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog dlg.setMinSize(60, 8) return dlg.show() == yui.YMGAMessageBox.B_ONE - def handleevent(self): + def doSomethingIntoLoop(self): self.traitement = None - while True: - event = self.dialog.waitForEvent(100) - if event.eventType() == yui.YEvent.CancelEvent: - self.close() - break - if event.widget() == self.quitbt: - self.close() - break - if event.widget() == self.ima: - self.img_name = yui.YUI.app().askForExistingFile("", "*.iso *.img", self.ChooseImage) - if self.img_name != "": - self.ima.setLabel(os.path.basename(self.img_name)) - self.dialog.recalcLayout() - self.writebt.setEnabled() - self.activate_devicelist() - self.persistencecb.setEnabled() - if event.widget() == self.persistencecb: - print(self.persistencecb.value) - if self.persistencecb.isChecked(): - self.cryptcb.setEnabled() - else: - self.cryptcb.setDisabled() - self.cryptkey.setDisabled() - self.cryptcb.setChecked(False) - if event.widget() == self.cryptcb: - if self.cryptcb.isChecked(): - self.cryptkey.setEnabled() - else: - self.cryptkey.setDisabled() - if event.widget() == self.writebt: - self.wip_unsensitive() - self.do_write() - self.restore() - if event.widget() == self.backupbt: - self.wip_unsensitive() - self.backup_go() - self.restore() - if event.widget() == self.backup_select: - self.backup_img_name = yui.YUI.app().askForSaveFileName("", "*.img", _("Backup to:")) - if self.backup_img_name != '': - self.backup_choosed() - if event.widget() == self.formatbt: - code, format_type, name = self.ask_format() - if code: - self.do_format(format_type, name) - self.restore() - if event.widget() == self.devicelist: - self.device_selected() - try: - if event.widget() == self.refreshbt: - self.update_list() - except: - pass - try: - if event.widget() == self.helpbt: - self.help_dialog() - except: - pass - try: - if event.widget() == self.quitbt: - self.confirm_close() - except: - pass - if event.widget() == self.aboutbt: - self.aboutDialog() - try: - item = self.uEventQueue.get_nowait() - if item['event'] == "device-changed": - self.update_list_on_event() - except Exception as e: - pass - - def run(self): + #if event.eventType() == yui.YEvent.CancelEvent: + #self.confirm_close() + #break + try: + item = self.uEventQueue.get_nowait() + if item['event'] == "device-changed": + self.update_list_on_event() + except Exception as e: + pass + + def run(self, debug=False): + + self._setupUI() + + self._running = True + self.timeout = 100 + try: - self.handleevent() + self._handleEvents() except Exception: import traceback traceback.print_exc() |