mirror of https://github.com/halo-dev/halo
Support update theme from new theme package.
parent
f70f7560ba
commit
648becf111
|
@ -117,13 +117,6 @@ public class ThemeController {
|
|||
themeSettingService.save(settings, themeId);
|
||||
}
|
||||
|
||||
@PutMapping("{themeId}")
|
||||
public ThemeProperty updateTheme(@PathVariable("themeId") String themeId,
|
||||
@RequestPart(name = "file", required = false) MultipartFile file) {
|
||||
|
||||
return themeService.update(themeId);
|
||||
}
|
||||
|
||||
@DeleteMapping("{themeId}")
|
||||
@ApiOperation("Deletes a theme")
|
||||
public void deleteBy(@PathVariable("themeId") String themeId) {
|
||||
|
@ -136,12 +129,25 @@ public class ThemeController {
|
|||
return themeService.upload(file);
|
||||
}
|
||||
|
||||
@PutMapping("upload/{themeId}")
|
||||
public ThemeProperty updateThemeByUpload(@PathVariable("themeId") String themeId,
|
||||
@RequestPart("file") MultipartFile file) {
|
||||
return themeService.update(themeId, file);
|
||||
}
|
||||
|
||||
@PostMapping("fetching")
|
||||
@ApiOperation("Fetches a new theme")
|
||||
public ThemeProperty fetchTheme(@RequestParam("uri") String uri) {
|
||||
return themeService.fetch(uri);
|
||||
}
|
||||
|
||||
@PutMapping("fetching/{themeId}")
|
||||
public ThemeProperty updateThemeByFetching(@PathVariable("themeId") String themeId,
|
||||
@RequestPart(name = "file", required = false) MultipartFile file) {
|
||||
|
||||
return themeService.update(themeId);
|
||||
}
|
||||
|
||||
@PostMapping("reload")
|
||||
@ApiOperation("Reloads themes")
|
||||
public void reload() {
|
||||
|
|
|
@ -24,6 +24,7 @@ public interface ThemeService {
|
|||
/**
|
||||
* Theme property file name.
|
||||
*/
|
||||
@Deprecated
|
||||
String THEME_PROPERTY_FILE_NAME = "theme.yaml";
|
||||
|
||||
/**
|
||||
|
@ -236,6 +237,7 @@ public interface ThemeService {
|
|||
*
|
||||
* @param themeTmpPath theme temporary path must not be null
|
||||
* @return theme property
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
@NonNull
|
||||
ThemeProperty add(@NonNull Path themeTmpPath) throws IOException;
|
||||
|
@ -262,4 +264,13 @@ public interface ThemeService {
|
|||
*/
|
||||
@NonNull
|
||||
ThemeProperty update(@NonNull String themeId);
|
||||
|
||||
/**
|
||||
* Updates theme by theme id.
|
||||
*
|
||||
* @param themeId theme id must not be blank
|
||||
* @param file multipart file must not be null
|
||||
* @return theme info
|
||||
*/
|
||||
ThemeProperty update(@NonNull String themeId, @NonNull MultipartFile file);
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
|
||||
@Override
|
||||
public ThemeProperty getThemeOfNonNullBy(String themeId) {
|
||||
return getThemeBy(themeId).orElseThrow(() -> new NotFoundException("Theme with id: " + themeId + " was not found").setErrorData(themeId));
|
||||
return getThemeBy(themeId).orElseThrow(() -> new NotFoundException("没有找到 id 为 " + themeId + " 的主题").setErrorData(themeId));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -487,6 +487,59 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
return getThemeOfNonNullBy(themeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ThemeProperty update(String themeId, MultipartFile file) {
|
||||
Assert.hasText(themeId, "Theme id must not be blank");
|
||||
Assert.notNull(themeId, "Theme file must not be blank");
|
||||
|
||||
if (!StringUtils.endsWithIgnoreCase(file.getOriginalFilename(), ".zip")) {
|
||||
throw new UnsupportedMediaTypeException("不支持的文件类型: " + file.getContentType()).setErrorData(file.getOriginalFilename());
|
||||
}
|
||||
|
||||
ThemeProperty updatingTheme = getThemeOfNonNullBy(themeId);
|
||||
|
||||
ZipInputStream zis = null;
|
||||
Path tempPath = null;
|
||||
|
||||
try {
|
||||
// Create temp directory
|
||||
tempPath = FileUtils.createTempDirectory();
|
||||
|
||||
String basename = FilenameUtils.getBasename(file.getOriginalFilename());
|
||||
Path themeTempPath = tempPath.resolve(basename);
|
||||
|
||||
// Check directory traversal
|
||||
FileUtils.checkDirectoryTraversal(tempPath, themeTempPath);
|
||||
|
||||
// New zip input stream
|
||||
zis = new ZipInputStream(file.getInputStream());
|
||||
|
||||
// Unzip to temp path
|
||||
FileUtils.unzip(zis, themeTempPath);
|
||||
|
||||
Path preparePath = FileUtils.tryToSkipZipParentFolder(themeTempPath);
|
||||
|
||||
ThemeProperty prepareThemeProperty = getProperty(preparePath);
|
||||
|
||||
if (!prepareThemeProperty.getId().equals(updatingTheme.getId())) {
|
||||
throw new ServiceException("上传的主题包不是该主题的更新包: " + file.getOriginalFilename());
|
||||
}
|
||||
|
||||
// Coping new theme files to old theme folder.
|
||||
FileUtils.copyFolder(preparePath, Paths.get(updatingTheme.getThemePath()));
|
||||
|
||||
// Gets theme property again.
|
||||
return getProperty(Paths.get(updatingTheme.getThemePath()));
|
||||
} catch (IOException e) {
|
||||
throw new ServiceException("更新主题失败: " + file.getOriginalFilename(), e);
|
||||
} finally {
|
||||
// Close zip input stream
|
||||
FileUtils.closeQuietly(zis);
|
||||
// Delete folder after testing
|
||||
FileUtils.deleteFolderQuietly(tempPath);
|
||||
}
|
||||
}
|
||||
|
||||
private void pullFromGit(@NonNull ThemeProperty themeProperty) throws IOException, GitAPIException, URISyntaxException {
|
||||
Assert.notNull(themeProperty, "Theme property must not be null");
|
||||
|
||||
|
@ -735,7 +788,7 @@ public class ThemeServiceImpl implements ThemeService {
|
|||
*/
|
||||
@NonNull
|
||||
private ThemeProperty getProperty(@NonNull Path themePath) {
|
||||
return getPropertyOfNullable(themePath).orElseThrow(() -> new ThemePropertyMissingException("该主题没有说明文件").setErrorData(themePath));
|
||||
return getPropertyOfNullable(themePath).orElseThrow(() -> new ThemePropertyMissingException(themePath + " 没有说明文件").setErrorData(themePath));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue