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 __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 __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()
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()
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()
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()
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()