mirror of https://github.com/halo-dev/halo
feat: Refactor the naming method of uploaded attachments
parent
0dc75e29bb
commit
d8116c8557
|
@ -10,14 +10,18 @@ import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.coobird.thumbnailator.Thumbnails;
|
import net.coobird.thumbnailator.Thumbnails;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import run.halo.app.config.properties.HaloProperties;
|
import run.halo.app.config.properties.HaloProperties;
|
||||||
import run.halo.app.exception.FileOperationException;
|
import run.halo.app.exception.FileOperationException;
|
||||||
|
import run.halo.app.handler.file.LocalFileHandler.FilePath.Builder;
|
||||||
import run.halo.app.model.enums.AttachmentType;
|
import run.halo.app.model.enums.AttachmentType;
|
||||||
import run.halo.app.model.support.UploadResult;
|
import run.halo.app.model.support.UploadResult;
|
||||||
import run.halo.app.service.OptionService;
|
import run.halo.app.service.OptionService;
|
||||||
|
@ -87,53 +91,28 @@ public class LocalFileHandler implements FileHandler {
|
||||||
public UploadResult upload(MultipartFile file) {
|
public UploadResult upload(MultipartFile file) {
|
||||||
Assert.notNull(file, "Multipart file must not be null");
|
Assert.notNull(file, "Multipart file must not be null");
|
||||||
|
|
||||||
// Get current time
|
FilePath uploadFilePath = new Builder()
|
||||||
Calendar current = Calendar.getInstance(optionService.getLocale());
|
.setBasePath(workDir)
|
||||||
// Get month and day of month
|
.setOriginalName(file.getOriginalFilename())
|
||||||
int year = current.get(Calendar.YEAR);
|
.build();
|
||||||
int month = current.get(Calendar.MONTH) + 1;
|
log.info("Uploading file: [{}] to directory: [{}]", file.getOriginalFilename(),
|
||||||
|
uploadFilePath.getSubPath());
|
||||||
String monthString = month < 10 ? "0" + month : String.valueOf(month);
|
|
||||||
|
|
||||||
// Build directory
|
|
||||||
String subDir = UPLOAD_SUB_DIR + year + FILE_SEPARATOR + monthString + FILE_SEPARATOR;
|
|
||||||
|
|
||||||
String originalBasename =
|
|
||||||
FilenameUtils.getBasename(Objects.requireNonNull(file.getOriginalFilename()));
|
|
||||||
|
|
||||||
// Get basename
|
|
||||||
String basename = originalBasename + '-' + HaloUtils.randomUUIDWithoutDash();
|
|
||||||
|
|
||||||
// Get extension
|
|
||||||
String extension = FilenameUtils.getExtension(file.getOriginalFilename());
|
|
||||||
|
|
||||||
log.debug("Base name: [{}], extension: [{}] of original filename: [{}]", basename,
|
|
||||||
extension, file.getOriginalFilename());
|
|
||||||
|
|
||||||
// Build sub file path
|
|
||||||
String subFilePath = subDir + basename + '.' + extension;
|
|
||||||
|
|
||||||
// Get upload path
|
|
||||||
Path uploadPath = Paths.get(workDir, subFilePath);
|
|
||||||
|
|
||||||
log.info("Uploading file: [{}]to directory: [{}]", file.getOriginalFilename(),
|
|
||||||
uploadPath.toString());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// TODO Synchronize here
|
// TODO Synchronize here
|
||||||
// Create directory
|
// Create directory
|
||||||
Files.createDirectories(uploadPath.getParent());
|
Files.createDirectories(uploadFilePath.getFullPath().getParent());
|
||||||
Files.createFile(uploadPath);
|
Files.createFile(uploadFilePath.getFullPath());
|
||||||
|
|
||||||
// Upload this file
|
// Upload this file
|
||||||
file.transferTo(uploadPath);
|
file.transferTo(uploadFilePath.getFullPath());
|
||||||
|
|
||||||
// Build upload result
|
// Build upload result
|
||||||
UploadResult uploadResult = new UploadResult();
|
UploadResult uploadResult = new UploadResult();
|
||||||
uploadResult.setFilename(originalBasename);
|
uploadResult.setFilename(uploadFilePath.getName());
|
||||||
uploadResult.setFilePath(subFilePath);
|
uploadResult.setFilePath(uploadFilePath.getSubPath());
|
||||||
uploadResult.setKey(subFilePath);
|
uploadResult.setKey(uploadFilePath.getSubPath());
|
||||||
uploadResult.setSuffix(extension);
|
uploadResult.setSuffix(uploadFilePath.getExtension());
|
||||||
uploadResult
|
uploadResult
|
||||||
.setMediaType(MediaType.valueOf(Objects.requireNonNull(file.getContentType())));
|
.setMediaType(MediaType.valueOf(Objects.requireNonNull(file.getContentType())));
|
||||||
uploadResult.setSize(file.getSize());
|
uploadResult.setSize(file.getSize());
|
||||||
|
@ -141,28 +120,123 @@ public class LocalFileHandler implements FileHandler {
|
||||||
// TODO refactor this: if image is svg ext. extension
|
// TODO refactor this: if image is svg ext. extension
|
||||||
handleImageMetadata(file, uploadResult, () -> {
|
handleImageMetadata(file, uploadResult, () -> {
|
||||||
// Upload a thumbnail
|
// Upload a thumbnail
|
||||||
final String thumbnailBasename = basename + THUMBNAIL_SUFFIX;
|
FilePath thumbnailFilePath = new Builder()
|
||||||
final String thumbnailSubFilePath = subDir + thumbnailBasename + '.' + extension;
|
.setBasePath(workDir)
|
||||||
final Path thumbnailPath = Paths.get(workDir + thumbnailSubFilePath);
|
.setOriginalName(THUMBNAIL_SUFFIX + uploadFilePath.getFullName())
|
||||||
|
.build();
|
||||||
|
final Path thumbnailPath = thumbnailFilePath.getFullPath();
|
||||||
try (InputStream is = file.getInputStream()) {
|
try (InputStream is = file.getInputStream()) {
|
||||||
// Generate thumbnail
|
// Generate thumbnail
|
||||||
BufferedImage originalImage = ImageUtils.getImageFromFile(is, extension);
|
BufferedImage originalImage =
|
||||||
boolean result = generateThumbnail(originalImage, thumbnailPath, extension);
|
ImageUtils.getImageFromFile(is, uploadFilePath.getExtension());
|
||||||
|
boolean result = generateThumbnail(originalImage, thumbnailPath,
|
||||||
|
uploadFilePath.getExtension());
|
||||||
if (result) {
|
if (result) {
|
||||||
// Set thumb path
|
// Set thumb path
|
||||||
return thumbnailSubFilePath;
|
return thumbnailFilePath.getSubFilePath();
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
log.warn("Failed to open image file.", e);
|
log.warn("Failed to open image file.", e);
|
||||||
}
|
}
|
||||||
return subFilePath;
|
return uploadFilePath.getSubFilePath();
|
||||||
});
|
});
|
||||||
|
|
||||||
log.info("Uploaded file: [{}] to directory: [{}] successfully",
|
log.info("Uploaded file: [{}] to directory: [{}] successfully",
|
||||||
file.getOriginalFilename(), uploadPath.toString());
|
file.getOriginalFilename(), uploadFilePath.getFullPath().toString());
|
||||||
return uploadResult;
|
return uploadResult;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new FileOperationException("上传附件失败").setErrorData(uploadPath);
|
throw new FileOperationException("上传附件失败").setErrorData(uploadFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public static final class FilePath {
|
||||||
|
String name;
|
||||||
|
String extension;
|
||||||
|
String subPath;
|
||||||
|
String subFilePath;
|
||||||
|
String basePath;
|
||||||
|
String fullName;
|
||||||
|
Path fullPath;
|
||||||
|
|
||||||
|
public static final class Builder {
|
||||||
|
String name;
|
||||||
|
String extension;
|
||||||
|
String path;
|
||||||
|
String basePath;
|
||||||
|
|
||||||
|
public Builder() {
|
||||||
|
this.path = generatePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generatePath() {
|
||||||
|
// Get current time
|
||||||
|
Calendar current = Calendar.getInstance();
|
||||||
|
// Get month and day of month
|
||||||
|
int year = current.get(Calendar.YEAR);
|
||||||
|
int month = current.get(Calendar.MONTH) + 1;
|
||||||
|
|
||||||
|
String monthString = month < 10 ? "0" + month : String.valueOf(month);
|
||||||
|
|
||||||
|
// Build directory
|
||||||
|
return UPLOAD_SUB_DIR + year + FILE_SEPARATOR + monthString + FILE_SEPARATOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set original file name.
|
||||||
|
*
|
||||||
|
* @param originalFileName original file name
|
||||||
|
* @return file path builder
|
||||||
|
*/
|
||||||
|
public Builder setOriginalName(String originalFileName) {
|
||||||
|
Assert.notNull(originalFileName, "The originalFileName must not be null.");
|
||||||
|
this.name = FilenameUtils.getBasename(originalFileName);
|
||||||
|
this.extension = FilenameUtils.getExtension(originalFileName);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setBasePath(String basePath) {
|
||||||
|
this.basePath = basePath;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getFullName() {
|
||||||
|
if (!hasExtension()) {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
return this.name + '.' + this.extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path getFullPath() {
|
||||||
|
if (StringUtils.isNotBlank(this.basePath)) {
|
||||||
|
return Paths.get(this.basePath, this.path, this.getFullName());
|
||||||
|
}
|
||||||
|
return Paths.get(this.path, this.getFullName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* build file path object.
|
||||||
|
*
|
||||||
|
* @return file path
|
||||||
|
*/
|
||||||
|
public FilePath build() {
|
||||||
|
if (Files.exists(getFullPath())) {
|
||||||
|
this.name = this.name + '-' + HaloUtils.simpleUUID();
|
||||||
|
}
|
||||||
|
return new FilePath()
|
||||||
|
.setBasePath(this.basePath)
|
||||||
|
.setSubPath(this.path)
|
||||||
|
.setSubFilePath(this.path + getFullName())
|
||||||
|
.setName(this.name)
|
||||||
|
.setExtension(extension)
|
||||||
|
.setFullPath(getFullPath())
|
||||||
|
.setFullName(getFullName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasExtension() {
|
||||||
|
return StringUtils.isNotBlank(this.extension);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue