Example #1
0
    def __init__(self, core: ApartCore, z_options: List[str]):
        Gtk.Stack.__init__(self)
        self.core = core
        self.z_options = z_options

        self.get_style_context().add_class('progress-view')
        self.next_notification = NotificationHelper()

        self.nothing_label = Gtk.Label('Select a partition to clone',
                                       xalign=0.5,
                                       vexpand=True)
        self.nothing_label.get_style_context().add_class('dim-label')
        self.add(self.nothing_label)

        self.content = Gtk.VBox(valign=Gtk.Align.START)
        self.add(self.content)

        self.running_jobs_label = Gtk.Label('Running', halign=Gtk.Align.START)
        self.running_jobs_label.get_style_context().add_class('section-title')
        self.content.add(self.running_jobs_label)

        # self.running_jobs: Dict[str, RunningJob] = {} <- not compatible with 3.5
        self.running_jobs = {}
        self.running_jobs_grid = Gtk.Grid(orientation=Gtk.Orientation.VERTICAL,
                                          column_spacing=6,
                                          row_spacing=6)

        self.running_jobs_grid.get_style_context().add_class('jobs')
        self.content.add(self.running_jobs_grid)

        # self.finished_jobs: Dict[str, FinishedJob] = {} <- not compatible with 3.5
        self.finished_jobs = {}
        self.finished_jobs_label = Gtk.Label('History', halign=Gtk.Align.START)
        self.finished_jobs_label.get_style_context().add_class('section-title')
        self.content.add(self.finished_jobs_label)

        self.finished_jobs_grid = Gtk.Grid(
            orientation=Gtk.Orientation.VERTICAL, column_spacing=6)
        self.finished_jobs_grid.get_style_context().add_class('finished-jobs')
        self.content.add(self.finished_jobs_grid)

        self.show_all()

        self.listener = MessageListener(
            message_predicate=lambda m: m['type'] in
            ['clone', 'restore', 'clone-failed', 'restore-failed'],
            on_message=lambda m: GLib.idle_add(self.on_job_message, m),
            listen_to=core)

        GLib.timeout_add(interval=1000, function=self.update_jobs)
        self.connect('destroy', self.save_history)
        GLib.idle_add(self.read_history)
Example #2
0
    def __init__(self):
        Gtk.Window.__init__(self, title='apart')
        self.dying = False
        self.status_listener = MessageListener(
            on_message=lambda m: GLib.idle_add(self.on_status_msg, m),
            message_predicate=lambda m: m['type'] == 'status')
        self.core = ApartCore(
            listeners=[self.status_listener],
            on_finish=lambda code: GLib.idle_add(self.on_delete))
        self.sources = None
        self.sources_interest = []  # array of callbacks on sources update

        self.set_default_size(height=300, width=300 * 16 / 9)

        self.loading_body = LoadingBody()
        self.clone_body = None

        self.add(self.loading_body)

        self.connect('delete-event', self.on_delete)

        self.set_icon_name('apart')
Example #3
0
    def delete_image(self, arg=None):
        filename = self.msg['destination']
        dialog = OkCancelDialog(self.delete_image_btn.get_toplevel(),
                                header='Delete image file',
                                text="Delete {}?".format(filename),
                                message_type=Gtk.MessageType.WARNING)
        user_response = dialog.run()
        dialog.destroy()
        if user_response != Gtk.ResponseType.OK:
            return

        for btn in self.buttons.get_children():
            btn.set_sensitive(False)
            btn.set_tooltip_text('Deleting...')

        def on_response(msg: Dict):
            if msg['type'] == 'deleted-clone':
                self.forget()
            else:  # failed
                err_dialog = OkDialog(self.delete_image_btn.get_toplevel(),
                                      header='Delete failed',
                                      text='Could not delete {}: {}'.format(
                                          filename, msg['error']),
                                      message_type=Gtk.MessageType.ERROR)
                err_dialog.run()
                err_dialog.destroy()
                for btn in self.buttons.get_children():
                    btn.set_sensitive(True)
                self.forget_btn.set_tooltip_text(FORGET_TIP)
                self.rerun_btn.set_tooltip_text(RERUN_TIP)
                self.delete_image_btn.set_tooltip_text(DELETE_TIP)

        MessageListener(
            message_predicate=lambda m: m['type'] in
            ['deleted-clone', 'delete-clone-failed'] and m['file'] == filename,
            on_message=lambda m: GLib.idle_add(on_response, m),
            listen_to=self.core,
            one_time=True)

        self.core.send('type: delete-clone\nfile: ' + filename)
Example #4
0
class Window(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title='apart')
        self.dying = False
        self.status_listener = MessageListener(
            on_message=lambda m: GLib.idle_add(self.on_status_msg, m),
            message_predicate=lambda m: m['type'] == 'status')
        self.core = ApartCore(
            listeners=[self.status_listener],
            on_finish=lambda code: GLib.idle_add(self.on_delete))
        self.sources = None
        self.sources_interest = []  # array of callbacks on sources update

        self.set_default_size(height=300, width=300 * 16 / 9)

        self.loading_body = LoadingBody()
        self.clone_body = None

        self.add(self.loading_body)

        self.connect('delete-event', self.on_delete)

        self.set_icon_name('apart')

    def register_interest_in_sources(self, on_update_callback: Callable[[Dict],
                                                                        None]):
        """
        Register a callback to be run every time a new sources message is received
        Note callbacks are run on the GTK main thread
        Run callback immediately if sources are available
        """
        if self.sources:
            on_update_callback(self.sources)
        self.sources_interest.append(on_update_callback)

    def on_status_msg(self, msg: Dict):
        if msg['status'] == 'dying':
            self.on_delete()
        elif msg['status'] == 'started':
            if msg['sources']:
                self.sources = msg['sources']
                self.clone_body = CloneBody(
                    self.core,
                    sources=msg['sources'],
                    z_options=msg['compression_options'])
                self.remove(self.loading_body)
                self.add(self.clone_body)
                self.clone_body.show_all()
            else:
                err_dialog = OkDialog(self,
                                      text='No partitions found',
                                      ok_button_text='Exit',
                                      message_type=Gtk.MessageType.ERROR)
                err_dialog.run()
                err_dialog.destroy()
                self.on_delete()
        elif self.clone_body and msg['status'] == 'running':
            self.sources = msg['sources']
            # TODO move to sources_interest with a reliable way of getting toplevel
            self.clone_body.update_sources(msg['sources'])
            for callback in self.sources_interest:
                callback(self.sources)

    def on_delete(self, *args):
        if self.dying:
            return
        self.status_listener.stop_listening()
        if self.clone_body:
            self.remove(self.clone_body)
            self.clone_body.destroy()
            self.add(self.loading_body)
        self.core.kill()
        self.destroy()
        Gtk.main_quit()
        self.dying = True