def update_files(self,a=None): treeview_files_model = self.xml.get_widget('treeview_files').get_model() treeview_files_model.clear() treeview_files_model.append( (util.pango_escape('loading files... (please wait)'),) ) model, entry = a.get_selection().get_selected() if not entry: treeview_files_model.clear() return self.xml.get_widget('toolbutton_export').set_sensitive( True ) self.xml.get_widget('toolbutton_explore').set_sensitive( True ) rev = entry and model.get_value(entry, 1) icon = self.main_window.render_icon(gtk.STOCK_FIND, gtk.ICON_SIZE_MENU) running_tasks_model = self.xml.get_widget('running_tasks').get_model() i = running_tasks_model.append( ( icon, util.pango_escape('loading files for rev: '+self.path), datetime.datetime.now(), '' ) ) gui = self class T(threading.Thread): def run(self): if rev not in gui.rev_files_map: gui.rev_files_map[rev] = backup.get_files_for_revision(gui.uuid, gui.host, gui.path, rev) gtk.gdk.threads_enter() if rev==gui.get_selected_revision(): treeview_files_model.clear() for fn in gui.rev_files_map[rev]: treeview_files_model.append( (util.pango_escape(fn),) ) running_tasks_model.remove(i) gtk.gdk.threads_leave() T().start()
def refresh_device_list(self): treeview_backups_model = self.xml.get_widget( 'treeview_backups').get_model() treeview_backups_model.clear() writable_devices = backup.get_writable_devices() for uuid in writable_devices: path = backup.get_mount_point_for_uuid(uuid) if backup.get_device_type(uuid) == 'gvfs': icon = self.main_window.render_icon(gtk.STOCK_NETWORK, gtk.ICON_SIZE_DIALOG) elif backup.get_device_type(uuid) == 'local': icon = self.main_window.render_icon(gtk.STOCK_HARDDISK, gtk.ICON_SIZE_DIALOG) else: icon = self.main_window.render_icon(gtk.STOCK_DIALOG_QUESTION, gtk.ICON_SIZE_DIALOG) free_space = util.humanize_bytes(backup.get_free_space(uuid)) s = "<b>Drive:</b> %s\n<b>Mount Point:</b> %s\n<b>Free Space:</b> %s" % ( util.pango_escape(uuid), util.pango_escape(path), util.pango_escape(free_space)) treeview_backups_model.append( (icon, s, backup.is_dev_present(uuid), uuid)) if not writable_devices: icon = self.main_window.render_icon(gtk.STOCK_INFO, gtk.ICON_SIZE_DIALOG) s = 'In order to create a backup, Flyback needs a hard drive\nother than the one your computer boots from.\n(preferably external and removable) Please plug one\ninto a free USB or eSATA port...' treeview_backups_model.append((icon, s, False, None)) self.xml.get_widget('button_new').set_sensitive(False) else: self.xml.get_widget('button_new').set_sensitive(True)
def update_revisions(self): revisions = backup.get_revisions(self.uuid, self.host, self.path) treeview_revisions_widget = self.xml.get_widget('treeview_revisions') treeview_revisions_model = treeview_revisions_widget.get_model() treeview_revisions_model.clear() for rev in revisions: s = 'Captured on: %s\nBy: <i>%s</i>' % ( util.pango_escape(rev['date']), util.pango_escape(rev['author']) ) if rev['verified']: s += '\nVerified on: %s' % util.pango_escape(rev['verified']) #.strftime('%') treeview_revisions_model.append((s,rev['commit']))
def refresh_device_list(self): treeview_backups_model = self.xml.get_widget("treeview_backups").get_model() treeview_backups_model.clear() known_backups = backup.get_known_backups() for t in known_backups: uuid = t["uuid"] paths = backup.get_dev_paths_for_uuid(t["uuid"]) drive_name = "UUID: " + t["uuid"] for path in paths: if "disk/by-id" in path: drive_name = path[path.index("disk/by-id") + 11 :] free_space = util.humanize_bytes(backup.get_free_space(t["uuid"])) drive_name = backup.get_mount_point_for_uuid(t["uuid"]) + " (%s free)" % free_space s = "<b>Drive:</b> %s\n<b>Source:</b> <i>%s</i>:%s\n" % ( util.pango_escape(drive_name), util.pango_escape(t["host"]), util.pango_escape(t["path"]), ) if backup.is_dev_present(t["uuid"]) and backup.get_hostname() == t["host"]: s += "<b>Status:</b> Drive is ready for backups" else: if backup.is_dev_present(t["uuid"]) and backup.get_hostname() != t["host"]: s += "<b>Status:</b> Backup available for export only (was created on another computer)" else: s += "<b>Status:</b> Drive is unavailable (please attach)" if backup.get_device_type(uuid) == "gvfs": icon = self.main_window.render_icon(gtk.STOCK_NETWORK, gtk.ICON_SIZE_DIALOG) elif backup.get_device_type(uuid) == "local": icon = self.main_window.render_icon(gtk.STOCK_HARDDISK, gtk.ICON_SIZE_DIALOG) else: icon = self.main_window.render_icon(gtk.STOCK_DIALOG_QUESTION, gtk.ICON_SIZE_DIALOG) treeview_backups_model.append((icon, s, backup.is_dev_present(t["uuid"]), t["uuid"], t["host"], t["path"])) if known_backups: treeview_backups_model.append( ( self.main_window.render_icon(gtk.STOCK_ADD, gtk.ICON_SIZE_DIALOG), "Double-click here to create a new backup...", True, None, None, None, ) ) else: treeview_backups_model.append( ( self.main_window.render_icon(gtk.STOCK_ADD, gtk.ICON_SIZE_DIALOG), "No existing backups found.\nDouble-click here to create a new backup...", True, None, None, None, ) )
def update_revisions(self): revisions = backup.get_revisions(self.uuid, self.host, self.path) treeview_revisions_widget = self.xml.get_widget('treeview_revisions') treeview_revisions_model = treeview_revisions_widget.get_model() treeview_revisions_model.clear() for rev in revisions: s = 'Captured on: %s\nBy: <i>%s</i>' % (util.pango_escape( rev['date']), util.pango_escape(rev['author'])) if rev['verified']: s += '\nVerified on: %s' % util.pango_escape( rev['verified']) #.strftime('%') treeview_revisions_model.append((s, rev['commit']))
def start_explore(self): target_dir = tmp = tempfile.mkdtemp(suffix='_flyback') rev = self.get_selected_revision() icon = self.main_window.render_icon(gtk.STOCK_DIRECTORY, gtk.ICON_SIZE_MENU) running_tasks_model = self.xml.get_widget('running_tasks').get_model() i = running_tasks_model.append( (icon, util.pango_escape('preparing folder for exploration: ' + target_dir), datetime.datetime.now(), '')) gui = self class T(threading.Thread): def run(self): fn = backup.export_revision(gui.uuid, gui.host, gui.path, rev, target_dir) os.chdir(target_dir) os.system('tar -zxvf "%s"' % fn) os.remove(fn) os.chdir(util.RUN_FROM_DIR) util.open_file(target_dir) gtk.gdk.threads_enter() running_tasks_model.remove(i) gtk.gdk.threads_leave() T().start()
def refresh_device_list(self): treeview_backups_model = self.xml.get_widget('treeview_backups').get_model() treeview_backups_model.clear() known_backups = backup.get_known_backups() for t in known_backups: uuid = t['uuid'] paths = backup.get_dev_paths_for_uuid(t['uuid']) drive_name = 'UUID: '+ t['uuid'] for path in paths: if 'disk/by-id' in path: drive_name = path[path.index('disk/by-id')+11:] free_space = util.humanize_bytes(backup.get_free_space(t['uuid'])) drive_name = backup.get_mount_point_for_uuid(t['uuid']) + ' (%s free)' % free_space s = "<b>Drive:</b> %s\n<b>Source:</b> <i>%s</i>:%s\n" % (util.pango_escape(drive_name), util.pango_escape(t['host']), util.pango_escape(t['path']), ) if backup.is_dev_present(t['uuid']) and backup.get_hostname()==t['host']: s += "<b>Status:</b> Drive is ready for backups" else: if backup.is_dev_present(t['uuid']) and backup.get_hostname()!=t['host']: s += "<b>Status:</b> Backup available for export only (was created on another computer)" else: s += "<b>Status:</b> Drive is unavailable (please attach)" if backup.get_device_type(uuid)=='gvfs': icon = self.main_window.render_icon(gtk.STOCK_NETWORK, gtk.ICON_SIZE_DIALOG) elif backup.get_device_type(uuid)=='local': icon = self.main_window.render_icon(gtk.STOCK_HARDDISK, gtk.ICON_SIZE_DIALOG) else: icon = self.main_window.render_icon(gtk.STOCK_DIALOG_QUESTION, gtk.ICON_SIZE_DIALOG) treeview_backups_model.append( (icon, s, backup.is_dev_present(t['uuid']), t['uuid'], t['host'], t['path']) ) if known_backups: treeview_backups_model.append( (self.main_window.render_icon(gtk.STOCK_ADD, gtk.ICON_SIZE_DIALOG), 'Double-click here to create a new backup...', True, None, None, None) ) else: treeview_backups_model.append( (self.main_window.render_icon(gtk.STOCK_ADD, gtk.ICON_SIZE_DIALOG), 'No existing backups found.\nDouble-click here to create a new backup...', True, None, None, None) )
def delete_backup(self,a=None,b=None,c=None): treeview_backups_widget = self.xml.get_widget('treeview_backups') model, entry = treeview_backups_widget.get_selection().get_selected() if entry and model.get_value(entry, 2): uuid = model.get_value(entry, 3) host = model.get_value(entry, 4) path = model.get_value(entry, 5) if uuid and host and path: title = 'Delete Backup?' s = "Permanently delete the following backup repository?\n" s += "<b>Drive:</b> %s:%s\n<b>Source:</b> <i>%s</i>:%s\n" % (util.pango_escape(uuid), util.pango_escape(backup.get_mount_point_for_uuid(uuid)), util.pango_escape(host), util.pango_escape(path), ) s += '\n<b>This action cannot be undone!</b>' md = gtk.MessageDialog(None, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO, util.pango_escape(title)) md.format_secondary_markup(s) if gtk.RESPONSE_YES==md.run(): print 'deleting',uuid,host,path gui = self class T(threading.Thread): def run(self): backup.delete_backup(uuid, host, path) gtk.gdk.threads_enter() gui.refresh_device_list() gtk.gdk.threads_leave() T().start() md.destroy()
def run(self): if rev not in gui.rev_files_map: gui.rev_files_map[rev] = backup.get_files_for_revision(gui.uuid, gui.host, gui.path, rev) gtk.gdk.threads_enter() if rev==gui.get_selected_revision(): treeview_files_model.clear() for fn in gui.rev_files_map[rev]: treeview_files_model.append( (util.pango_escape(fn),) ) running_tasks_model.remove(i) gtk.gdk.threads_leave()
def run(self): if rev not in gui.rev_files_map: gui.rev_files_map[rev] = backup.get_files_for_revision( gui.uuid, gui.host, gui.path, rev) gtk.gdk.threads_enter() if rev == gui.get_selected_revision(): treeview_files_model.clear() for fn in gui.rev_files_map[rev]: treeview_files_model.append((util.pango_escape(fn), )) running_tasks_model.remove(i) gtk.gdk.threads_leave()
def delete_backup(self, a=None, b=None, c=None): treeview_backups_widget = self.xml.get_widget("treeview_backups") model, entry = treeview_backups_widget.get_selection().get_selected() if entry and model.get_value(entry, 2): uuid = model.get_value(entry, 3) host = model.get_value(entry, 4) path = model.get_value(entry, 5) if uuid and host and path: title = "Delete Backup?" s = "Permanently delete the following backup repository?\n" s += "<b>Drive:</b> %s:%s\n<b>Source:</b> <i>%s</i>:%s\n" % ( util.pango_escape(uuid), util.pango_escape(backup.get_mount_point_for_uuid(uuid)), util.pango_escape(host), util.pango_escape(path), ) s += "\n<b>This action cannot be undone!</b>" md = gtk.MessageDialog( None, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO, util.pango_escape(title), ) md.format_secondary_markup(s) if gtk.RESPONSE_YES == md.run(): print "deleting", uuid, host, path gui = self class T(threading.Thread): def run(self): backup.delete_backup(uuid, host, path) gtk.gdk.threads_enter() gui.refresh_device_list() gtk.gdk.threads_leave() T().start() md.destroy()
def start_backup(self): icon = self.main_window.render_icon(gtk.STOCK_SAVE, gtk.ICON_SIZE_MENU) running_tasks_model = self.xml.get_widget('running_tasks').get_model() i = running_tasks_model.append( ( icon, util.pango_escape('backing up: '+self.path), datetime.datetime.now(), '' ) ) gui = self class T(threading.Thread): def run(self): backup.backup(gui.uuid, gui.host, gui.path) gtk.gdk.threads_enter() gui.update_revisions() running_tasks_model.remove(i) gtk.gdk.threads_leave() T().start()
def update_files(self, a=None): treeview_files_model = self.xml.get_widget( 'treeview_files').get_model() treeview_files_model.clear() treeview_files_model.append( (util.pango_escape('loading files... (please wait)'), )) model, entry = a.get_selection().get_selected() if not entry: treeview_files_model.clear() return self.xml.get_widget('toolbutton_export').set_sensitive(True) self.xml.get_widget('toolbutton_explore').set_sensitive(True) rev = entry and model.get_value(entry, 1) icon = self.main_window.render_icon(gtk.STOCK_FIND, gtk.ICON_SIZE_MENU) running_tasks_model = self.xml.get_widget('running_tasks').get_model() i = running_tasks_model.append( (icon, util.pango_escape('loading files for rev: ' + self.path), datetime.datetime.now(), '')) gui = self class T(threading.Thread): def run(self): if rev not in gui.rev_files_map: gui.rev_files_map[rev] = backup.get_files_for_revision( gui.uuid, gui.host, gui.path, rev) gtk.gdk.threads_enter() if rev == gui.get_selected_revision(): treeview_files_model.clear() for fn in gui.rev_files_map[rev]: treeview_files_model.append((util.pango_escape(fn), )) running_tasks_model.remove(i) gtk.gdk.threads_leave() T().start()
def start_verify(self): rev = self.get_selected_revision() icon = self.main_window.render_icon(gtk.STOCK_DIALOG_QUESTION, gtk.ICON_SIZE_MENU) running_tasks_model = self.xml.get_widget('running_tasks').get_model() i = running_tasks_model.append( ( icon, util.pango_escape('verifying revision: '+rev), datetime.datetime.now(), '' ) ) gui = self class T(threading.Thread): def run(self): fn = backup.verify_revision( gui.uuid, gui.host, gui.path, rev ) gtk.gdk.threads_enter() gui.update_revisions() running_tasks_model.remove(i) gtk.gdk.threads_leave() T().start()
def save_as(self): os.chdir(config.CURRENT_DIR) dialog = gtk.FileChooserDialog(title='Save TEX file...', parent=None, action=gtk.FILE_CHOOSER_ACTION_SAVE, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE,gtk.RESPONSE_OK), backend=None) dialog.set_default_response(gtk.RESPONSE_OK) dialog.show_all() response = dialog.run() if response == gtk.RESPONSE_OK: CURRENT_DIR = dialog.get_current_folder() self.fq_filename = dialog.get_filename() self.notebook_label.set_text( pango_escape(os.path.basename(self.fq_filename)) ) self.save() dialog.destroy() return True else: dialog.destroy() return False
def start_status(self): icon = self.main_window.render_icon(gtk.STOCK_FIND, gtk.ICON_SIZE_MENU) running_tasks_model = self.xml.get_widget('running_tasks').get_model() i = running_tasks_model.append( ( icon, util.pango_escape('retrieving folder status since last backup...'), datetime.datetime.now(), '' ) ) import backup_status_gui gui2 = backup_status_gui.GUI(self.register_gui, self.unregister_gui, self.uuid, self.host, self.path) self.register_gui( gui2 ) gui = self class T(threading.Thread): def run(self): added, modified, deleted = backup.get_status( gui.uuid, gui.host, gui.path ) gtk.gdk.threads_enter() gui2.set_files(added, modified, deleted) running_tasks_model.remove(i) gtk.gdk.threads_leave() T().start()
def start_backup(self): icon = self.main_window.render_icon(gtk.STOCK_SAVE, gtk.ICON_SIZE_MENU) running_tasks_model = self.xml.get_widget('running_tasks').get_model() i = running_tasks_model.append( (icon, util.pango_escape('backing up: ' + self.path), datetime.datetime.now(), '')) gui = self class T(threading.Thread): def run(self): backup.backup(gui.uuid, gui.host, gui.path) gtk.gdk.threads_enter() gui.update_revisions() running_tasks_model.remove(i) gtk.gdk.threads_leave() T().start()
def start_verify(self): rev = self.get_selected_revision() icon = self.main_window.render_icon(gtk.STOCK_DIALOG_QUESTION, gtk.ICON_SIZE_MENU) running_tasks_model = self.xml.get_widget('running_tasks').get_model() i = running_tasks_model.append( (icon, util.pango_escape('verifying revision: ' + rev), datetime.datetime.now(), '')) gui = self class T(threading.Thread): def run(self): fn = backup.verify_revision(gui.uuid, gui.host, gui.path, rev) gtk.gdk.threads_enter() gui.update_revisions() running_tasks_model.remove(i) gtk.gdk.threads_leave() T().start()
def init_label(self): hbox = gtk.HBox() if self.fq_filename: self.notebook_label = gtk.Label( pango_escape(os.path.basename(self.fq_filename)) ) else: self.notebook_label = gtk.Label('untitled') hbox.add( self.notebook_label ) close_button = gtk.Button() close_button.connect('clicked', self.close) close_button.set_focus_on_click(False) close_button_image = gtk.Image() close_button_image.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU) close_button.set_image(close_button_image) close_button.set_relief(gtk.RELIEF_NONE) style = close_button.get_style().copy() settings = gtk.Widget.get_settings (close_button); (w,h) = gtk.icon_size_lookup_for_settings(settings,gtk.ICON_SIZE_MENU); gtk.Widget.set_size_request (close_button, w + 4, h + 4); hbox.add( close_button ) hbox.show_all() self.notebook.set_tab_label( self.scrolled_window, hbox )
def start_explore(self): target_dir = tmp = tempfile.mkdtemp(suffix='_flyback') rev = self.get_selected_revision() icon = self.main_window.render_icon(gtk.STOCK_DIRECTORY, gtk.ICON_SIZE_MENU) running_tasks_model = self.xml.get_widget('running_tasks').get_model() i = running_tasks_model.append( ( icon, util.pango_escape('preparing folder for exploration: '+target_dir), datetime.datetime.now(), '' ) ) gui = self class T(threading.Thread): def run(self): fn = backup.export_revision( gui.uuid, gui.host, gui.path, rev, target_dir ) os.chdir(target_dir) os.system('tar -zxvf "%s"' % fn) os.remove(fn) os.chdir(util.RUN_FROM_DIR) util.open_file(target_dir) gtk.gdk.threads_enter() running_tasks_model.remove(i) gtk.gdk.threads_leave() T().start()
def refresh_device_list(self): treeview_backups_model = self.xml.get_widget('treeview_backups').get_model() treeview_backups_model.clear() writable_devices = backup.get_writable_devices() for uuid in writable_devices: path = backup.get_mount_point_for_uuid(uuid) if backup.get_device_type(uuid)=='gvfs': icon = self.main_window.render_icon(gtk.STOCK_NETWORK, gtk.ICON_SIZE_DIALOG) elif backup.get_device_type(uuid)=='local': icon = self.main_window.render_icon(gtk.STOCK_HARDDISK, gtk.ICON_SIZE_DIALOG) else: icon = self.main_window.render_icon(gtk.STOCK_DIALOG_QUESTION, gtk.ICON_SIZE_DIALOG) free_space = util.humanize_bytes(backup.get_free_space(uuid)) s = "<b>Drive:</b> %s\n<b>Mount Point:</b> %s\n<b>Free Space:</b> %s" % (util.pango_escape(uuid), util.pango_escape(path), util.pango_escape(free_space)) treeview_backups_model.append( (icon, s, backup.is_dev_present(uuid), uuid) ) if not writable_devices: icon = self.main_window.render_icon(gtk.STOCK_INFO, gtk.ICON_SIZE_DIALOG) s = 'In order to create a backup, Flyback needs a hard drive\nother than the one your computer boots from.\n(preferably external and removable) Please plug one\ninto a free USB or eSATA port...' treeview_backups_model.append( (icon, s, False, None) ) self.xml.get_widget('button_new').set_sensitive(False) else: self.xml.get_widget('button_new').set_sensitive(True)
def start_status(self): icon = self.main_window.render_icon(gtk.STOCK_FIND, gtk.ICON_SIZE_MENU) running_tasks_model = self.xml.get_widget('running_tasks').get_model() i = running_tasks_model.append(( icon, util.pango_escape('retrieving folder status since last backup...'), datetime.datetime.now(), '')) import backup_status_gui gui2 = backup_status_gui.GUI(self.register_gui, self.unregister_gui, self.uuid, self.host, self.path) self.register_gui(gui2) gui = self class T(threading.Thread): def run(self): added, modified, deleted = backup.get_status( gui.uuid, gui.host, gui.path) gtk.gdk.threads_enter() gui2.set_files(added, modified, deleted) running_tasks_model.remove(i) gtk.gdk.threads_leave() T().start()
def start_export(self): dialog = gtk.FileChooserDialog(title='Select folder to save archive to...', parent=None, action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK), backend=None) response = dialog.run() if response == gtk.RESPONSE_OK: target_dir = dialog.get_filename() rev = self.get_selected_revision() icon = self.main_window.render_icon(gtk.STOCK_FLOPPY, gtk.ICON_SIZE_MENU) running_tasks_model = self.xml.get_widget('running_tasks').get_model() i = running_tasks_model.append( ( icon, util.pango_escape('exporting selected revision to: '+target_dir), datetime.datetime.now(), '' ) ) gui = self class T(threading.Thread): def run(self): fn = backup.export_revision( gui.uuid, gui.host, gui.path, rev, target_dir ) util.open_file(fn) gtk.gdk.threads_enter() running_tasks_model.remove(i) gtk.gdk.threads_leave() T().start() elif response == gtk.RESPONSE_CANCEL: pass dialog.destroy()
def start_export(self): dialog = gtk.FileChooserDialog( title='Select folder to save archive to...', parent=None, action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK), backend=None) response = dialog.run() if response == gtk.RESPONSE_OK: target_dir = dialog.get_filename() rev = self.get_selected_revision() icon = self.main_window.render_icon(gtk.STOCK_FLOPPY, gtk.ICON_SIZE_MENU) running_tasks_model = self.xml.get_widget( 'running_tasks').get_model() i = running_tasks_model.append( (icon, util.pango_escape('exporting selected revision to: ' + target_dir), datetime.datetime.now(), '')) gui = self class T(threading.Thread): def run(self): fn = backup.export_revision(gui.uuid, gui.host, gui.path, rev, target_dir) util.open_file(fn) gtk.gdk.threads_enter() running_tasks_model.remove(i) gtk.gdk.threads_leave() T().start() elif response == gtk.RESPONSE_CANCEL: pass dialog.destroy()
def __init__(self, register_gui, unregister_gui, uuid, host, path): self.register_gui = register_gui self.unregister_gui = unregister_gui self.uuid = uuid self.host = host self.path = path self.rev_files_map = {} self.xml = gtk.glade.XML( os.path.join(util.RUN_FROM_DIR, 'glade', 'manage_backup.glade')) self.main_window = self.xml.get_widget('window') self.main_window.connect("delete-event", self.close) icon = self.main_window.render_icon(gtk.STOCK_HARDDISK, gtk.ICON_SIZE_BUTTON) self.main_window.set_icon(icon) self.xml.get_widget('entry_drive_name').set_text( backup.get_drive_name(self.uuid)) self.xml.get_widget('entry_path').set_text(self.host + ':' + self.path) self.main_window.set_title( '%s v%s - Manage Backup' % (settings.PROGRAM_NAME, settings.PROGRAM_VERSION)) # toolbar self.xml.get_widget('toolbutton_backup').set_sensitive( backup.test_backup_assertions(self.uuid, self.host, self.path)) self.xml.get_widget('toolbutton_backup').connect( 'clicked', lambda x: self.start_backup()) self.xml.get_widget('toolbutton_status').set_sensitive( backup.test_backup_assertions(self.uuid, self.host, self.path)) self.xml.get_widget('toolbutton_status').connect( 'clicked', lambda x: self.start_status()) self.xml.get_widget('toolbutton_export').connect( 'clicked', lambda x: self.start_export()) self.xml.get_widget('toolbutton_explore').connect( 'clicked', lambda x: self.start_explore()) self.xml.get_widget('toolbutton_verify').connect( 'clicked', lambda x: self.start_verify()) self.xml.get_widget('toolbutton_preferences').connect( 'clicked', lambda x: self.open_preferences()) # revision list treeview_revisions_model = gtk.ListStore(str, str) treeview_revisions_widget = self.xml.get_widget('treeview_revisions') renderer = gtk.CellRendererText() treeview_revisions_widget.append_column( gtk.TreeViewColumn('History', renderer, markup=0)) treeview_revisions_widget.set_model(treeview_revisions_model) treeview_revisions_widget.connect('cursor-changed', self.update_files) treeview_revisions_widget.set_property('rules-hint', True) self.update_revisions() # file list treeview_files_widget = self.xml.get_widget('treeview_files') treeview_files_model = gtk.ListStore(str) renderer = gtk.CellRendererText() renderer.set_property('font', 'monospace') treeview_files_widget.append_column( gtk.TreeViewColumn('Files', renderer, markup=0)) treeview_files_widget.set_model(treeview_files_model) treeview_files_widget.set_property('rules-hint', True) treeview_files_model.append((util.pango_escape( 'please select a revision to view... (on the left)'), )) # task list running_tasks_widget = self.xml.get_widget('running_tasks') running_tasks_model = gtk.ListStore(gtk.gdk.Pixbuf, str, gobject.TYPE_PYOBJECT, str) renderer = gtk.CellRendererPixbuf() renderer.set_property('xpad', 4) renderer.set_property('ypad', 4) running_tasks_widget.append_column( gtk.TreeViewColumn('', renderer, pixbuf=0)) renderer = gtk.CellRendererText() running_tasks_widget.append_column( gtk.TreeViewColumn('', renderer, markup=1)) renderer = gtk.CellRendererText() running_tasks_widget.append_column( gtk.TreeViewColumn('', renderer, markup=3)) running_tasks_widget.set_model(running_tasks_model) running_tasks_widget.set_headers_visible(False) running_tasks_widget.set_property('rules-hint', True) class T(threading.Thread): def run(self): while True: tasks_running = False gtk.gdk.threads_enter() for x in running_tasks_model: x[3] = util.humanize_time(datetime.datetime.now() - x[2]) gtk.gdk.threads_leave() if tasks_running: time.sleep(1) else: time.sleep(10) running_tasks_thread = T() running_tasks_thread.daemon = True running_tasks_thread.start() self.main_window.show() # if no revisions exist, prompt user to run backup if not backup.get_revisions(self.uuid, self.host, self.path): s = 'Welcome to Flyback!' md = gtk.MessageDialog(None, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_INFO, gtk.BUTTONS_CLOSE, s) md.format_secondary_markup( 'This is a brand new (and currently empty) backup repository. To fill it with data, please click the "backup" button in the upper-left corner.' ) md.run() md.destroy()
def __init__(self, register_gui, unregister_gui, uuid, host, path): self.register_gui = register_gui self.unregister_gui = unregister_gui self.uuid = uuid self.host = host self.path = path self.rev_files_map = {} self.xml = gtk.glade.XML( os.path.join( util.RUN_FROM_DIR, 'glade', 'manage_backup.glade' ) ) self.main_window = self.xml.get_widget('window') self.main_window.connect("delete-event", self.close ) icon = self.main_window.render_icon(gtk.STOCK_HARDDISK, gtk.ICON_SIZE_BUTTON) self.main_window.set_icon(icon) self.xml.get_widget('entry_drive_name').set_text( backup.get_drive_name(self.uuid) ) self.xml.get_widget('entry_path').set_text( self.host +':'+ self.path ) self.main_window.set_title('%s v%s - Manage Backup' % (settings.PROGRAM_NAME, settings.PROGRAM_VERSION)) # toolbar self.xml.get_widget('toolbutton_backup').set_sensitive( backup.test_backup_assertions(self.uuid, self.host, self.path) ) self.xml.get_widget('toolbutton_backup').connect('clicked', lambda x: self.start_backup() ) self.xml.get_widget('toolbutton_status').set_sensitive( backup.test_backup_assertions(self.uuid, self.host, self.path) ) self.xml.get_widget('toolbutton_status').connect('clicked', lambda x: self.start_status() ) self.xml.get_widget('toolbutton_export').connect('clicked', lambda x: self.start_export() ) self.xml.get_widget('toolbutton_explore').connect('clicked', lambda x: self.start_explore() ) self.xml.get_widget('toolbutton_verify').connect('clicked', lambda x: self.start_verify() ) self.xml.get_widget('toolbutton_preferences').connect('clicked', lambda x: self.open_preferences() ) # revision list treeview_revisions_model = gtk.ListStore( str, str ) treeview_revisions_widget = self.xml.get_widget('treeview_revisions') renderer = gtk.CellRendererText() treeview_revisions_widget.append_column( gtk.TreeViewColumn('History', renderer, markup=0) ) treeview_revisions_widget.set_model(treeview_revisions_model) treeview_revisions_widget.connect( 'cursor-changed', self.update_files ) treeview_revisions_widget.set_property('rules-hint', True) self.update_revisions() # file list treeview_files_widget = self.xml.get_widget('treeview_files') treeview_files_model = gtk.ListStore( str ) renderer = gtk.CellRendererText() renderer.set_property('font','monospace') treeview_files_widget.append_column( gtk.TreeViewColumn('Files', renderer, markup=0) ) treeview_files_widget.set_model(treeview_files_model) treeview_files_widget.set_property('rules-hint', True) treeview_files_model.append( (util.pango_escape('please select a revision to view... (on the left)'),) ) # task list running_tasks_widget = self.xml.get_widget('running_tasks') running_tasks_model = gtk.ListStore( gtk.gdk.Pixbuf, str, gobject.TYPE_PYOBJECT, str ) renderer = gtk.CellRendererPixbuf() renderer.set_property('xpad', 4) renderer.set_property('ypad', 4) running_tasks_widget.append_column( gtk.TreeViewColumn('', renderer, pixbuf=0) ) renderer = gtk.CellRendererText() running_tasks_widget.append_column( gtk.TreeViewColumn('', renderer, markup=1) ) renderer = gtk.CellRendererText() running_tasks_widget.append_column( gtk.TreeViewColumn('', renderer, markup=3) ) running_tasks_widget.set_model(running_tasks_model) running_tasks_widget.set_headers_visible(False) running_tasks_widget.set_property('rules-hint', True) class T(threading.Thread): def run(self): while True: tasks_running = False gtk.gdk.threads_enter() for x in running_tasks_model: x[3] = util.humanize_time( datetime.datetime.now() - x[2] ) gtk.gdk.threads_leave() if tasks_running: time.sleep(1) else: time.sleep(10) running_tasks_thread = T() running_tasks_thread.daemon = True running_tasks_thread.start() self.main_window.show() # if no revisions exist, prompt user to run backup if not backup.get_revisions(self.uuid, self.host, self.path): s = 'Welcome to Flyback!' md = gtk.MessageDialog(None, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_INFO, gtk.BUTTONS_CLOSE, s) md.format_secondary_markup('This is a brand new (and currently empty) backup repository. To fill it with data, please click the "backup" button in the upper-left corner.') md.run() md.destroy()
def run(self): os.chdir(RUN_FROM_DIR) output = commands.getoutput('svn update') gtk.gdk.threads_enter() dialog = gtk.MessageDialog( type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_OK ) dialog.connect('response', lambda x,y: dialog.destroy()) dialog.set_markup('<b>Output from SVN:</b>\n\n%s\n\n(restart for changes to take effect)' % ( pango_escape(output) )) dialog.show_all() response = dialog.run() gtk.gdk.threads_leave()
def close(self, x=None): if self.changed: dialog = gtk.MessageDialog( type=gtk.MESSAGE_WARNING ) if self.fq_filename: dialog.set_markup('<b>Save changes to document "%s" before closing?</b>\n\nIf you don\'t save, changes will be lost.' % ( pango_escape(os.path.basename(self.fq_filename)) )) dialog.add_button('_Save', 1) else: dialog.set_markup('<b>Save untitled document before closing?</b>\n\nIf you don\'t save, changes will be lost.') dialog.add_button('_Save as', 1) dialog.add_button('Close _without saving', 2) dialog.add_button('_Cancel', 3) dialog.show_all() response = dialog.run() dialog.destroy() if response==1: if self.fq_filename: self.save() else: if not self.save_as(): return True elif response==2: pass elif response==3: return True page_num = self.main_gui.tex_docs.index(self) self.notebook.remove_page(page_num) self.main_gui.tex_docs.remove(self)