def restore(self, name, restore_date, use_zip): """Used to restore the given file located in this path.""" assert isinstance(name, str) assert isinstance(restore_date, rdw_helpers.rdwTime) name = name.lstrip(b"/") # Determine the file name to be restore (from rdiff-backup # point of view). file_to_restore = os.path.join(self.full_path, name) file_to_restore = self.repo.unquote(file_to_restore) # Convert the date into epoch. date_epoch = str(restore_date.getSeconds()) # Define a location where to restore the data if name == b"" and self.path == b"": filename = b"root" if self.path != b"": filename = os.path.basename(self.path) if name != b"": filename = name # Generate a temporary location used to restore data. tempdir = rdw_helpers.encode_s(rdw_config.get_config("tempdir", default=None)) output = os.path.join(tempfile.mkdtemp(dir=tempdir), filename) # Execute rdiff-backup to restore the data. logger.info(b"execute rdiff-backup --restore-as-of=%s '%s' '%s'" % (date_epoch, file_to_restore, output)) results = self._execute( b"rdiff-backup", b"--restore-as-of=" + date_epoch, file_to_restore, output) # Check the result if results['exitCode'] != 0 or not os.access(output, os.F_OK): error = results['stderr'] if not error: error = '''rdiff-backup claimed success, but did not restore anything. This indicates a bug in rdiffweb. Please report this to a developer.''' raise UnknownError('unable to restore!\n' + error) # The path restored is a directory and need to be archived using zip # or tar if os.path.isdir(output): output_dir = output try: if use_zip: output = output_dir + ZIP_SUFFIX self._recursiveZipDir(output_dir, output) else: output = output_dir + TARGZ_SUFFIX self._recursiveTarDir(output_dir, output) finally: rdw_helpers.remove_dir(output_dir) # Return the location of the file to be restored return output
def autodelete(): """Register an handler to delete the restored files when the HTTP request is ending.""" if not hasattr(cherrypy.request, "_autodelete_dir"): return autodelete_dir = cherrypy.request._autodelete_dir logger.info("deleting temporary folder [%s]" % decode_s(autodelete_dir, 'replace')) # Check if path exists if not os.access(autodelete_dir, os.F_OK): logger.info("temporary folder [%s] doesn't exists" % decode_s(autodelete_dir, 'replace')) return if not os.path.isdir(autodelete_dir): autodelete_dir = os.path.dirname(autodelete_dir) rdw_helpers.remove_dir(autodelete_dir)