class StoragePanel(EditPanel, gui.StoragePanel): ''' classdocs ''' def __init__(self, parent): ''' Constructor ''' log.info("***StorePanel.init") gui.StoragePanel.__init__(self, parent) self.db = DB() self.config = Config.get_config() self.state = ViewState self.load_static_data() self.update_store_list() self.clear() if self.lstItems.GetCount() > 0: self.lstItems.SetSelection(0) self.onItemSelected(None) self.onAutoManage(None) self.image = wx.Bitmap(os.path.join(const.PixmapDir, "storage.png")) self.title = _("Storage") self.ftp_hidden = True self.db_hidden = True log.trace("Done StorePanel.init") def update_data(self): sel = self.lstItems.GetStringSelection() self.update_store_list() self.lstItems.SetStringSelection(sel) def update_store_list(self): self.lstItems.Clear() self.lstItems.AppendItems(self.config.storage.keys()) def load_static_data(self): self.cboLimitUnits.Clear() self.cboLimitUnits.AppendItems(const.DiskUnits) self.cboLimitUnits.SetSelection(0) ######################################################################3 # # EVENTS # ######################################################################3 def onTest(self, event): # Get the name to be tested name = self.lstItems.GetStringSelection() if len(name) == 0: return # Load it try: with ProgressDialog(self, _("Testing"), _("Testing connectivity and access to the store.\nPlease wait...")): s = self.config.storage[name].copy() s.test() dlg.Info(self, _("Store {store} OK").format(store=name)) except Exception as e: # Missing backup! dlg.Warn(self, str(e)) finally: app.clear_message() def onAutoManage(self, event): mng = self.chkAutoManage.GetValue() self.txtLimitSize.Enabled = mng self.cboLimitUnits.Enabled = mng def onFolderChoose(self, event): dlg = wx.DirDialog(self, _("Choose A Store Folder"), defaultPath=self.txtFolderPath.GetValue()) if dlg.ShowModal() == wx.ID_OK: self.txtFolderPath.SetValue(dlg.GetPath()) dlg.Destroy() def onShareChoose(self, event): dlg = wx.DirDialog(self, _("Choose A Store Folder"), defaultPath=self.txtShareRoot.GetValue()) if dlg.ShowModal() == wx.ID_OK: self.txtShareRoot.SetValue(dlg.GetPath()) dlg.Destroy() def onLimitChar(self, event): log.trace("StoragePanel.onLimitChar", event, event.GetUniChar()) if event.GetKeyCode() in [ wx.WXK_TAB, wx.WXK_BACK, wx.WXK_RETURN, wx.WXK_DELETE, wx.WXK_CLEAR, wx.WXK_HOME, wx.WXK_END, wx.WXK_LEFT, wx.WXK_RIGHT, wx.WXK_UP, wx.WXK_DOWN, wx.WXK_INSERT, wx.WXK_NUMPAD_HOME, wx.WXK_NUMPAD_END, wx.WXK_NUMPAD_LEFT, wx.WXK_NUMPAD_RIGHT, wx.WXK_NUMPAD_UP, wx.WXK_NUMPAD_DOWN, wx.WXK_NUMPAD_INSERT, wx.WXK_NUMPAD_DELETE]: # OK event.Skip() return ch = unichr(event.GetUniChar()) dp = unicode(locale.localeconv()['decimal_point']) has_dp = self.txtLimitSize.GetValue().find(dp) >= 0 if ch.isdigit() or (ch == dp and not has_dp): if event.HasModifiers() or event.MetaDown() or event.ShiftDown(): pass else: # OK event.Skip() else: # Eat the event pass def onDropBoxClick(self, event): url = self.url_dropbox_create.GetURL() import webbrowser webbrowser.open(url, new=1, autoraise=True) app.show_message("Opening browser to DropBox") def onFTPHidePassword(self, event): if self.ftp_hidden: self.txtFTPPass.SetWindowStyle(wx.NORMAL) self.ftp_hidden = False self.btnFTPHidePassword.SetLabel("Hide") else: self.txtFTPPass.SetWindowStyle(wx.TE_PASSWORD) self.ftp_hidden = True self.btnFTPHidePassword.SetLabel("Show") def onDBHidePassword(self, event): if self.db_hidden: self.txtDBPass.SetWindowStyle(wx.NORMAL) self.db_hidden = False self.btnDBHidePassword.SetLabel("Hide") else: self.txtDBPass.SetWindowStyle(wx.TE_PASSWORD) self.db_hidden = True self.btnDBHidePassword.SetLabel("Show") ###################################################################### # # Save and Load # ###################################################################### def update_state(self): if self.state == ViewState: self.lblName.Show(True) self.txtName.Show(False) if self.state == NewState: self.lblName.Show(False) self.txtName.Show(True) self.pnlName.Fit() def clear(self): d = FolderStore("<name>", "", False, "<folder>") self.show_store(d) def delete(self, name): use = self.db.store_usage(name) if use.size > 0: log.debug(name, utils.readable_form(use.size)) msg = _("Store '{store}' contains {size} of backups.\nAre you sure?").format( store=name, size=utils.readable_form(use.size)) mbox = OptionDialog(self, msg, _("Delete Store"), _("Also delete all backup data stored on the store.")) if mbox.ShowModal() == wx.ID_OK: with ProgressDialog(self, _("Deleting"), _("Deleting store %s.\nPlease wait. This can take a while..." % name)): self.delete_store(name, mbox.chkOption.GetValue()) self.clear() self.state = ViewState else: ret = dlg.OkCancel(self, _("Store '{store}' is not currently used. Delete?").format(store=name)) if ret == wx.ID_OK: with ProgressDialog(self, _("Deleting"), _("Deleting store %s.\nPlease wait. This can take a while..." % name)): self.delete_store(name, False) self.clear() self.state = ViewState app.broadcast_update() def show(self, name): # Load it try: store = self.config.storage[name].copy() self.state = ViewState self.show_store(store) except : # Missing backup! dlg.Warn(self, _("The store '{store}' seems to be corrupt.").format(store=name)) # self.update_store_list() # self.state = ViewState # self.clear() return def show_store(self, d): try: # General Information self.txtName.SetValue(d.name) self.lblName.SetLabel(d.name) # Storage Information. More specialised first. then more general if isinstance(d, ShareStore): self.nbStoreType.SetSelection(2) self.txtShareRoot.SetValue(d.root) self.txtShareMount.SetValue(d.mount) self.txtShareUMount.SetValue(d.umount) elif isinstance(d, FolderStore): self.nbStoreType.SetSelection(0) self.txtFolderPath.SetValue(d.root) elif isinstance(d, FTPStore): self.nbStoreType.SetSelection(1) self.txtFTPAddress.SetValue(d.ip) self.txtFTPRoot.SetValue(d.root) self.chkSFTP.SetValue(d.sftp) self.txtFTPLogin.SetValue(d.login) self.txtFTPPass.SetValue(d.password) elif isinstance(d, DropBoxStore): self.nbStoreType.SetSelection(3) self.txtDBRoot.SetValue(d.root) self.txtDBLogin.SetValue(d.login) self.txtDBPass.SetValue(d.password) self.txtDBKey.SetValue(d.app_key) self.txtDBSecretKey.SetValue(d.app_secret_key) elif isinstance(d, S3Store): self.nbStoreType.SetSelection(4) self.txtAmazonBucket.SetValue(d.bucket) self.txtAmazonKey.SetValue(d.key) self.txtAmazonSecretKey.SetValue(d.secret_key) else: raise Exception("Invalid store type") (dummy, num, units) = d.limit_details() self.txtLimitSize.SetValue(str(num)) self.cboLimitUnits.SetStringSelection(units) self.chkAutoManage.SetValue(d.auto_manage) self.onAutoManage(None) # Whats inside the store. use = self.db.store_usage(d.name) if not use or use.size == 0: self.lblContentDetails.SetLabel("Empty") else: self.lblContentDetails.SetLabel( _("Size {size}, Files {files}, Folders {folders}").format( size=utils.readable_form(use.size), files=utils.comma_int(use.nfiles), folders=utils.comma_int(use.nfolders))) self.update_state() except Exception as e: log.error("Error showing store:", str(e)) dlg.Error(self, _("Store {store} appears to be corrupt. Unable to show.").format(name=d.name)) def save(self): # BUILD THE Storage if len(self.txtName.GetValue()) == 0: raise Exception(_("Storage name cannot be blank")) try: # Create the new backup object name = self.txtName.GetValue() auto_manage = self.chkAutoManage.GetValue() # Convert to float and back to string. Cleans up the number limit = str(float(self.txtLimitSize.GetValue())) + self.cboLimitUnits.GetStringSelection() if self.nbStoreType.GetSelection() == 0: root = self.txtFolderPath.GetValue() d = FolderStore(name, limit, auto_manage, root) elif self.nbStoreType.GetSelection() == 1: ip = self.txtFTPAddress.GetValue() root = self.txtFTPRoot.GetValue() sftp = self.chkSFTP.GetValue() login = self.txtFTPLogin.GetValue() password = self.txtFTPPass.GetValue() d = FTPStore(name, limit, auto_manage, ip, root, login, password, sftp) elif self.nbStoreType.GetSelection() == 2: root = self.txtShareRoot.GetValue() mount = self.txtShareMount.GetValue() umount = self.txtShareUMount.GetValue() d = ShareStore(name, limit, auto_manage, root, mount, umount) elif self.nbStoreType.GetSelection() == 3: root = self.txtDBRoot.GetValue() login = self.txtDBLogin.GetValue() password = self.txtDBPass.GetValue() app_key = self.txtDBKey.GetValue() app_secret_key = self.txtDBSecretKey.GetValue() d = DropBoxStore(name, limit, auto_manage, root, login, password, app_key, app_secret_key) elif self.nbStoreType.GetSelection() == 4: bucket = self.txtAmazonBucket.GetValue() key = self.txtAmazonKey.GetValue() secret_key = self.txtAmazonSecretKey.GetValue() d = S3Store(name, limit, auto_manage, bucket, key, secret_key) else: log.error("Invalid Storage Type") raise Exception(_("Invalid Storage type")) except Exception as e: raise e if self.state == ViewState: # Delete the old name oldname = self.lstItems.GetStringSelection() try: del self.config.storage[oldname] except: pass self.config.storage[d.name] = d self.config.save() self.update_store_list() self.show_store(d) ######################################################################3 # # Misc Routines # ######################################################################3 def delete_store(self, name, delete_store_data): store = self.config.storage[name].copy() self.db.delete_store(name) if delete_store_data: store.delete_store_data() del self.config.storage[name] self.config.save() self.update_store_list()