diff --git a/src/main/java/run/halo/app/handler/file/AliOssFileHandler.java b/src/main/java/run/halo/app/handler/file/AliOssFileHandler.java index 9b4d756d4..2cdac5bc8 100644 --- a/src/main/java/run/halo/app/handler/file/AliOssFileHandler.java +++ b/src/main/java/run/halo/app/handler/file/AliOssFileHandler.java @@ -87,8 +87,9 @@ public class AliOssFileHandler implements FileHandler { .setBasePath(basePath.toString()) .setSubPath(source) .setAutomaticRename(true) - .setRenamePredicate(builder -> - attachmentRepository.countByPath(builder.getFullPath()) > 0) + .setRenamePredicate(relativePath -> + attachmentRepository + .countByFileKeyAndType(relativePath, AttachmentType.ALIOSS) > 0) .setOriginalName(file.getOriginalFilename()) .build(); diff --git a/src/main/java/run/halo/app/handler/file/BaiduBosFileHandler.java b/src/main/java/run/halo/app/handler/file/BaiduBosFileHandler.java index 0dbf7589d..85719fc8f 100644 --- a/src/main/java/run/halo/app/handler/file/BaiduBosFileHandler.java +++ b/src/main/java/run/halo/app/handler/file/BaiduBosFileHandler.java @@ -75,8 +75,9 @@ public class BaiduBosFileHandler implements FileHandler { .setBasePath(domain) .setSubPath(source) .setAutomaticRename(true) - .setRenamePredicate(builder -> - attachmentRepository.countByPath(builder.getFullPath()) > 0) + .setRenamePredicate(relativePath -> + attachmentRepository + .countByFileKeyAndType(relativePath, AttachmentType.BAIDUBOS) > 0) .setOriginalName(file.getOriginalFilename()) .build(); diff --git a/src/main/java/run/halo/app/handler/file/FilePathDescriptor.java b/src/main/java/run/halo/app/handler/file/FilePathDescriptor.java index 9939ba08e..aa1172b84 100644 --- a/src/main/java/run/halo/app/handler/file/FilePathDescriptor.java +++ b/src/main/java/run/halo/app/handler/file/FilePathDescriptor.java @@ -3,10 +3,10 @@ package run.halo.app.handler.file; import java.util.function.Predicate; import lombok.Data; import lombok.experimental.Accessors; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.util.Assert; import run.halo.app.utils.FilenameUtils; -import run.halo.app.utils.HaloUtils; /** * File path descriptor. @@ -14,6 +14,7 @@ import run.halo.app.utils.HaloUtils; * @author guqing * @since 2021-10-21 */ +@Slf4j @Data @Accessors(chain = true) public final class FilePathDescriptor { @@ -30,15 +31,16 @@ public final class FilePathDescriptor { private String name; private String extension; - private String path; + private String subPath; private String basePath; private String nameSuffix = StringUtils.EMPTY; private String separator = "/"; private boolean automaticRename; - private Predicate renamePredicate; + private Predicate renamePredicate; + private String relativePath; public Builder setSubPath(String subPath) { - this.path = StringUtils.removeEnd(subPath, separator); + this.subPath = StringUtils.removeEnd(subPath, separator); return this; } @@ -47,7 +49,7 @@ public final class FilePathDescriptor { return this; } - public Builder setRenamePredicate(Predicate predicate) { + public Builder setRenamePredicate(Predicate predicate) { this.renamePredicate = predicate; return this; } @@ -80,7 +82,7 @@ public final class FilePathDescriptor { } public Builder setBasePath(String basePath) { - this.basePath = basePath; + this.basePath = StringUtils.removeEnd(basePath, separator); return this; } @@ -98,7 +100,7 @@ public final class FilePathDescriptor { return this; } - String getName() { + String buildName() { StringBuilder sb = new StringBuilder() .append(this.name); if (shouldRename()) { @@ -112,16 +114,20 @@ public final class FilePathDescriptor { String getFullName() { // eg. hello.jpg -> hello-uuid-thumbnail.jpg if (StringUtils.isNotBlank(this.extension)) { - return getName() + '.' + this.extension; + return this.name + '.' + this.extension; } - return getName(); + return this.name; } String getFullPath() { if (StringUtils.isNotBlank(this.basePath)) { - return getPath(this.basePath, this.path, this.getFullName()); + return getPath(this.basePath, this.subPath, this.getFullName()); } - return getPath(this.path, this.getFullName()); + return getPath(this.subPath, this.getFullName()); + } + + String getRelativePath() { + return getPath(this.subPath, getFullName()); } private boolean shouldRename() { @@ -133,7 +139,7 @@ public final class FilePathDescriptor { return true; } // renamePredicate not null - return renamePredicate.test(this); + return renamePredicate.test(this.relativePath); } private String getPath(String first, String... more) { @@ -162,14 +168,22 @@ public final class FilePathDescriptor { * @return file path */ public FilePathDescriptor build() { - return new FilePathDescriptor() + // build relative path first, used to determine if it needs to be renamed + this.relativePath = getRelativePath(); + // then build name, returns a new name if the relative path exists + this.name = buildName(); + + FilePathDescriptor descriptor = new FilePathDescriptor() .setBasePath(this.basePath) - .setSubPath(this.path) - .setRelativePath(getPath(this.path, getFullName())) - .setName(FilenameUtils.getBasename(getName())) + .setSubPath(this.subPath) + // regenerate relative path + .setRelativePath(getRelativePath()) + .setName(FilenameUtils.getBasename(this.name)) .setExtension(extension) .setFullPath(getFullPath()) .setFullName(getFullName()); + log.info("FilePathDescriptor: [{}]", descriptor); + return descriptor; } } } diff --git a/src/main/java/run/halo/app/handler/file/HuaweiObsFileHandler.java b/src/main/java/run/halo/app/handler/file/HuaweiObsFileHandler.java index db83577e4..e8bb5fe7b 100644 --- a/src/main/java/run/halo/app/handler/file/HuaweiObsFileHandler.java +++ b/src/main/java/run/halo/app/handler/file/HuaweiObsFileHandler.java @@ -85,8 +85,9 @@ public class HuaweiObsFileHandler implements FileHandler { .setBasePath(domain) .setSubPath(source) .setAutomaticRename(true) - .setRenamePredicate(builder -> - attachmentRepository.countByPath(builder.getFullPath()) > 0) + .setRenamePredicate(relativePath -> + attachmentRepository + .countByFileKeyAndType(relativePath, AttachmentType.HUAWEIOBS) > 0) .setOriginalName(file.getOriginalFilename()) .build(); diff --git a/src/main/java/run/halo/app/handler/file/LocalFileHandler.java b/src/main/java/run/halo/app/handler/file/LocalFileHandler.java index 84c1d6e7c..64360fa0b 100644 --- a/src/main/java/run/halo/app/handler/file/LocalFileHandler.java +++ b/src/main/java/run/halo/app/handler/file/LocalFileHandler.java @@ -94,8 +94,9 @@ public class LocalFileHandler implements FileHandler { .setSubPath(generatePath()) .setSeparator(FILE_SEPARATOR) .setAutomaticRename(true) - .setRenamePredicate(builder -> - attachmentRepository.countByPath(builder.getFullPath()) > 0) + .setRenamePredicate(relativePath -> + attachmentRepository + .countByFileKeyAndType(relativePath, AttachmentType.LOCAL) > 0) .setOriginalName(file.getOriginalFilename()) .build(); log.info("Uploading file: [{}] to directory: [{}]", file.getOriginalFilename(), diff --git a/src/main/java/run/halo/app/handler/file/MinioFileHandler.java b/src/main/java/run/halo/app/handler/file/MinioFileHandler.java index 8d303c467..28d27c008 100644 --- a/src/main/java/run/halo/app/handler/file/MinioFileHandler.java +++ b/src/main/java/run/halo/app/handler/file/MinioFileHandler.java @@ -69,8 +69,9 @@ public class MinioFileHandler implements FileHandler { .setBasePath(endpoint + bucketName) .setSubPath(source) .setAutomaticRename(true) - .setRenamePredicate(builder -> - attachmentRepository.countByPath(builder.getFullPath()) > 0) + .setRenamePredicate(relativePath -> + attachmentRepository + .countByFileKeyAndType(relativePath, AttachmentType.MINIO) > 0) .setOriginalName(file.getOriginalFilename()) .build(); diff --git a/src/main/java/run/halo/app/handler/file/QiniuOssFileHandler.java b/src/main/java/run/halo/app/handler/file/QiniuOssFileHandler.java index ba343ed7f..6e890b9c5 100644 --- a/src/main/java/run/halo/app/handler/file/QiniuOssFileHandler.java +++ b/src/main/java/run/halo/app/handler/file/QiniuOssFileHandler.java @@ -32,7 +32,6 @@ import run.halo.app.model.properties.QiniuOssProperties; import run.halo.app.model.support.UploadResult; import run.halo.app.repository.AttachmentRepository; import run.halo.app.service.OptionService; -import run.halo.app.utils.FilenameUtils; import run.halo.app.utils.ImageUtils; import run.halo.app.utils.JsonUtils; @@ -105,8 +104,9 @@ public class QiniuOssFileHandler implements FileHandler { .setBasePath(basePath.toString()) .setSubPath(source) .setAutomaticRename(true) - .setRenamePredicate(builder -> - attachmentRepository.countByPath(builder.getFullPath()) > 0) + .setRenamePredicate(relativePath -> + attachmentRepository + .countByFileKeyAndType(relativePath, AttachmentType.QINIUOSS) > 0) .setOriginalName(file.getOriginalFilename()) .build(); diff --git a/src/main/java/run/halo/app/handler/file/TencentCosFileHandler.java b/src/main/java/run/halo/app/handler/file/TencentCosFileHandler.java index 44e12e49e..5c7a3f9b4 100644 --- a/src/main/java/run/halo/app/handler/file/TencentCosFileHandler.java +++ b/src/main/java/run/halo/app/handler/file/TencentCosFileHandler.java @@ -94,8 +94,9 @@ public class TencentCosFileHandler implements FileHandler { .setBasePath(basePath.toString()) .setSubPath(source) .setAutomaticRename(true) - .setRenamePredicate(builder -> - attachmentRepository.countByPath(builder.getFullPath()) > 0) + .setRenamePredicate(relativePath -> + attachmentRepository + .countByFileKeyAndType(relativePath, AttachmentType.TENCENTCOS) > 0) .setOriginalName(file.getOriginalFilename()) .build(); diff --git a/src/main/java/run/halo/app/handler/file/UpOssFileHandler.java b/src/main/java/run/halo/app/handler/file/UpOssFileHandler.java index 9bad98899..3881b7803 100644 --- a/src/main/java/run/halo/app/handler/file/UpOssFileHandler.java +++ b/src/main/java/run/halo/app/handler/file/UpOssFileHandler.java @@ -107,6 +107,7 @@ public class UpOssFileHandler implements FileHandler { filePath + thumbnailStyleRule; } }); + result.close(); return uploadResult; } catch (Exception e) { throw new FileOperationException("上传附件 " + file.getOriginalFilename() + " 到又拍云失败", e); diff --git a/src/main/java/run/halo/app/repository/AttachmentRepository.java b/src/main/java/run/halo/app/repository/AttachmentRepository.java index dd68ba3c1..200aac43b 100644 --- a/src/main/java/run/halo/app/repository/AttachmentRepository.java +++ b/src/main/java/run/halo/app/repository/AttachmentRepository.java @@ -41,4 +41,13 @@ public interface AttachmentRepository * @return count of the given path */ long countByPath(@NonNull String path); + + /** + * Counts by attachment file key and type. + * + * @param fileKey attachment file key must not be blank + * @param type attachment type must not be null + * @return count of the given path and type + */ + long countByFileKeyAndType(@NonNull String fileKey, @NonNull AttachmentType type); } diff --git a/src/test/java/run/halo/app/handler/file/FilePathDescriptorTest.java b/src/test/java/run/halo/app/handler/file/FilePathDescriptorTest.java index 71dd2de7e..11683ecb6 100644 --- a/src/test/java/run/halo/app/handler/file/FilePathDescriptorTest.java +++ b/src/test/java/run/halo/app/handler/file/FilePathDescriptorTest.java @@ -45,12 +45,12 @@ public class FilePathDescriptorTest { @Test public void autoRenameWithPredicate() { FilePathDescriptor descriptor1 = descriptorBuilder.setAutomaticRename(true) - .setRenamePredicate(builder -> false).build(); + .setRenamePredicate(path -> false).build(); assertEquals("/home/halo/2021/10/hello.jpg", descriptor1.getFullPath()); assertEquals("2021/10/hello.jpg", descriptor1.getRelativePath()); FilePathDescriptor descriptor2 = descriptorBuilder.setAutomaticRename(true) - .setRenamePredicate(builder -> true).build(); + .setRenamePredicate(path -> true).build(); assertNotEquals("/home/halo/2021/10/hello.jpg", descriptor2.getFullPath()); assertNotEquals("2021/10/hello.jpg", descriptor2.getRelativePath()); }