mirror of https://github.com/halo-dev/halo
Add a common theme addition service
parent
9e9bd1a377
commit
76b3310027
|
@ -7,6 +7,7 @@ import run.halo.app.handler.theme.support.ThemeProperty;
|
|||
import run.halo.app.model.support.ThemeFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
@ -204,9 +205,19 @@ public interface ThemeService {
|
|||
|
||||
/**
|
||||
* Upload theme.
|
||||
*
|
||||
* @param file multipart file must not be null
|
||||
* @return theme info
|
||||
*/
|
||||
@NonNull
|
||||
ThemeProperty upload(@NonNull MultipartFile file);
|
||||
|
||||
/**
|
||||
* Adds a new theme.
|
||||
*
|
||||
* @param themeTmpPath theme temporary path must not be null
|
||||
* @return theme property
|
||||
*/
|
||||
@NonNull
|
||||
ThemeProperty add(@NonNull Path themeTmpPath) throws IOException;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import freemarker.template.Configuration;
|
|||
import freemarker.template.TemplateModelException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@ -20,7 +19,6 @@ import org.springframework.web.multipart.MultipartFile;
|
|||
import run.halo.app.cache.StringCacheStore;
|
||||
import run.halo.app.config.properties.HaloProperties;
|
||||
import run.halo.app.exception.*;
|
||||
import run.halo.app.handler.file.FileHandler;
|
||||
import run.halo.app.handler.theme.ThemeConfigResolver;
|
||||
import run.halo.app.handler.theme.ThemePropertyResolver;
|
||||
import run.halo.app.handler.theme.support.Group;
|
||||
|
@ -28,14 +26,12 @@ import run.halo.app.handler.theme.support.ThemeProperty;
|
|||
import run.halo.app.model.properties.PrimaryProperties;
|
||||
import run.halo.app.model.support.HaloConst;
|
||||
import run.halo.app.model.support.ThemeFile;
|
||||
import run.halo.app.model.support.UploadResult;
|
||||
import run.halo.app.service.OptionService;
|
||||
import run.halo.app.service.ThemeService;
|
||||
import run.halo.app.utils.FileUtils;
|
||||
import run.halo.app.utils.FilenameUtils;
|
||||
import run.halo.app.utils.JsonUtils;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
@ -287,15 +283,6 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
return activatedThemeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set activated theme id.
|
||||
*
|
||||
* @param themeId theme id
|
||||
*/
|
||||
private void setActivatedThemeId(@Nullable String themeId) {
|
||||
this.activatedThemeId = themeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThemeProperty activeTheme(String themeId) {
|
||||
// Check existence of the theme
|
||||
|
@ -322,12 +309,6 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
return themeProperty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload theme.
|
||||
*
|
||||
* @param file multipart file must not be null
|
||||
* @return theme info
|
||||
*/
|
||||
@Override
|
||||
public ThemeProperty upload(MultipartFile file) {
|
||||
Assert.notNull(file, "Multipart file must not be null");
|
||||
|
@ -346,7 +327,7 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
file.transferTo(uploadPath);
|
||||
|
||||
// Unzip theme package
|
||||
ZipUtil.unzip(uploadPath.toFile(),uploadPath.getParent().toFile());
|
||||
ZipUtil.unzip(uploadPath.toFile(), uploadPath.getParent().toFile());
|
||||
|
||||
// Delete theme package
|
||||
FileUtil.del(uploadPath.toFile());
|
||||
|
@ -360,6 +341,36 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThemeProperty add(Path themeTmpPath) throws IOException {
|
||||
Assert.notNull(themeTmpPath, "Theme temporary path must not be null");
|
||||
Assert.isTrue(Files.isDirectory(themeTmpPath), "Theme temporary path must be a directory");
|
||||
|
||||
// Check property config
|
||||
Path configPath = getThemePropertyPathOfNullable(themeTmpPath).orElseThrow(() -> new ThemePropertyMissingException("Theme property file is dismiss").setErrorData(themeTmpPath));
|
||||
|
||||
ThemeProperty tmpThemeProperty = getProperty(configPath);
|
||||
|
||||
// Copy the temporary path to current theme folder
|
||||
Path targetThemePath = workDir.resolve(tmpThemeProperty.getId());
|
||||
FileUtils.copyFolder(themeTmpPath, targetThemePath);
|
||||
|
||||
// Delete temp theme folder
|
||||
FileUtils.deleteFolder(themeTmpPath);
|
||||
|
||||
// Get property again
|
||||
return getProperty(targetThemePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set activated theme id.
|
||||
*
|
||||
* @param themeId theme id
|
||||
*/
|
||||
private void setActivatedThemeId(@Nullable String themeId) {
|
||||
this.activatedThemeId = themeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists theme files as tree view.
|
||||
*
|
||||
|
@ -446,8 +457,14 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Path getPropertyPath(@NonNull Path themePath) {
|
||||
/**
|
||||
* Gets property path of nullable.
|
||||
*
|
||||
* @param themePath theme path.
|
||||
* @return an optional property path
|
||||
*/
|
||||
@NonNull
|
||||
private Optional<Path> getThemePropertyPathOfNullable(@NonNull Path themePath) {
|
||||
Assert.notNull(themePath, "Theme path must not be null");
|
||||
|
||||
for (String propertyPathName : THEME_PROPERTY_FILE_NAMES) {
|
||||
|
@ -456,28 +473,28 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
log.debug("Attempting to find property file: [{}]", propertyPath);
|
||||
if (Files.exists(propertyPath) && Files.isReadable(propertyPath)) {
|
||||
log.debug("Found property file: [{}]", propertyPath);
|
||||
return propertyPath;
|
||||
return Optional.of(propertyPath);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets theme property.
|
||||
* Gets property path of non null.
|
||||
*
|
||||
* @param themePath must not be null
|
||||
* @return theme property
|
||||
* @param themePath theme path.
|
||||
* @return property path won't be null
|
||||
*/
|
||||
@NonNull
|
||||
private ThemeProperty getProperty(@NonNull Path themePath) {
|
||||
private Path getThemePropertyPath(@NonNull Path themePath) {
|
||||
return getThemePropertyPathOfNullable(themePath).orElseThrow(() -> new ThemePropertyMissingException(themePath + " dose not exist any theme property file").setErrorData(themePath));
|
||||
}
|
||||
|
||||
private Optional<ThemeProperty> getPropertyOfNullable(Path themePath) {
|
||||
Assert.notNull(themePath, "Theme path must not be null");
|
||||
|
||||
Path propertyPath = getPropertyPath(themePath);
|
||||
|
||||
if (propertyPath == null) {
|
||||
throw new ThemePropertyMissingException(themePath + " dose not exist any theme property file").setErrorData(themePath);
|
||||
}
|
||||
Path propertyPath = getThemePropertyPath(themePath);
|
||||
|
||||
try {
|
||||
// Get property content
|
||||
|
@ -504,10 +521,24 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
themeProperty.setActivated(true);
|
||||
}
|
||||
|
||||
return themeProperty;
|
||||
return Optional.of(themeProperty);
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new ThemePropertyMissingException("Cannot resolve theme property", e).setErrorData(propertyPath.toString());
|
||||
log.error("Failed to load theme property file", e);
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets theme property.
|
||||
*
|
||||
* @param themePath must not be null
|
||||
* @return theme property
|
||||
*/
|
||||
@NonNull
|
||||
private ThemeProperty getProperty(@NonNull Path themePath) {
|
||||
return getPropertyOfNullable(themePath).orElseThrow(() -> new ThemePropertyMissingException("Cannot resolve theme property").setErrorData(themePath));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -517,6 +548,7 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
* @return screenshots file name or null if the given theme path has not screenshots
|
||||
* @throws IOException throws when listing files
|
||||
*/
|
||||
@NonNull
|
||||
private Optional<String> getScreenshotsFileName(@NonNull Path themePath) throws IOException {
|
||||
Assert.notNull(themePath, "Theme path must not be null");
|
||||
|
||||
|
|
|
@ -3,9 +3,11 @@ package run.halo.app.utils;
|
|||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* File utilities.
|
||||
|
@ -46,4 +48,18 @@ public class FileUtils {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes folder recursively.
|
||||
*
|
||||
* @param deletingPath deleting path must not be null
|
||||
*/
|
||||
public static void deleteFolder(Path deletingPath) throws IOException {
|
||||
Assert.notNull(deletingPath, "Deleting path must not be null");
|
||||
|
||||
Files.walk(deletingPath)
|
||||
.sorted(Comparator.reverseOrder())
|
||||
.map(Path::toFile)
|
||||
.forEach(File::delete);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue