예제 #1
0
    def __init__(self):
        self.environment = EnvironmentModel()

        self.window = Gtk.Window()
        self.window.set_title('SftpMan')
        self.window.resize(550, 600)
        self.window.set_position(Gtk.WindowPosition.CENTER)
        self.window.connect('destroy', self.handler_destroy)

        self.icon_file = os.path.join(os.path.dirname(__file__), '..',
                                      'sftpman-gtk.png')
        if not os.path.exists(self.icon_file):
            self.icon_file = '/usr/share/pixmaps/sftpman-gtk.png'
            if not os.path.exists(self.icon_file):
                self.icon_file = None
        if self.icon_file is not None:
            self.window.set_icon_from_file(self.icon_file)

        self.window.set_titlebar(self._create_header_bar())

        self.list_container_wrapper = Gtk.ScrolledWindow()
        self.list_container_wrapper.add_with_viewport(
            self._create_list_container())

        vbox_main = create_vbox()
        vbox_main.pack_start(self.list_container_wrapper, True, True, 0)
        vbox_main.pack_start(self._create_record_container(), False, False, 0)

        self.vbox_main = vbox_main

        self.window.add(vbox_main)
        self.window.show_all()

        self.in_list_mode = True

        def list_periodic_refresher():
            while True:
                # Trying to update the GTK GUI from a thread causes
                # a segmentation fault - this is the proper way to do it
                if self.in_list_mode:
                    GLib.idle_add(self.refresh_list)
                sleep(15)

        refresher_thread = Thread(target=list_periodic_refresher)
        refresher_thread.daemon = True
        refresher_thread.start()
예제 #2
0
    def __init__(self):
        self.environment = EnvironmentModel()

        self.window = Gtk.Window()
        self.window.set_title('SftpMan')
        self.window.resize(550, 600)
        self.window.set_position(Gtk.WindowPosition.CENTER)
        self.window.connect('destroy', self.handler_destroy)

        self.icon_file = os.path.join(os.path.dirname(__file__), '..', 'sftpman-gtk.png')
        if not os.path.exists(self.icon_file):
            self.icon_file = '/usr/share/pixmaps/sftpman-gtk.png'
            if not os.path.exists(self.icon_file):
                self.icon_file = None
        if self.icon_file is not None:
            self.window.set_icon_from_file(self.icon_file)

        self.window.set_titlebar(self._create_header_bar())

        self.list_container_wrapper = Gtk.ScrolledWindow()
        self.list_container_wrapper.add_with_viewport(self._create_list_container())

        vbox_main = create_vbox()
        vbox_main.pack_start(self.list_container_wrapper, True, True, 0)
        vbox_main.pack_start(self._create_record_container(), False, False, 0)

        self.vbox_main = vbox_main

        self.window.add(vbox_main)
        self.window.show_all()

        self.in_list_mode = True

        def list_periodic_refresher():
            while True:
                # Trying to update the GTK GUI from a thread causes
                # a segmentation fault - this is the proper way to do it
                if self.in_list_mode:
                    GLib.idle_add(self.refresh_list)
                sleep(15)

        refresher_thread = Thread(target=list_periodic_refresher)
        refresher_thread.daemon = True
        refresher_thread.start()
예제 #3
0
    def __init__(self):
        self.environment = EnvironmentModel()

        self.window = Gtk.Window()
        self.window.set_title("SftpMan")
        self.window.resize(550, 750)
        # Add some padding, because of the GTK3 window size grip
        self.window.set_border_width(12)
        self.window.set_position(Gtk.WindowPosition.CENTER)
        self.window.connect("destroy", self.handler_destroy)

        self.icon_file = os.path.join(os.path.dirname(__file__), "..", "sftpman-gtk.png")
        if not os.path.exists(self.icon_file):
            self.icon_file = "/usr/share/pixmaps/sftpman-gtk.png"
            if not os.path.exists(self.icon_file):
                self.icon_file = None
        if self.icon_file is not None:
            self.window.set_icon_from_file(self.icon_file)

        self.list_container_wrapper = Gtk.ScrolledWindow()
        self.list_container_wrapper.add_with_viewport(self._create_list_container())

        vbox_main = create_vbox()
        vbox_main.pack_start(self._create_tool_box(), False, False, 0)
        vbox_main.pack_start(self.list_container_wrapper, True, True, 0)
        vbox_main.pack_start(self._create_record_container(), False, False, 0)

        self.window.add(vbox_main)
        self.window.show_all()

        self.in_list_mode = True

        def list_periodic_refresher():
            while True:
                # Trying to update the GTK GUI from a thread causes
                # a segmentation fault - this is the proper way to do it
                if self.in_list_mode:
                    GObject.idle_add(self.refresh_list)
                sleep(15)

        refresher_thread = Thread(target=list_periodic_refresher)
        refresher_thread.daemon = True
        refresher_thread.start()
예제 #4
0
class SftpManGtk(object):
    def handler_destroy(self, widget, data=None):
        Gtk.main_quit()

    def destroy(self, widget, data=None):
        Gtk.main_quit()

    def _get_system_by_id(self, system_id):
        return SystemModel.create_by_id(system_id, self.environment)

    def _get_system_controller_by_id(self, system_id):
        system = SystemModel.create_by_id(system_id, self.environment)
        return SystemControllerModel(system, self.environment)

    def handler_open_by_id(self, btn, system_id):
        controller = self._get_system_controller_by_id(system_id)
        if controller.mounted:
            open_file_browser(controller.mount_point_local)

    def _handle_mount(self, system_id):
        controller = self._get_system_controller_by_id(system_id)
        try:
            controller.mount()
        except SftpMountException as e:
            msg = "Mounting failed for {system_id}.\n\n" "Mount command:\n{cmd}\n\n" "Command output:\n{output}"
            msg = msg.format(system_id=system_id, cmd=e.mount_cmd, output=e.mount_cmd_output)
            show_warning_message(msg)

    def handler_mount_by_id(self, btn, system_id):
        self._handle_mount(system_id)
        self.refresh_list()

    def handler_unmount_by_id(self, btn, system_id):
        controller = self._get_system_controller_by_id(system_id)
        controller.unmount()
        self.refresh_list()

    def handler_mount_all(self, btn):
        for system_id in self.environment.get_available_ids():
            self._handle_mount(system_id)
        self.refresh_list()

    def handler_unmount_all(self, btn):
        for system_id in self.environment.get_mounted_ids():
            controller = self._get_system_controller_by_id(system_id)
            controller.unmount()
        self.refresh_list()

    def handler_about(self, btn):
        dialog = Gtk.AboutDialog()
        dialog.set_program_name("SftpMan")
        dialog.set_version(sftpman_gtk.__version__)
        dialog.set_license_type(Gtk.License.BSD)
        dialog.set_comments("Mount sftp/sshfs file systems with ease")
        dialog.set_website(sftpman_gtk.__website_url__)
        dialog.set_website_label(sftpman_gtk.__website_url__)
        dialog.set_copyright(sftpman_gtk.__copyright__)
        if self.icon_file is not None:
            dialog.set_logo(GdkPixbuf.Pixbuf.new_from_file(self.icon_file))
        dialog.set_transient_for(self.window)
        dialog.run()
        dialog.destroy()

    def handler_create_new(self, btn):
        system = SystemModel()
        system.id = ""
        system.user = shell_exec("whoami").strip()
        system.mount_point = "/home/%s/" % system.user
        system.mount_opts = ["follow_symlinks", "workaround=rename", "big_writes"]
        RecordRenderer(self, system, added=False).render()

    def handler_edit(self, btn, system_id):
        system = self._get_system_by_id(system_id)
        RecordRenderer(self, system, added=True).render()

    def refresh_list(self):
        ids_mounted = self.environment.get_mounted_ids()

        for childHbox in self.list_container.get_children():
            self.list_container.remove(childHbox)

        self.list_container.pack_start(create_hbox(), False, False, 0)

        ids_available = self.environment.get_available_ids()
        for system_id in ids_available:
            is_mounted = system_id in ids_mounted

            hbox = create_hbox()

            icon = Gtk.Image()
            icon.set_from_stock(Gtk.STOCK_YES if is_mounted else Gtk.STOCK_NO, Gtk.IconSize.SMALL_TOOLBAR)
            hbox.pack_start(icon, True, True, 0)

            # Sftp system id
            label = Gtk.Label(label=system_id)
            label.set_alignment(0, 0)
            label.set_size_request(150, 35)
            hbox.pack_start(label, True, True, 0)

            # Open/Mount button
            if is_mounted:
                btn_mount_or_open = create_button("Open", Gtk.STOCK_OPEN)
                btn_mount_or_open.connect("clicked", self.handler_open_by_id, system_id)
            else:
                btn_mount_or_open = create_button("Mount", Gtk.STOCK_CONNECT)
                btn_mount_or_open.connect("clicked", self.handler_mount_by_id, system_id)

            # Unmount button
            btn_unmount = create_button("Unmount", Gtk.STOCK_DISCONNECT)
            if not is_mounted:
                btn_unmount.set_sensitive(False)
            else:
                btn_unmount.connect("clicked", self.handler_unmount_by_id, system_id)

            # Edit button
            btn_edit = create_button("Edit", Gtk.STOCK_EDIT)
            btn_edit.connect("clicked", self.handler_edit, system_id)

            hbox.pack_start(btn_mount_or_open, True, True, 0)
            hbox.pack_start(btn_unmount, True, True, 0)
            hbox.pack_start(btn_edit, True, True, 0)

            self.list_container.pack_start(hbox, False, False, 0)

        if len(ids_available) == 0:
            label = Gtk.Label(label="No sftp systems defined yet.")
            label.set_justify(Gtk.Justification.CENTER)
            self.list_container.pack_start(label, True, True, 0)

        self.list_container.show_all()

    def show_list(self):
        self.list_container_wrapper.show()
        self.in_list_mode = True

    def hide_list(self):
        self.list_container_wrapper.hide()
        self.in_list_mode = False

    def _create_tool_box(self):
        self.toolbox = create_hbox()
        self.toolbox.pack_start(create_button("New", Gtk.STOCK_ADD, onclick=self.handler_create_new), True, True, 0)
        self.toolbox.pack_start(
            create_button("Mount all", Gtk.STOCK_CONNECT, onclick=self.handler_mount_all), True, True, 0
        )
        self.toolbox.pack_start(
            create_button("Unmount all", Gtk.STOCK_DISCONNECT, onclick=self.handler_unmount_all), True, True, 0
        )
        self.toolbox.pack_start(create_button("About", Gtk.STOCK_ABOUT, onclick=self.handler_about), True, True, 0)
        return self.toolbox

    def _create_list_container(self):
        # This would contain the sftp systems list
        self.list_container = create_vbox()
        self.refresh_list()
        return self.list_container

    def _create_record_container(self):
        # This would contain the form entries when adding/editing systems
        self.record_container = create_hbox()
        return self.record_container

    def __init__(self):
        self.environment = EnvironmentModel()

        self.window = Gtk.Window()
        self.window.set_title("SftpMan")
        self.window.resize(550, 750)
        # Add some padding, because of the GTK3 window size grip
        self.window.set_border_width(12)
        self.window.set_position(Gtk.WindowPosition.CENTER)
        self.window.connect("destroy", self.handler_destroy)

        self.icon_file = os.path.join(os.path.dirname(__file__), "..", "sftpman-gtk.png")
        if not os.path.exists(self.icon_file):
            self.icon_file = "/usr/share/pixmaps/sftpman-gtk.png"
            if not os.path.exists(self.icon_file):
                self.icon_file = None
        if self.icon_file is not None:
            self.window.set_icon_from_file(self.icon_file)

        self.list_container_wrapper = Gtk.ScrolledWindow()
        self.list_container_wrapper.add_with_viewport(self._create_list_container())

        vbox_main = create_vbox()
        vbox_main.pack_start(self._create_tool_box(), False, False, 0)
        vbox_main.pack_start(self.list_container_wrapper, True, True, 0)
        vbox_main.pack_start(self._create_record_container(), False, False, 0)

        self.window.add(vbox_main)
        self.window.show_all()

        self.in_list_mode = True

        def list_periodic_refresher():
            while True:
                # Trying to update the GTK GUI from a thread causes
                # a segmentation fault - this is the proper way to do it
                if self.in_list_mode:
                    GObject.idle_add(self.refresh_list)
                sleep(15)

        refresher_thread = Thread(target=list_periodic_refresher)
        refresher_thread.daemon = True
        refresher_thread.start()

    def _perform_preflight_check(self):
        checks_pass, failures = self.environment.perform_preflight_check()
        if not checks_pass:
            for msg in failures:
                show_warning_message(msg)
            show_warning_message("Mounting will fail until all problems are fixed.")

    def main(self):
        self._perform_preflight_check()
        Gtk.main()
예제 #5
0
class SftpManGtk(object):

    def handler_destroy(self, widget, data=None):
        Gtk.main_quit()

    def destroy(self, widget, data=None):
        Gtk.main_quit()

    def _get_system_by_id(self, system_id):
        return SystemModel.create_by_id(system_id, self.environment)

    def _get_system_controller_by_id(self, system_id):
        system =  SystemModel.create_by_id(system_id, self.environment)
        return SystemControllerModel(system, self.environment)

    def handler_open_by_id(self, btn, system_id):
        controller = self._get_system_controller_by_id(system_id)
        if controller.mounted:
            open_file_browser(controller.mount_point_local)

    def _handle_mount(self, system_id):
        controller = self._get_system_controller_by_id(system_id)
        try:
            controller.mount()
        except SftpMountException as e:
            msg = ('Mounting failed for {system_id}.\n\n'
                   'Mount command:\n{cmd}\n\n'
                   'Command output:\n{output}')
            msg = msg.format(
                system_id = system_id,
                cmd = e.mount_cmd,
                output = e.mount_cmd_output,
            )
            show_warning_message(msg)

    def handler_mount_by_id(self, btn, system_id):
        self._handle_mount(system_id)
        self.refresh_list()

    def handler_unmount_by_id(self, btn, system_id):
        controller = self._get_system_controller_by_id(system_id)
        controller.unmount()
        self.refresh_list()

    def handler_mount_all(self, btn):
        for system_id in self.environment.get_available_ids():
            self._handle_mount(system_id)
        self.refresh_list()

    def handler_unmount_all(self, btn):
        for system_id in self.environment.get_mounted_ids():
            controller = self._get_system_controller_by_id(system_id)
            controller.unmount()
        self.refresh_list()

    def handler_about(self, btn):
        dialog = Gtk.AboutDialog()
        dialog.set_program_name('SftpMan')
        dialog.set_version(sftpman_gtk.__version__)
        dialog.set_license_type(Gtk.License.BSD)
        dialog.set_comments('Mount sftp/sshfs file systems with ease')
        dialog.set_website(sftpman_gtk.__website_url__)
        dialog.set_website_label(sftpman_gtk.__website_url__)
        dialog.set_copyright(sftpman_gtk.__copyright__)
        if self.icon_file is not None:
            dialog.set_logo(GdkPixbuf.Pixbuf.new_from_file(self.icon_file))
        dialog.set_transient_for(self.window)
        dialog.run()
        dialog.destroy()

    def handler_create_new(self, btn):
        system = SystemModel()
        system.id = ''
        system.user = shell_exec('whoami').strip()
        system.mount_point = '/home/%s/' % system.user
        system.mount_opts = ['follow_symlinks', 'workaround=rename', 'big_writes']
        RecordRenderer(self, system, added=False).render()

    def handler_edit(self, btn, system_id):
        system = self._get_system_by_id(system_id)
        RecordRenderer(self, system, added=True).render()

    def refresh_list(self):
        ids_mounted = self.environment.get_mounted_ids()

        for childHbox in self.list_container.get_children():
            self.list_container.remove(childHbox)

        self.list_container.pack_start(create_hbox(), False, False, 0)

        ids_available = self.environment.get_available_ids()
        for system_id in ids_available:
            is_mounted = system_id in ids_mounted

            hbox = create_hbox()

            icon = Gtk.Image()
            icon.set_from_stock(Gtk.STOCK_YES if is_mounted else Gtk.STOCK_NO, Gtk.IconSize.SMALL_TOOLBAR)
            hbox.pack_start(icon, True, True, 0)

            # Sftp system id
            label = Gtk.Label(label=system_id)
            label.set_alignment(0, 0)
            label.set_size_request(150, 35)
            hbox.pack_start(label, True, True, 0)

            # Open/Mount button
            if (is_mounted):
                btn_mount_or_open = create_button('Open', Gtk.STOCK_OPEN)
                btn_mount_or_open.connect('clicked', self.handler_open_by_id, system_id)
            else:
                btn_mount_or_open = create_button('Mount', Gtk.STOCK_CONNECT)
                btn_mount_or_open.connect('clicked', self.handler_mount_by_id, system_id)

            # Unmount button
            btn_unmount = create_button('Unmount', Gtk.STOCK_DISCONNECT)
            if (not is_mounted):
                btn_unmount.set_sensitive(False)
            else:
                btn_unmount.connect('clicked', self.handler_unmount_by_id, system_id)

            # Edit button
            btn_edit = create_button('Edit', Gtk.STOCK_EDIT)
            btn_edit.connect('clicked', self.handler_edit, system_id)

            hbox.pack_start(btn_mount_or_open, True, True, 0)
            hbox.pack_start(btn_unmount, True, True, 0)
            hbox.pack_start(btn_edit, True, True, 0)

            self.list_container.pack_start(hbox, False, False, 0)

        if len(ids_available) == 0:
            label = Gtk.Label(label='No sftp systems defined yet.')
            label.set_justify(Gtk.Justification.CENTER)
            self.list_container.pack_start(label, True, True, 0)

        self.list_container.show_all()

    def show_list(self):
        self.list_container_wrapper.show()
        self.in_list_mode = True

    def hide_list(self):
        self.list_container_wrapper.hide()
        self.in_list_mode = False

    def _create_tool_box(self):
        self.toolbox = create_hbox()
        self.toolbox.pack_start(create_button('New', Gtk.STOCK_ADD, onclick=self.handler_create_new), True, True, 0)
        self.toolbox.pack_start(create_button('Mount all', Gtk.STOCK_CONNECT, onclick=self.handler_mount_all), True, True, 0)
        self.toolbox.pack_start(create_button('Unmount all', Gtk.STOCK_DISCONNECT, onclick=self.handler_unmount_all), True, True, 0)
        self.toolbox.pack_start(create_button('About', Gtk.STOCK_ABOUT, onclick=self.handler_about), True, True, 0)
        return self.toolbox

    def _create_list_container(self):
        # This would contain the sftp systems list
        self.list_container = create_vbox()
        self.refresh_list()
        return self.list_container

    def _create_record_container(self):
        # This would contain the form entries when adding/editing systems
        self.record_container = create_hbox()
        return self.record_container

    def __init__(self):
        self.environment = EnvironmentModel()

        self.window = Gtk.Window()
        self.window.set_title('SftpMan')
        self.window.resize(550, 750)
        # Add some padding, because of the GTK3 window size grip
        self.window.set_border_width(12)
        self.window.set_position(Gtk.WindowPosition.CENTER)
        self.window.connect('destroy', self.handler_destroy)

        self.icon_file = os.path.join(os.path.dirname(__file__), '..', 'sftpman-gtk.png')
        if not os.path.exists(self.icon_file):
            self.icon_file = '/usr/share/pixmaps/sftpman-gtk.png'
            if not os.path.exists(self.icon_file):
                self.icon_file = None
        if self.icon_file is not None:
            self.window.set_icon_from_file(self.icon_file)

        self.list_container_wrapper = Gtk.ScrolledWindow()
        self.list_container_wrapper.add_with_viewport(self._create_list_container())

        vbox_main = create_vbox()
        vbox_main.pack_start(self._create_tool_box(), False, False, 0)
        vbox_main.pack_start(self.list_container_wrapper, True, True, 0)
        vbox_main.pack_start(self._create_record_container(), False, False, 0)

        self.window.add(vbox_main)
        self.window.show_all()

        self.in_list_mode = True

        def list_periodic_refresher():
            while True:
                # Trying to update the GTK GUI from a thread causes
                # a segmentation fault - this is the proper way to do it
                if self.in_list_mode:
                    GObject.idle_add(self.refresh_list)
                sleep(15)

        refresher_thread = Thread(target=list_periodic_refresher)
        refresher_thread.daemon = True
        refresher_thread.start()

    def _perform_preflight_check(self):
        checks_pass, failures = self.environment.perform_preflight_check()
        if not checks_pass:
            for msg in failures:
                show_warning_message(msg)
            show_warning_message('Mounting will fail until all problems are fixed.')

    def main(self):
        self._perform_preflight_check()
        Gtk.main()
예제 #6
0
class SftpManGtk(object):

    def handler_destroy(self, widget, data=None):
        Gtk.main_quit()

    def destroy(self, widget, data=None):
        Gtk.main_quit()

    def _get_system_by_id(self, system_id):
        return SystemModel.create_by_id(system_id, self.environment)

    def _get_system_controller_by_id(self, system_id):
        system =  SystemModel.create_by_id(system_id, self.environment)
        return SystemControllerModel(system, self.environment)

    def handler_open_by_id(self, btn, system_id):
        controller = self._get_system_controller_by_id(system_id)
        if controller.mounted:
            open_file_browser(controller.mount_point_local)

    def _handle_mount(self, system_id):
        controller = self._get_system_controller_by_id(system_id)
        try:
            controller.mount()
        except SftpMountException as e:
            msg = ('Mounting failed for {system_id}.\n\n'
                   'Mount command:\n{cmd}\n\n'
                   'Command output:\n{output}')
            msg = msg.format(
                system_id = system_id,
                cmd = e.mount_cmd,
                output = e.mount_cmd_output,
            )
            show_warning_message(self.window, msg)

    def handler_mount_by_id(self, btn, system_id):
        self._handle_mount(system_id)
        self.refresh_list()

    def handler_unmount_by_id(self, btn, system_id):
        controller = self._get_system_controller_by_id(system_id)
        controller.unmount()
        self.refresh_list()

    def handler_mount_all(self, btn):
        for system_id in self.environment.get_available_ids():
            self._handle_mount(system_id)
        self.refresh_list()

    def handler_unmount_all(self, btn):
        for system_id in self.environment.get_mounted_ids():
            controller = self._get_system_controller_by_id(system_id)
            controller.unmount()
        self.refresh_list()

    def handler_about(self, btn):
        dialog = Gtk.AboutDialog()
        dialog.set_program_name('SftpMan')
        dialog.set_version(sftpman_gtk.__version__)
        dialog.set_license_type(Gtk.License.GPL_3_0)
        dialog.set_comments('Mount sftp/sshfs file systems with ease')
        dialog.set_website(sftpman_gtk.__website_url__)
        dialog.set_website_label(sftpman_gtk.__website_url__)
        dialog.set_copyright(sftpman_gtk.__copyright__)
        if self.icon_file is not None:
            dialog.set_logo(GdkPixbuf.Pixbuf.new_from_file(self.icon_file))
        dialog.set_transient_for(self.window)
        dialog.run()
        dialog.destroy()

    def handler_create_new(self, btn):
        system = SystemModel()
        system.id = ''
        system.user = shell_exec('whoami').strip()
        system.mount_point = '/home/%s/' % system.user
        system.mount_opts = ['follow_symlinks', 'workaround=rename']
        RecordRenderer(self, system, added=False).render()

    def handler_edit(self, btn, system_id):
        system = self._get_system_by_id(system_id)
        RecordRenderer(self, system, added=True).render()

    def refresh_list(self):
        ids_mounted = self.environment.get_mounted_ids()

        for child in self.list_container.get_children():
            self.list_container.remove(child)

        ids_available = self.environment.get_available_ids()
        for system_id in ids_available:
            is_mounted = system_id in ids_mounted

            hbox = create_hbox()

            icon_name = 'network-server' if is_mounted else 'network-offline'
            icon = Gtk.Image.new_from_icon_name(icon_name, Gtk.IconSize.SMALL_TOOLBAR)
            hbox.pack_start(icon, False, True, 10)

            # Sftp system id
            label = Gtk.Label(label=system_id)
            label.set_alignment(0, 0)
            label.set_size_request(150, 35)
            hbox.pack_start(label, True, True, 0)

            # Open/Mount button
            if (is_mounted):
                btn_mount_or_open = Gtk.Button()
                btn_mount_or_open.set_label('Open')
                btn_mount_or_open.set_image(Gtk.Image.new_from_icon_name('document-open', Gtk.IconSize.BUTTON))
                btn_mount_or_open.set_always_show_image(True)
                btn_mount_or_open.set_tooltip_text('Opens this filesystem')
                btn_mount_or_open.connect("clicked", self.handler_open_by_id, system_id)
            else:
                btn_mount_or_open = Gtk.Button()
                btn_mount_or_open.set_label('Mount')
                btn_mount_or_open.set_image(Gtk.Image.new_from_icon_name('network-idle', Gtk.IconSize.BUTTON))
                btn_mount_or_open.set_always_show_image(True)
                btn_mount_or_open.set_tooltip_text('Mounts this filesystem')
                btn_mount_or_open.connect("clicked", self.handler_mount_by_id, system_id)
            btn_mount_or_open.set_size_request(120, 35)

            # Unmount button
            btn_unmount = Gtk.Button()
            btn_unmount.set_label('Unmount')
            btn_unmount.set_image(Gtk.Image.new_from_icon_name('network-offline', Gtk.IconSize.BUTTON))
            btn_unmount.set_always_show_image(True)
            btn_unmount.set_tooltip_text('Unmounts this filesystem')
            if not is_mounted:
                btn_unmount.set_sensitive(False)
            else:
                btn_unmount.connect("clicked", self.handler_unmount_by_id, system_id)
            btn_unmount.set_size_request(120, 35)

            # Edit button
            btn_edit = Gtk.Button()
            btn_edit.set_image(Gtk.Image.new_from_icon_name('preferences-system', Gtk.IconSize.BUTTON))
            btn_edit.set_always_show_image(False)
            btn_edit.set_tooltip_text("Edit this filesystem's settings")
            btn_edit.connect("clicked", self.handler_edit, system_id)
            btn_edit.set_margin_end(10)

            hbox.pack_start(btn_mount_or_open, False, True, 0)
            hbox.pack_start(btn_unmount, False, True, 0)
            hbox.pack_start(btn_edit, False, True, 0)

            row = Gtk.ListBoxRow()
            row.add(hbox)
            self.list_container.add(row)

        if len(ids_available) == 0:
            label = Gtk.Label(label='No sftp systems defined yet.')
            label.set_justify(Gtk.Justification.CENTER)
            self.list_container.add(label)

        self.list_container.show_all()

    def show_list(self):
        self.list_container_wrapper.show()
        self.in_list_mode = True

    def hide_list(self):
        self.list_container_wrapper.hide()
        self.in_list_mode = False

    def _create_header_bar(self):
        self.header_bar = Gtk.HeaderBar()
        self.header_bar.set_show_close_button(True)

        btn_add_new = Gtk.Button()
        btn_add_new.set_label('New')
        btn_add_new.set_image(Gtk.Image.new_from_icon_name('document-new', Gtk.IconSize.LARGE_TOOLBAR))
        btn_add_new.set_always_show_image(True)
        btn_add_new.set_tooltip_text('Add a new filesystem')
        btn_add_new.connect("clicked", self.handler_create_new)
        self.header_bar.pack_start(btn_add_new)

        btn_about = Gtk.Button()
        btn_about.set_image(Gtk.Image.new_from_icon_name('help-about', Gtk.IconSize.LARGE_TOOLBAR))
        btn_about.connect("clicked", self.handler_about)
        self.header_bar.pack_end(btn_about)

        btn_unmount_all = Gtk.Button()
        btn_unmount_all.set_label('Unmount all')
        btn_unmount_all.set_image(Gtk.Image.new_from_icon_name('network-offline', Gtk.IconSize.LARGE_TOOLBAR))
        btn_unmount_all.set_always_show_image(True)
        btn_unmount_all.set_tooltip_text('Unmounts all filesystems')
        btn_unmount_all.connect("clicked", self.handler_unmount_all)
        self.header_bar.pack_end(btn_unmount_all)

        btn_mount_all = Gtk.Button()
        btn_mount_all.set_label('Mount all')
        btn_mount_all.set_image(Gtk.Image.new_from_icon_name('network-idle', Gtk.IconSize.LARGE_TOOLBAR))
        btn_mount_all.set_always_show_image(True)
        btn_mount_all.set_tooltip_text('Mounts all filesystems')
        btn_mount_all.connect("clicked", self.handler_mount_all)
        self.header_bar.pack_end(btn_mount_all)

        return self.header_bar

    def _create_list_container(self):
        # This would contain the sftp systems list
        self.list_container = Gtk.ListBox()
        self.list_container.set_selection_mode(Gtk.SelectionMode.NONE)
        self.refresh_list()
        return self.list_container

    def _create_record_container(self):
        # This would contain the form entries when adding/editing systems
        self.record_container = create_hbox()
        return self.record_container

    def __init__(self):
        self.environment = EnvironmentModel()

        self.window = Gtk.Window()
        self.window.set_title('SftpMan')
        self.window.resize(550, 600)
        self.window.set_position(Gtk.WindowPosition.CENTER)
        self.window.connect('destroy', self.handler_destroy)

        self.icon_file = os.path.join(os.path.dirname(__file__), '..', 'sftpman-gtk.png')
        if not os.path.exists(self.icon_file):
            self.icon_file = '/usr/share/pixmaps/sftpman-gtk.png'
            if not os.path.exists(self.icon_file):
                self.icon_file = None
        if self.icon_file is not None:
            self.window.set_icon_from_file(self.icon_file)

        self.window.set_titlebar(self._create_header_bar())

        self.list_container_wrapper = Gtk.ScrolledWindow()
        self.list_container_wrapper.add_with_viewport(self._create_list_container())

        vbox_main = create_vbox()
        vbox_main.pack_start(self.list_container_wrapper, True, True, 0)
        vbox_main.pack_start(self._create_record_container(), False, False, 0)

        self.vbox_main = vbox_main

        self.window.add(vbox_main)
        self.window.show_all()

        self.in_list_mode = True

        def list_periodic_refresher():
            while True:
                # Trying to update the GTK GUI from a thread causes
                # a segmentation fault - this is the proper way to do it
                if self.in_list_mode:
                    GLib.idle_add(self.refresh_list)
                sleep(15)

        refresher_thread = Thread(target=list_periodic_refresher)
        refresher_thread.daemon = True
        refresher_thread.start()

    def _perform_preflight_check(self):
        checks_pass, failures = self.environment.perform_preflight_check()
        if not checks_pass:
            for msg in failures:
                show_warning_message(self.window, msg)
            show_warning_message(self.window, 'Mounting will fail until all problems are fixed.')

    def main(self):
        self._perform_preflight_check()
        Gtk.main()
예제 #7
0
class SftpManGtk(object):
    def handler_destroy(self, widget, data=None):
        Gtk.main_quit()

    def destroy(self, widget, data=None):
        Gtk.main_quit()

    def _get_system_by_id(self, system_id):
        return SystemModel.create_by_id(system_id, self.environment)

    def _get_system_controller_by_id(self, system_id):
        system = SystemModel.create_by_id(system_id, self.environment)
        return SystemControllerModel(system, self.environment)

    def handler_open_by_id(self, btn, system_id):
        controller = self._get_system_controller_by_id(system_id)
        if controller.mounted:
            open_file_browser(controller.mount_point_local)

    def _handle_mount(self, system_id):
        controller = self._get_system_controller_by_id(system_id)
        try:
            controller.mount()
        except SftpMountException as e:
            msg = ('Mounting failed for {system_id}.\n\n'
                   'Mount command:\n{cmd}\n\n'
                   'Command output:\n{output}')
            msg = msg.format(
                system_id=system_id,
                cmd=e.mount_cmd,
                output=e.mount_cmd_output,
            )
            show_warning_message(self.window, msg)

    def handler_mount_by_id(self, btn, system_id):
        self._handle_mount(system_id)
        self.refresh_list()

    def handler_unmount_by_id(self, btn, system_id):
        controller = self._get_system_controller_by_id(system_id)
        controller.unmount()
        self.refresh_list()

    def handler_mount_all(self, btn):
        for system_id in self.environment.get_available_ids():
            self._handle_mount(system_id)
        self.refresh_list()

    def handler_unmount_all(self, btn):
        for system_id in self.environment.get_mounted_ids():
            controller = self._get_system_controller_by_id(system_id)
            controller.unmount()
        self.refresh_list()

    def handler_about(self, btn):
        dialog = Gtk.AboutDialog()
        dialog.set_program_name('SftpMan')
        dialog.set_version(sftpman_gtk.__version__)
        dialog.set_license_type(Gtk.License.GPL_3_0)
        dialog.set_comments('Mount sftp/sshfs file systems with ease')
        dialog.set_website(sftpman_gtk.__website_url__)
        dialog.set_website_label(sftpman_gtk.__website_url__)
        dialog.set_copyright(sftpman_gtk.__copyright__)
        if self.icon_file is not None:
            dialog.set_logo(GdkPixbuf.Pixbuf.new_from_file(self.icon_file))
        dialog.set_transient_for(self.window)
        dialog.run()
        dialog.destroy()

    def handler_create_new(self, btn):
        system = SystemModel()
        system.id = ''
        system.user = shell_exec('whoami').strip()
        system.mount_point = '/home/%s/' % system.user
        system.mount_opts = ['follow_symlinks', 'workaround=rename']
        RecordRenderer(self, system, added=False).render()

    def handler_edit(self, btn, system_id):
        system = self._get_system_by_id(system_id)
        RecordRenderer(self, system, added=True).render()

    def refresh_list(self):
        ids_mounted = self.environment.get_mounted_ids()

        for child in self.list_container.get_children():
            self.list_container.remove(child)

        ids_available = self.environment.get_available_ids()
        for system_id in ids_available:
            is_mounted = system_id in ids_mounted

            hbox = create_hbox()

            icon_name = 'network-server' if is_mounted else 'network-offline'
            icon = Gtk.Image.new_from_icon_name(icon_name,
                                                Gtk.IconSize.SMALL_TOOLBAR)
            hbox.pack_start(icon, False, True, 10)

            # Sftp system id
            label = Gtk.Label(label=system_id)
            label.set_alignment(0, 0)
            label.set_size_request(150, 35)
            hbox.pack_start(label, True, True, 0)

            # Open/Mount button
            if (is_mounted):
                btn_mount_or_open = Gtk.Button()
                btn_mount_or_open.set_label('Open')
                btn_mount_or_open.set_image(
                    Gtk.Image.new_from_icon_name('document-open',
                                                 Gtk.IconSize.BUTTON))
                btn_mount_or_open.set_always_show_image(True)
                btn_mount_or_open.set_tooltip_text('Opens this filesystem')
                btn_mount_or_open.connect("clicked", self.handler_open_by_id,
                                          system_id)
            else:
                btn_mount_or_open = Gtk.Button()
                btn_mount_or_open.set_label('Mount')
                btn_mount_or_open.set_image(
                    Gtk.Image.new_from_icon_name('network-idle',
                                                 Gtk.IconSize.BUTTON))
                btn_mount_or_open.set_always_show_image(True)
                btn_mount_or_open.set_tooltip_text('Mounts this filesystem')
                btn_mount_or_open.connect("clicked", self.handler_mount_by_id,
                                          system_id)
            btn_mount_or_open.set_size_request(120, 35)

            # Unmount button
            btn_unmount = Gtk.Button()
            btn_unmount.set_label('Unmount')
            btn_unmount.set_image(
                Gtk.Image.new_from_icon_name('network-offline',
                                             Gtk.IconSize.BUTTON))
            btn_unmount.set_always_show_image(True)
            btn_unmount.set_tooltip_text('Unmounts this filesystem')
            if not is_mounted:
                btn_unmount.set_sensitive(False)
            else:
                btn_unmount.connect("clicked", self.handler_unmount_by_id,
                                    system_id)
            btn_unmount.set_size_request(120, 35)

            # Edit button
            btn_edit = Gtk.Button()
            btn_edit.set_image(
                Gtk.Image.new_from_icon_name('preferences-system',
                                             Gtk.IconSize.BUTTON))
            btn_edit.set_always_show_image(False)
            btn_edit.set_tooltip_text("Edit this filesystem's settings")
            btn_edit.connect("clicked", self.handler_edit, system_id)
            btn_edit.set_margin_end(10)

            hbox.pack_start(btn_mount_or_open, False, True, 0)
            hbox.pack_start(btn_unmount, False, True, 0)
            hbox.pack_start(btn_edit, False, True, 0)

            row = Gtk.ListBoxRow()
            row.add(hbox)
            self.list_container.add(row)

        if len(ids_available) == 0:
            label = Gtk.Label(label='No sftp systems defined yet.')
            label.set_justify(Gtk.Justification.CENTER)
            self.list_container.add(label)

        self.list_container.show_all()

    def show_list(self):
        self.list_container_wrapper.show()
        self.in_list_mode = True

    def hide_list(self):
        self.list_container_wrapper.hide()
        self.in_list_mode = False

    def _create_header_bar(self):
        self.header_bar = Gtk.HeaderBar()
        self.header_bar.set_show_close_button(True)

        btn_add_new = Gtk.Button()
        btn_add_new.set_label('New')
        btn_add_new.set_image(
            Gtk.Image.new_from_icon_name('document-new',
                                         Gtk.IconSize.LARGE_TOOLBAR))
        btn_add_new.set_always_show_image(True)
        btn_add_new.set_tooltip_text('Add a new filesystem')
        btn_add_new.connect("clicked", self.handler_create_new)
        self.header_bar.pack_start(btn_add_new)

        btn_about = Gtk.Button()
        btn_about.set_image(
            Gtk.Image.new_from_icon_name('help-about',
                                         Gtk.IconSize.LARGE_TOOLBAR))
        btn_about.connect("clicked", self.handler_about)
        self.header_bar.pack_end(btn_about)

        btn_unmount_all = Gtk.Button()
        btn_unmount_all.set_label('Unmount all')
        btn_unmount_all.set_image(
            Gtk.Image.new_from_icon_name('network-offline',
                                         Gtk.IconSize.LARGE_TOOLBAR))
        btn_unmount_all.set_always_show_image(True)
        btn_unmount_all.set_tooltip_text('Unmounts all filesystems')
        btn_unmount_all.connect("clicked", self.handler_unmount_all)
        self.header_bar.pack_end(btn_unmount_all)

        btn_mount_all = Gtk.Button()
        btn_mount_all.set_label('Mount all')
        btn_mount_all.set_image(
            Gtk.Image.new_from_icon_name('network-idle',
                                         Gtk.IconSize.LARGE_TOOLBAR))
        btn_mount_all.set_always_show_image(True)
        btn_mount_all.set_tooltip_text('Mounts all filesystems')
        btn_mount_all.connect("clicked", self.handler_mount_all)
        self.header_bar.pack_end(btn_mount_all)

        return self.header_bar

    def _create_list_container(self):
        # This would contain the sftp systems list
        self.list_container = Gtk.ListBox()
        self.list_container.set_selection_mode(Gtk.SelectionMode.NONE)
        self.refresh_list()
        return self.list_container

    def _create_record_container(self):
        # This would contain the form entries when adding/editing systems
        self.record_container = create_hbox()
        return self.record_container

    def __init__(self):
        self.environment = EnvironmentModel()

        self.window = Gtk.Window()
        self.window.set_title('SftpMan')
        self.window.resize(550, 600)
        self.window.set_position(Gtk.WindowPosition.CENTER)
        self.window.connect('destroy', self.handler_destroy)

        self.icon_file = os.path.join(os.path.dirname(__file__), '..',
                                      'sftpman-gtk.png')
        if not os.path.exists(self.icon_file):
            self.icon_file = '/usr/share/pixmaps/sftpman-gtk.png'
            if not os.path.exists(self.icon_file):
                self.icon_file = None
        if self.icon_file is not None:
            self.window.set_icon_from_file(self.icon_file)

        self.window.set_titlebar(self._create_header_bar())

        self.list_container_wrapper = Gtk.ScrolledWindow()
        self.list_container_wrapper.add_with_viewport(
            self._create_list_container())

        vbox_main = create_vbox()
        vbox_main.pack_start(self.list_container_wrapper, True, True, 0)
        vbox_main.pack_start(self._create_record_container(), False, False, 0)

        self.vbox_main = vbox_main

        self.window.add(vbox_main)
        self.window.show_all()

        self.in_list_mode = True

        def list_periodic_refresher():
            while True:
                # Trying to update the GTK GUI from a thread causes
                # a segmentation fault - this is the proper way to do it
                if self.in_list_mode:
                    GLib.idle_add(self.refresh_list)
                sleep(15)

        refresher_thread = Thread(target=list_periodic_refresher)
        refresher_thread.daemon = True
        refresher_thread.start()

    def _perform_preflight_check(self):
        checks_pass, failures = self.environment.perform_preflight_check()
        if not checks_pass:
            for msg in failures:
                show_warning_message(self.window, msg)
            show_warning_message(
                self.window,
                'Mounting will fail until all problems are fixed.')

    def main(self):
        self._perform_preflight_check()
        Gtk.main()