mirror of https://github.com/halo-dev/halo
feat: add work dir backup options (#1494)
* feat: Add backup options * feat: add sort for list backup items api * refactor: rename variblespull/1665/head^2
parent
8c26430b31
commit
0dc75e29bb
|
@ -6,8 +6,12 @@ import static run.halo.app.service.BackupService.BackupType.WHOLE_SITE;
|
|||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
@ -81,8 +85,19 @@ public class BackupController {
|
|||
@PostMapping("work-dir")
|
||||
@ApiOperation("Backups work directory")
|
||||
@DisableOnCondition
|
||||
public BackupDTO backupHalo() {
|
||||
return backupService.backupWorkDirectory();
|
||||
public BackupDTO backupHalo(@RequestBody List<String> options) {
|
||||
return backupService.backupWorkDirectory(options);
|
||||
}
|
||||
|
||||
@GetMapping("work-dir/options")
|
||||
@ApiOperation("Gets items that can be backed up")
|
||||
public List<String> listBackupItems() throws IOException {
|
||||
return Files.list(Paths.get(haloProperties.getWorkDir()))
|
||||
.map(Path::getFileName)
|
||||
.filter(Objects::nonNull)
|
||||
.map(Path::toString)
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@GetMapping("work-dir")
|
||||
|
|
|
@ -32,11 +32,11 @@ public interface BackupService {
|
|||
/**
|
||||
* Zips work directory.
|
||||
*
|
||||
* @param options file or directory items to back up
|
||||
* @return backup dto.
|
||||
*/
|
||||
@NonNull
|
||||
BackupDTO backupWorkDirectory();
|
||||
|
||||
BackupDTO backupWorkDirectory(List<String> options);
|
||||
|
||||
/**
|
||||
* Lists all backups.
|
||||
|
|
|
@ -33,10 +33,12 @@ import org.springframework.core.io.UrlResource;
|
|||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import run.halo.app.config.properties.HaloProperties;
|
||||
import run.halo.app.event.options.OptionUpdatedEvent;
|
||||
import run.halo.app.event.theme.ThemeUpdatedEvent;
|
||||
import run.halo.app.exception.BadRequestException;
|
||||
import run.halo.app.exception.NotFoundException;
|
||||
import run.halo.app.exception.ServiceException;
|
||||
import run.halo.app.handler.file.FileHandler;
|
||||
|
@ -213,7 +215,10 @@ public class BackupServiceImpl implements BackupService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public BackupDTO backupWorkDirectory() {
|
||||
public BackupDTO backupWorkDirectory(List<String> options) {
|
||||
if (CollectionUtils.isEmpty(options)) {
|
||||
throw new BadRequestException("The options parameter is missing, at least one.");
|
||||
}
|
||||
// Zip work directory to temporary file
|
||||
try {
|
||||
// Create zip path for halo zip
|
||||
|
@ -229,7 +234,17 @@ public class BackupServiceImpl implements BackupService {
|
|||
|
||||
// Zip halo
|
||||
run.halo.app.utils.FileUtils
|
||||
.zip(Paths.get(this.haloProperties.getWorkDir()), haloZipPath);
|
||||
.zip(Paths.get(this.haloProperties.getWorkDir()), haloZipPath,
|
||||
path -> {
|
||||
for (String itemToBackup : options) {
|
||||
Path backupItemPath =
|
||||
Paths.get(this.haloProperties.getWorkDir()).resolve(itemToBackup);
|
||||
if (path.startsWith(backupItemPath)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
// Build backup dto
|
||||
return buildBackupDto(BACKUP_RESOURCE_BASE_URI, haloZipPath);
|
||||
|
|
|
@ -185,6 +185,23 @@ public class FileUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Zips folder or file with filter.
|
||||
*
|
||||
* @param pathToZip file path to zip must not be null
|
||||
* @param pathOfArchive zip file path to archive must not be null
|
||||
* @param filter folder or file filter
|
||||
* @throws IOException throws when failed to access file to be zipped
|
||||
*/
|
||||
public static void zip(@NonNull Path pathToZip, @NonNull Path pathOfArchive,
|
||||
@Nullable Predicate<Path> filter) throws IOException {
|
||||
try (OutputStream outputStream = Files.newOutputStream(pathOfArchive)) {
|
||||
try (ZipOutputStream zipOut = new ZipOutputStream(outputStream)) {
|
||||
zip(pathToZip, zipOut, filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Zips folder or file.
|
||||
*
|
||||
|
@ -198,6 +215,20 @@ public class FileUtils {
|
|||
zip(pathToZip, pathToZip.getFileName().toString(), zipOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zips folder or file with filter.
|
||||
*
|
||||
* @param pathToZip file path to zip must not be null
|
||||
* @param zipOut zip output stream must not be null
|
||||
* @param filter directory or file filter
|
||||
* @throws IOException throws when failed to access file to be zipped
|
||||
*/
|
||||
public static void zip(@NonNull Path pathToZip, @NonNull ZipOutputStream zipOut,
|
||||
Predicate<Path> filter) throws IOException {
|
||||
// Zip file
|
||||
zip(pathToZip, pathToZip.getFileName().toString(), zipOut, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zips folder or file.
|
||||
*
|
||||
|
@ -208,6 +239,20 @@ public class FileUtils {
|
|||
*/
|
||||
private static void zip(@NonNull Path fileToZip, @NonNull String fileName,
|
||||
@NonNull ZipOutputStream zipOut) throws IOException {
|
||||
zip(fileToZip, fileName, zipOut, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zips folder or file with path filter.
|
||||
*
|
||||
* @param fileToZip file path to zip must not be null
|
||||
* @param fileName file name must not be blank
|
||||
* @param zipOut zip output stream must not be null
|
||||
* @param filter directory or file filter
|
||||
* @throws IOException throws when failed to access file to be zipped
|
||||
*/
|
||||
private static void zip(@NonNull Path fileToZip, @NonNull String fileName,
|
||||
@NonNull ZipOutputStream zipOut, @Nullable Predicate<Path> filter) throws IOException {
|
||||
if (Files.isDirectory(fileToZip)) {
|
||||
log.debug("Try to zip folder: [{}]", fileToZip);
|
||||
// Append with '/' if missing
|
||||
|
@ -222,10 +267,12 @@ public class FileUtils {
|
|||
try (Stream<Path> subPathStream = Files.list(fileToZip)) {
|
||||
// There should not use foreach for stream as internal zip method will throw
|
||||
// IOException
|
||||
List<Path> subFiles = subPathStream.collect(Collectors.toList());
|
||||
List<Path> subFiles =
|
||||
filter != null ? subPathStream.filter(filter).collect(Collectors.toList())
|
||||
: subPathStream.collect(Collectors.toList());
|
||||
for (Path subFileToZip : subFiles) {
|
||||
// Zip children
|
||||
zip(subFileToZip, folderName + subFileToZip.getFileName(), zipOut);
|
||||
zip(subFileToZip, folderName + subFileToZip.getFileName(), zipOut, filter);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue