def _on_menu_file_save(self, _evt): appconfig = self._appconfig dlg = wx.FileDialog(self.wnd, _("Please select target sync file."), defaultDir=appconfig.get('files', 'last_dir', ''), defaultFile=appconfig.get('files', 'last_file', 'GTD_SYNC.zip'), style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) if dlg.ShowModal() == wx.ID_OK: filename = dlg.GetPath() dlgp = DlgSyncProggress(self.wnd) dlgp.run() try: exporter.save_to_file(filename, dlgp.update) except Exception as err: # pylint: disable=W0703 _LOG.exception('FrameMain._on_menu_file_save error') msgdlg = wx.lib.dialogs.ScrolledMessageDialog(self.wnd, str(err), _("Synchronisation error")) msgdlg.ShowModal() msgdlg.Destroy() dlgp.update(100, _("Error: ") + str(err)) dlgp.mark_finished(2) publisher.sendMessage('task.update') appconfig.set('files', 'last_dir', os.path.dirname(filename)) appconfig.set('files', 'last_file', os.path.basename(filename)) dlg.Destroy()
def sync(load_only=False, notify_cb=_notify_progress): """ Sync data from/to given file. Notify progress by publisher. Args: load_only: only load, not write data Raises: SyncLockedError when source file is locked. """ _LOG.info("sync: %r", SYNC_PATH) if not dropbox: raise SYNC.OtherSyncError(_("Dropbox is not available.")) if not appconfig.AppConfig().get('dropbox', 'oauth_secret'): raise SYNC.OtherSyncError(_("Dropbox is not configured.")) notify_cb(0, _("Sync via Dropbox API....")) notify_cb(1, _("Creating backup")) SYNC.create_backup() notify_cb(25, _("Checking sync lock")) try: dbclient = _create_session() except dropbox.rest.ErrorResponse as error: raise SYNC.OtherSyncError(_("Dropbox: connection failed: %s") % str(error)) temp_file = tempfile.NamedTemporaryFile(suffix='.zip', delete=False) temp_filename = temp_file.name if create_sync_lock(dbclient): notify_cb(2, _("Downloading...")) try: loaded = download_file(temp_file, SYNC_PATH, dbclient) temp_file.close() if loaded: loader.load_from_file(temp_filename, notify_cb) if not load_only: exporter.save_to_file(temp_filename, notify_cb, 'GTD_SYNC.json') _delete_file(dbclient, SYNC_PATH) notify_cb(20, _("Uploading...")) with open(temp_filename) as temp_file: dbclient.put_file(SYNC_PATH, temp_file) except Exception as err: _LOG.exception("file sync error") raise SYNC.OtherSyncError(err) finally: notify_cb(90, _("Removing sync lock")) _delete_file(dbclient, LOCK_PATH) with ignore_exceptions(IOError): os.unlink(temp_filename) notify_cb(100, _("Completed")) else: notify_cb(100, _("Synchronization file is locked. " "Can't synchronize...")) raise SYNC.SyncLockedError()
def create_backup(): """ Create backup current data in database. Format of backup file is identical with synchronization file. Backup are stored for default in ~/.local/share/wxgtd/backups/ Configuration in wxgtd.conf: [backup] number_copies = 21 location = <path to dir> """ appcfg = appconfig.AppConfig() backup_dir = appcfg.get('backup', 'location') if backup_dir: backup_dir = os.path.expanduser(backup_dir) else: backup_dir = os.path.join(appcfg.user_share_dir, 'backups') filename = os.path.join(backup_dir, "BACKUP_" + datetime.date.today().isoformat() + ".json.zip") _LOG.info('create_backup: %s', filename) if os.path.isfile(filename): _LOG.info("create_backup: today backup already exists; skipping...") return True if os.path.isdir(backup_dir): num_files_to_keep = int(appcfg.get('backup', 'number_copies', 21)) # backup dir exists; check number of files and delete if more than 21 files = sorted((fname for fname in os.listdir(backup_dir) if fname.startswith('BACKUP') and fname.endswith('.json.zip')), reverse=True) if len(files) >= num_files_to_keep: for fname in files[num_files_to_keep:]: _LOG.info('create_backup: delete backup: %r', fname) os.unlink(os.path.join(backup_dir, fname)) else: try: os.mkdir(backup_dir) except IOError as error: _LOG.error('create_backup: create dir error: %s', str(error)) return False # backup is regular export (zip) exporter.save_to_file(os.path.join(backup_dir, filename), internal_fname="GDT_SYNC.json") _LOG.info('create_backup: COMPLETED %s', filename) return True
def sync(filename, load_only=False, notify_cb=_notify_progress): """ Sync data from/to given file. Notify progress by publisher. Args: filename: full path to file load_only: only load, not write data Raises: SyncLockedError when source file is locked. """ _LOG.info("sync: %r", filename) notify_cb(0, _("Sync via file %s") % filename) notify_cb(0, _("Creating backup")) create_backup() notify_cb(25, _("Sanity check")) _sync_file_check(filename) notify_cb(50, _("Checking sync lock")) if exporter.create_sync_lock(filename): notify_cb(1, _("Loading...")) try: if loader.load_from_file(filename, notify_cb): if not load_only: exporter.save_to_file(filename, notify_cb) except Exception as err: _LOG.exception("file sync error") raise OtherSyncError(err) finally: notify_cb(50, _("Removing sync lock")) exporter.delete_sync_lock(filename) notify_cb(100, _("Completed")) else: notify_cb(100, _("Synchronization file is locked. " "Can't synchronize...")) raise SyncLockedError()