diff --git a/src/main/java/run/halo/app/controller/admin/api/AdminController.java b/src/main/java/run/halo/app/controller/admin/api/AdminController.java index 0522cd44d..df3a38b21 100644 --- a/src/main/java/run/halo/app/controller/admin/api/AdminController.java +++ b/src/main/java/run/halo/app/controller/admin/api/AdminController.java @@ -62,13 +62,16 @@ public class AdminController { @PostMapping("password/code") @ApiOperation("Sends reset password verify code") + @CacheLock(autoDelete = false) + @DisableOnCondition public void sendResetCode(@RequestBody @Valid ResetPasswordParam param) { adminService.sendResetPasswordCode(param); } @PutMapping("password/reset") - @DisableOnCondition @ApiOperation("Resets password by verify code") + @CacheLock(autoDelete = false) + @DisableOnCondition public void resetPassword(@RequestBody @Valid ResetPasswordParam param) { adminService.resetPasswordByCode(param); } @@ -95,32 +98,35 @@ public class AdminController { @PutMapping("halo-admin") @ApiOperation("Updates halo-admin manually") + @Deprecated public void updateAdmin() { adminService.updateAdminAssets(); } @GetMapping("spring/application.yaml") @ApiOperation("Gets application config content") + @DisableOnCondition public BaseResponse getSpringApplicationConfig() { return BaseResponse.ok(HttpStatus.OK.getReasonPhrase(), adminService.getApplicationConfig()); } @PutMapping("spring/application.yaml") - @DisableOnCondition @ApiOperation("Updates application config content") + @DisableOnCondition public void updateSpringApplicationConfig(@RequestParam(name = "content") String content) { adminService.updateApplicationConfig(content); } @PostMapping(value = {"halo/restart", "spring/restart"}) - @DisableOnCondition @ApiOperation("Restarts halo server") + @DisableOnCondition public void restartApplication() { Application.restart(); } @GetMapping(value = "halo/logfile") @ApiOperation("Gets halo log file content") + @DisableOnCondition public BaseResponse getLogFiles(@RequestParam("lines") Long lines) { return BaseResponse.ok(HttpStatus.OK.getReasonPhrase(), adminService.getLogFiles(lines)); } diff --git a/src/main/java/run/halo/app/controller/admin/api/BackupController.java b/src/main/java/run/halo/app/controller/admin/api/BackupController.java index 451a97503..8f70a88c6 100644 --- a/src/main/java/run/halo/app/controller/admin/api/BackupController.java +++ b/src/main/java/run/halo/app/controller/admin/api/BackupController.java @@ -1,26 +1,20 @@ package run.halo.app.controller.admin.api; -import cn.hutool.core.util.ZipUtil; +import cn.hutool.core.date.DateUtil; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.time.DateFormatUtils; -import org.json.JSONObject; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; -import run.halo.app.exception.FileOperationException; +import run.halo.app.model.annotation.DisableOnCondition; import run.halo.app.model.dto.BackupDTO; import run.halo.app.model.dto.post.BasePostDetailDTO; import run.halo.app.service.BackupService; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.util.Date; import java.util.List; @@ -44,6 +38,7 @@ public class BackupController { @PostMapping("halo") @ApiOperation("Backups halo") + @DisableOnCondition public BackupDTO backupHalo() { return backupService.zipWorkDirectory(); } @@ -56,6 +51,7 @@ public class BackupController { @GetMapping("halo/{fileName:.+}") @ApiOperation("Downloads backup file") + @DisableOnCondition public ResponseEntity downloadBackup(@PathVariable("fileName") String fileName, HttpServletRequest request) { log.info("Try to download backup file: [{}]", fileName); @@ -79,6 +75,7 @@ public class BackupController { @DeleteMapping("halo") @ApiOperation("Deletes a backup") + @DisableOnCondition public void deleteBackup(@RequestParam("filename") String filename) { backupService.deleteHaloBackup(filename); } @@ -89,48 +86,17 @@ public class BackupController { return backupService.importMarkdown(file); } - @GetMapping("export/hexo") - @ApiOperation("export hexo markdown") - public void exportMarkdowns(HttpServletResponse response) { - final String tmpDir = System.getProperty("java.io.tmpdir"); - final String date = DateFormatUtils.format(new Date(), "yyyyMMddHHmmss"); - String localFilePath = tmpDir + File.separator + "halo-markdown-" + date; - log.trace(localFilePath); - final File localFile = new File(localFilePath); - final File postDir = new File(localFilePath + File.separator + "posts"); - final File passwordDir = new File(localFilePath + File.separator + "passwords"); - final File draftDir = new File(localFilePath + File.separator + "drafts"); - try { - if (!postDir.mkdirs()) { - throw new Exception("Create dir [" + postDir.getPath() + "] failed"); - } - if (!passwordDir.mkdirs()) { - throw new Exception("Create dir [" + passwordDir.getPath() + "] failed"); - } - if (!draftDir.mkdirs()) { - throw new Exception("Create dir [" + draftDir.getPath() + "] failed"); - } - final JSONObject result = backupService.exportHexoMDs(); - final List posts = (List) result.opt("posts"); - backupService.exportHexoMd(posts, postDir.getPath()); - final List passwords = (List) result.opt("passwords"); - backupService.exportHexoMd(passwords, passwordDir.getPath()); - final List drafts = (List) result.opt("drafts"); - backupService.exportHexoMd(drafts, draftDir.getPath()); + @GetMapping("export/data") + @DisableOnCondition + public ResponseEntity exportData() { - final File zipFile = ZipUtil.zip(localFile); - byte[] zipData; - try (final FileInputStream inputStream = new FileInputStream(zipFile)) { - zipData = IOUtils.toByteArray(inputStream); - response.setContentType("application/zip"); - final String fileName = "halo-markdown-" + date + ".zip"; - response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); - } + String contentType = "application/octet-stream;charset=UTF-8"; - response.getOutputStream().write(zipData); - } catch (final Exception e) { - log.error("Export failed", e); - throw new FileOperationException("文章导出失败", e); - } + String filename = "halo-data-" + DateUtil.format(new Date(), "yyyy-MM-dd-HH-mm-ss.json"); + + return ResponseEntity.ok() + .contentType(MediaType.parseMediaType(contentType)) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"") + .body(backupService.exportData().toJSONString()); } } diff --git a/src/main/java/run/halo/app/controller/admin/api/DataProcessController.java b/src/main/java/run/halo/app/controller/admin/api/DataProcessController.java index fccf379c5..b98f6fee2 100644 --- a/src/main/java/run/halo/app/controller/admin/api/DataProcessController.java +++ b/src/main/java/run/halo/app/controller/admin/api/DataProcessController.java @@ -23,18 +23,18 @@ public class DataProcessController { this.themeSettingService = themeSettingService; } - @PutMapping("url/replace") - @ApiOperation("Replace url in all table.") - public void replaceUrl(@RequestParam("oldUrl") String oldUrl, - @RequestParam("newUrl") String newUrl) { - dataProcessService.replaceAllUrl(oldUrl, newUrl); - } - - @DeleteMapping("themes/settings/inactivated") - @ApiOperation("Delete inactivated theme settings.") - public void deleteInactivatedThemeSettings() { - themeSettingService.deleteInactivated(); - } +// @PutMapping("url/replace") +// @ApiOperation("Replace url in all table.") +// public void replaceUrl(@RequestParam("oldUrl") String oldUrl, +// @RequestParam("newUrl") String newUrl) { +// dataProcessService.replaceAllUrl(oldUrl, newUrl); +// } +// +// @DeleteMapping("themes/settings/inactivated") +// @ApiOperation("Delete inactivated theme settings.") +// public void deleteInactivatedThemeSettings() { +// themeSettingService.deleteInactivated(); +// } @DeleteMapping("tags/unused") @ApiOperation("Delete unused tags") diff --git a/src/main/java/run/halo/app/controller/admin/api/InstallController.java b/src/main/java/run/halo/app/controller/admin/api/InstallController.java index 3b547726c..84ef913cc 100644 --- a/src/main/java/run/halo/app/controller/admin/api/InstallController.java +++ b/src/main/java/run/halo/app/controller/admin/api/InstallController.java @@ -164,6 +164,12 @@ public class InstallController { return null; } + long commentCount = postCommentService.count(); + + if (commentCount > 0) { + return null; + } + PostComment comment = new PostComment(); comment.setAuthor("Halo"); comment.setAuthorUrl("https://halo.run"); @@ -175,7 +181,9 @@ public class InstallController { @Nullable private PostDetailVO createDefaultPostIfAbsent(@Nullable Category category) { + long publishedCount = postService.countByStatus(PostStatus.PUBLISHED); + if (publishedCount > 0) { return null; } @@ -210,6 +218,11 @@ public class InstallController { @Nullable private void createDefaultSheet() { + long publishedCount = sheetService.countByStatus(PostStatus.PUBLISHED); + if (publishedCount > 0) { + return; + } + SheetParam sheetParam = new SheetParam(); sheetParam.setSlug("about"); sheetParam.setTitle("关于页面"); @@ -261,10 +274,19 @@ public class InstallController { properties.put(PrimaryProperties.IS_INSTALLED, Boolean.TRUE.toString()); properties.put(BlogProperties.BLOG_LOCALE, installParam.getLocale()); properties.put(BlogProperties.BLOG_TITLE, installParam.getTitle()); - properties.put(BlogProperties.BLOG_URL, StringUtils.isBlank(installParam.getUrl()) ? - optionService.getBlogBaseUrl() : installParam.getUrl()); - properties.put(PrimaryProperties.BIRTHDAY, String.valueOf(System.currentTimeMillis())); - properties.put(OtherProperties.GLOBAL_ABSOLUTE_PATH_ENABLED, Boolean.FALSE.toString()); + properties.put(BlogProperties.BLOG_URL, StringUtils.isBlank(installParam.getUrl()) ? optionService.getBlogBaseUrl() : installParam.getUrl()); + + Long birthday = optionService.getByPropertyOrDefault(PrimaryProperties.BIRTHDAY, Long.class, 0L); + + if (birthday.equals(0L)) { + properties.put(PrimaryProperties.BIRTHDAY, String.valueOf(System.currentTimeMillis())); + } + + Boolean globalAbsolutePathEnabled = optionService.getByPropertyOrDefault(OtherProperties.GLOBAL_ABSOLUTE_PATH_ENABLED, Boolean.class, null); + + if (globalAbsolutePathEnabled == null) { + properties.put(OtherProperties.GLOBAL_ABSOLUTE_PATH_ENABLED, Boolean.FALSE.toString()); + } // Create properties optionService.saveProperties(properties); diff --git a/src/main/java/run/halo/app/controller/admin/api/MailController.java b/src/main/java/run/halo/app/controller/admin/api/MailController.java index e11c33354..a2b5405c8 100644 --- a/src/main/java/run/halo/app/controller/admin/api/MailController.java +++ b/src/main/java/run/halo/app/controller/admin/api/MailController.java @@ -6,6 +6,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import run.halo.app.mail.MailService; +import run.halo.app.model.annotation.DisableOnCondition; import run.halo.app.model.params.MailParam; import run.halo.app.model.support.BaseResponse; @@ -29,6 +30,7 @@ public class MailController { @PostMapping("test") @ApiOperation("Tests the SMTP service") + @DisableOnCondition public BaseResponse testMail(@Valid @RequestBody MailParam mailParam) { mailService.sendTextMail(mailParam.getTo(), mailParam.getSubject(), mailParam.getContent()); return BaseResponse.ok("已发送,请查收。若确认没有收到邮件,请检查服务器日志"); @@ -36,6 +38,7 @@ public class MailController { @PostMapping("test/connection") @ApiOperation("Test connection with email server") + @DisableOnCondition public BaseResponse testConnection() { mailService.testConnection(); return BaseResponse.ok("您和邮箱服务器的连接通畅"); diff --git a/src/main/java/run/halo/app/controller/admin/api/MigrateController.java b/src/main/java/run/halo/app/controller/admin/api/MigrateController.java index e8df6d20a..0e56e3cde 100644 --- a/src/main/java/run/halo/app/controller/admin/api/MigrateController.java +++ b/src/main/java/run/halo/app/controller/admin/api/MigrateController.java @@ -6,8 +6,11 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; +import run.halo.app.exception.BadRequestException; import run.halo.app.model.enums.MigrateType; +import run.halo.app.model.properties.PrimaryProperties; import run.halo.app.service.MigrateService; +import run.halo.app.service.OptionService; /** * Migrate controller @@ -21,25 +24,32 @@ public class MigrateController { private final MigrateService migrateService; - public MigrateController(MigrateService migrateService) { + private final OptionService optionService; + + public MigrateController(MigrateService migrateService, + OptionService optionService) { this.migrateService = migrateService; + this.optionService = optionService; } - @PostMapping("halo_v0_4_4") - @ApiOperation("Migrate from Halo 0.4.4") - public void migrateHaloOldVersion(@RequestPart("file") MultipartFile file) { - migrateService.migrate(file, MigrateType.OLD_VERSION); + @PostMapping("halo") + @ApiOperation("Migrate from Halo") + public void migrateHalo(@RequestPart("file") MultipartFile file) { + if (optionService.getByPropertyOrDefault(PrimaryProperties.IS_INSTALLED, Boolean.class, false)) { + throw new BadRequestException("无法在博客初始化完成之后迁移数据"); + } + migrateService.migrate(file, MigrateType.HALO); } - @PostMapping("wordpress") - @ApiOperation("Migrate from WordPress") - public void migrateWordPress(@RequestPart("file") MultipartFile file) { - migrateService.migrate(file, MigrateType.WORDPRESS); - } - - @PostMapping("cnblogs") - @ApiOperation("Migrate from cnblogs") - public void migrateCnBlogs(@RequestPart("file") MultipartFile file) { - migrateService.migrate(file, MigrateType.CNBLOGS); - } +// @PostMapping("wordpress") +// @ApiOperation("Migrate from WordPress") +// public void migrateWordPress(@RequestPart("file") MultipartFile file) { +// migrateService.migrate(file, MigrateType.WORDPRESS); +// } +// +// @PostMapping("cnblogs") +// @ApiOperation("Migrate from cnblogs") +// public void migrateCnBlogs(@RequestPart("file") MultipartFile file) { +// migrateService.migrate(file, MigrateType.CNBLOGS); +// } } diff --git a/src/main/java/run/halo/app/controller/admin/api/OptionController.java b/src/main/java/run/halo/app/controller/admin/api/OptionController.java index 6552b7aa3..c63b02888 100644 --- a/src/main/java/run/halo/app/controller/admin/api/OptionController.java +++ b/src/main/java/run/halo/app/controller/admin/api/OptionController.java @@ -44,8 +44,8 @@ public class OptionController { } @PostMapping("saving") - @DisableOnCondition @ApiOperation("Saves options") + @DisableOnCondition public void saveOptions(@Valid @RequestBody List optionParams) { optionService.save(optionParams); } @@ -78,30 +78,30 @@ public class OptionController { } @PostMapping - @DisableOnCondition @ApiOperation("Creates option") + @DisableOnCondition public void createBy(@RequestBody @Valid OptionParam optionParam) { optionService.save(optionParam); } @PutMapping("{optionId:\\d+}") - @DisableOnCondition @ApiOperation("Updates option") + @DisableOnCondition public void updateBy(@PathVariable("optionId") Integer optionId, @RequestBody @Valid OptionParam optionParam) { optionService.update(optionId, optionParam); } @DeleteMapping("{optionId:\\d+}") - @DisableOnCondition @ApiOperation("Deletes option") + @DisableOnCondition public void deletePermanently(@PathVariable("optionId") Integer optionId) { optionService.removePermanently(optionId); } @PostMapping("map_view/saving") - @DisableOnCondition @ApiOperation("Saves options by option map") + @DisableOnCondition public void saveOptionsWithMapView(@RequestBody Map optionMap) { optionService.save(optionMap); } diff --git a/src/main/java/run/halo/app/controller/admin/api/ThemeController.java b/src/main/java/run/halo/app/controller/admin/api/ThemeController.java index b3d79927f..f5474f8e8 100644 --- a/src/main/java/run/halo/app/controller/admin/api/ThemeController.java +++ b/src/main/java/run/halo/app/controller/admin/api/ThemeController.java @@ -6,6 +6,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import run.halo.app.handler.theme.config.support.Group; import run.halo.app.handler.theme.config.support.ThemeProperty; +import run.halo.app.model.annotation.DisableOnCondition; import run.halo.app.model.params.ThemeContentParam; import run.halo.app.model.support.BaseResponse; import run.halo.app.model.support.ThemeFile; @@ -75,12 +76,14 @@ public class ThemeController { @PutMapping("files/content") @ApiOperation("Updates template content") + @DisableOnCondition public void updateContentBy(@RequestBody ThemeContentParam param) { themeService.saveTemplateContent(param.getPath(), param.getContent()); } @PutMapping("{themeId}/files/content") @ApiOperation("Updates template content by theme id") + @DisableOnCondition public void updateContentBy(@PathVariable("themeId") String themeId, @RequestBody ThemeContentParam param) { themeService.saveTemplateContent(themeId, param.getPath(), param.getContent()); @@ -149,6 +152,7 @@ public class ThemeController { @DeleteMapping("{themeId}") @ApiOperation("Deletes a theme") + @DisableOnCondition public void deleteBy(@PathVariable("themeId") String themeId) { themeService.deleteTheme(themeId); } @@ -187,7 +191,7 @@ public class ThemeController { @GetMapping(value = "activation/template/exists") @ApiOperation("Determines if template exists") - public BaseResponse exists(@RequestParam(value = "template") String template) { + public BaseResponse exists(@RequestParam(value = "template") String template) { return BaseResponse.ok(themeService.templateExists(template)); } } diff --git a/src/main/java/run/halo/app/controller/admin/api/UserController.java b/src/main/java/run/halo/app/controller/admin/api/UserController.java index 8515a7bcd..05aa39555 100644 --- a/src/main/java/run/halo/app/controller/admin/api/UserController.java +++ b/src/main/java/run/halo/app/controller/admin/api/UserController.java @@ -38,6 +38,7 @@ public class UserController { @PutMapping("profiles") @ApiOperation("Updates user profile") + @DisableOnCondition public UserDTO updateProfile(@RequestBody UserParam userParam, User user) { // Validate the user param ValidationUtils.validate(userParam, UpdateCheck.class); @@ -50,9 +51,9 @@ public class UserController { } @PutMapping("profiles/password") - @DisableOnCondition @ApiOperation("Updates user's password") - public BaseResponse updatePassword(@RequestBody @Valid PasswordParam passwordParam, User user) { + @DisableOnCondition + public BaseResponse updatePassword(@RequestBody @Valid PasswordParam passwordParam, User user) { userService.updatePassword(passwordParam.getOldPassword(), passwordParam.getNewPassword(), user.getId()); return BaseResponse.ok("密码修改成功"); } diff --git a/src/main/java/run/halo/app/exception/RepeatTypeException.java b/src/main/java/run/halo/app/exception/RepeatTypeException.java index 75c76fab4..6c5b9aaae 100644 --- a/src/main/java/run/halo/app/exception/RepeatTypeException.java +++ b/src/main/java/run/halo/app/exception/RepeatTypeException.java @@ -2,6 +2,7 @@ package run.halo.app.exception; /** * repeat type exception + * * @author bestsort * @date 3/13/20 5:03 PM */ @@ -9,6 +10,7 @@ public class RepeatTypeException extends ServiceException { public RepeatTypeException(String message) { super(message); } + public RepeatTypeException(String message, Throwable cause) { super(message, cause); } diff --git a/src/main/java/run/halo/app/handler/file/FileHandler.java b/src/main/java/run/halo/app/handler/file/FileHandler.java index 020f5c871..f581809bc 100644 --- a/src/main/java/run/halo/app/handler/file/FileHandler.java +++ b/src/main/java/run/halo/app/handler/file/FileHandler.java @@ -75,6 +75,7 @@ public interface FileHandler { /** * Get attachment type is supported. + * * @return attachment type */ AttachmentType getAttachmentType(); diff --git a/src/main/java/run/halo/app/handler/file/FileHandlers.java b/src/main/java/run/halo/app/handler/file/FileHandlers.java index 0e043d3d5..210ef0c28 100644 --- a/src/main/java/run/halo/app/handler/file/FileHandlers.java +++ b/src/main/java/run/halo/app/handler/file/FileHandlers.java @@ -61,7 +61,7 @@ public class FileHandlers { public void delete(@NonNull Attachment attachment) { Assert.notNull(attachment, "Attachment must not be null"); getSupportedType(attachment.getType()) - .delete(attachment.getFileKey()); + .delete(attachment.getFileKey()); } /** diff --git a/src/main/java/run/halo/app/handler/migrate/HaloMigrateHandler.java b/src/main/java/run/halo/app/handler/migrate/HaloMigrateHandler.java new file mode 100644 index 000000000..d55495fe5 --- /dev/null +++ b/src/main/java/run/halo/app/handler/migrate/HaloMigrateHandler.java @@ -0,0 +1,36 @@ +package run.halo.app.handler.migrate; + +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; +import run.halo.app.model.enums.MigrateType; +import run.halo.app.service.BackupService; + +import java.io.IOException; + +/** + * @author ryanwang + * @date 2020-03-14 + */ +@Component +public class HaloMigrateHandler implements MigrateHandler { + + private final BackupService backupService; + + public HaloMigrateHandler(BackupService backupService) { + this.backupService = backupService; + } + + @Override + public void migrate(MultipartFile file) { + try { + backupService.importData(file); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public boolean supportType(MigrateType type) { + return MigrateType.HALO.equals(type); + } +} diff --git a/src/main/java/run/halo/app/handler/migrate/OldVersionMigrateHandler.java b/src/main/java/run/halo/app/handler/migrate/OldVersionMigrateHandler.java index 6d8b0e331..46d1c2979 100644 --- a/src/main/java/run/halo/app/handler/migrate/OldVersionMigrateHandler.java +++ b/src/main/java/run/halo/app/handler/migrate/OldVersionMigrateHandler.java @@ -688,6 +688,6 @@ public class OldVersionMigrateHandler implements MigrateHandler { @Override public boolean supportType(MigrateType type) { - return MigrateType.OLD_VERSION.equals(type); + return false; } } diff --git a/src/main/java/run/halo/app/mail/AbstractMailService.java b/src/main/java/run/halo/app/mail/AbstractMailService.java index e342e5cf3..8f9634e4c 100644 --- a/src/main/java/run/halo/app/mail/AbstractMailService.java +++ b/src/main/java/run/halo/app/mail/AbstractMailService.java @@ -55,6 +55,7 @@ public abstract class AbstractMailService implements MailService { /** * Test connection with email server. */ + @Override public void testConnection() { JavaMailSender javaMailSender = getMailSender(); if (javaMailSender instanceof JavaMailSenderImpl) { diff --git a/src/main/java/run/halo/app/model/entity/Attachment.java b/src/main/java/run/halo/app/model/entity/Attachment.java index acb4b0480..1ca0ea10e 100644 --- a/src/main/java/run/halo/app/model/entity/Attachment.java +++ b/src/main/java/run/halo/app/model/entity/Attachment.java @@ -4,6 +4,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import org.hibernate.annotations.ColumnDefault; +import org.hibernate.annotations.GenericGenerator; import run.halo.app.model.enums.AttachmentType; import javax.persistence.*; @@ -22,8 +23,8 @@ import javax.persistence.*; public class Attachment extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id") + @GenericGenerator(name = "custom-id", strategy = "run.halo.app.model.entity.support.CustomIdGenerator") private Integer id; /** diff --git a/src/main/java/run/halo/app/model/entity/BaseComment.java b/src/main/java/run/halo/app/model/entity/BaseComment.java index e211b94c9..4f10f9d4e 100644 --- a/src/main/java/run/halo/app/model/entity/BaseComment.java +++ b/src/main/java/run/halo/app/model/entity/BaseComment.java @@ -4,6 +4,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import org.hibernate.annotations.ColumnDefault; +import org.hibernate.annotations.GenericGenerator; import run.halo.app.model.enums.CommentStatus; import run.halo.app.utils.ServiceUtils; @@ -25,7 +26,8 @@ import javax.persistence.*; public class BaseComment extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id") + @GenericGenerator(name = "custom-id", strategy = "run.halo.app.model.entity.support.CustomIdGenerator") private Long id; /** diff --git a/src/main/java/run/halo/app/model/entity/BaseMeta.java b/src/main/java/run/halo/app/model/entity/BaseMeta.java index 4150e5040..6a42a8d2b 100644 --- a/src/main/java/run/halo/app/model/entity/BaseMeta.java +++ b/src/main/java/run/halo/app/model/entity/BaseMeta.java @@ -4,6 +4,7 @@ package run.halo.app.model.entity; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; @@ -23,7 +24,8 @@ import javax.persistence.*; public class BaseMeta extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id") + @GenericGenerator(name = "custom-id", strategy = "run.halo.app.model.entity.support.CustomIdGenerator") private Long id; /** diff --git a/src/main/java/run/halo/app/model/entity/BasePost.java b/src/main/java/run/halo/app/model/entity/BasePost.java index 80d4e657f..2b22b128c 100644 --- a/src/main/java/run/halo/app/model/entity/BasePost.java +++ b/src/main/java/run/halo/app/model/entity/BasePost.java @@ -4,6 +4,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import org.hibernate.annotations.ColumnDefault; +import org.hibernate.annotations.GenericGenerator; import run.halo.app.model.enums.PostEditorType; import run.halo.app.model.enums.PostStatus; @@ -25,7 +26,8 @@ import java.util.Date; public class BasePost extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id") + @GenericGenerator(name = "custom-id", strategy = "run.halo.app.model.entity.support.CustomIdGenerator") private Integer id; /** diff --git a/src/main/java/run/halo/app/model/entity/Category.java b/src/main/java/run/halo/app/model/entity/Category.java index 5926ea212..3ef46abce 100644 --- a/src/main/java/run/halo/app/model/entity/Category.java +++ b/src/main/java/run/halo/app/model/entity/Category.java @@ -4,6 +4,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import org.hibernate.annotations.ColumnDefault; +import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; @@ -24,7 +25,8 @@ import javax.persistence.*; public class Category extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id") + @GenericGenerator(name = "custom-id", strategy = "run.halo.app.model.entity.support.CustomIdGenerator") private Integer id; /** diff --git a/src/main/java/run/halo/app/model/entity/CommentBlackList.java b/src/main/java/run/halo/app/model/entity/CommentBlackList.java index f4e98dcf7..0b56153b8 100644 --- a/src/main/java/run/halo/app/model/entity/CommentBlackList.java +++ b/src/main/java/run/halo/app/model/entity/CommentBlackList.java @@ -1,6 +1,7 @@ package run.halo.app.model.entity; import lombok.*; +import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; import java.util.Date; @@ -20,7 +21,8 @@ import java.util.Date; @NoArgsConstructor public class CommentBlackList extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id") + @GenericGenerator(name = "custom-id", strategy = "run.halo.app.model.entity.support.CustomIdGenerator") private Long id; @Column(name = "ip_address", length = 127, nullable = false) diff --git a/src/main/java/run/halo/app/model/entity/Journal.java b/src/main/java/run/halo/app/model/entity/Journal.java index 91aa88332..226c8f168 100644 --- a/src/main/java/run/halo/app/model/entity/Journal.java +++ b/src/main/java/run/halo/app/model/entity/Journal.java @@ -4,6 +4,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import org.hibernate.annotations.ColumnDefault; +import org.hibernate.annotations.GenericGenerator; import run.halo.app.model.enums.JournalType; import javax.persistence.*; @@ -23,7 +24,8 @@ import javax.persistence.*; public class Journal extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id") + @GenericGenerator(name = "custom-id", strategy = "run.halo.app.model.entity.support.CustomIdGenerator") private Integer id; @Column(name = "source_content", nullable = false) diff --git a/src/main/java/run/halo/app/model/entity/Link.java b/src/main/java/run/halo/app/model/entity/Link.java index 18c0cd0d5..c0206b80b 100644 --- a/src/main/java/run/halo/app/model/entity/Link.java +++ b/src/main/java/run/halo/app/model/entity/Link.java @@ -4,6 +4,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import org.hibernate.annotations.ColumnDefault; +import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; @@ -21,8 +22,8 @@ import javax.persistence.*; public class Link extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id") + @GenericGenerator(name = "custom-id", strategy = "run.halo.app.model.entity.support.CustomIdGenerator") private Integer id; /** diff --git a/src/main/java/run/halo/app/model/entity/Log.java b/src/main/java/run/halo/app/model/entity/Log.java index 140e7e467..5513d9d23 100644 --- a/src/main/java/run/halo/app/model/entity/Log.java +++ b/src/main/java/run/halo/app/model/entity/Log.java @@ -4,6 +4,7 @@ package run.halo.app.model.entity; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import org.hibernate.annotations.GenericGenerator; import run.halo.app.model.enums.LogType; import javax.persistence.*; @@ -21,7 +22,8 @@ import javax.persistence.*; public class Log extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id") + @GenericGenerator(name = "custom-id", strategy = "run.halo.app.model.entity.support.CustomIdGenerator") private Long id; /** diff --git a/src/main/java/run/halo/app/model/entity/Menu.java b/src/main/java/run/halo/app/model/entity/Menu.java index 0886d3f93..ff1f28cc4 100644 --- a/src/main/java/run/halo/app/model/entity/Menu.java +++ b/src/main/java/run/halo/app/model/entity/Menu.java @@ -4,6 +4,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import org.hibernate.annotations.ColumnDefault; +import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; @@ -21,8 +22,8 @@ import javax.persistence.*; public class Menu extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id") + @GenericGenerator(name = "custom-id", strategy = "run.halo.app.model.entity.support.CustomIdGenerator") private Integer id; /** diff --git a/src/main/java/run/halo/app/model/entity/Option.java b/src/main/java/run/halo/app/model/entity/Option.java index 059edc616..63ae25eb8 100644 --- a/src/main/java/run/halo/app/model/entity/Option.java +++ b/src/main/java/run/halo/app/model/entity/Option.java @@ -5,6 +5,7 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.ToString; import org.hibernate.annotations.ColumnDefault; +import org.hibernate.annotations.GenericGenerator; import run.halo.app.model.enums.OptionType; import javax.persistence.*; @@ -25,7 +26,8 @@ import javax.persistence.*; public class Option extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id") + @GenericGenerator(name = "custom-id", strategy = "run.halo.app.model.entity.support.CustomIdGenerator") private Integer id; /** @@ -44,7 +46,8 @@ public class Option extends BaseEntity { /** * option value */ - @Column(name = "option_value", length = 1023, nullable = false) + @Column(name = "option_value", nullable = false) + @Lob private String value; public Option(String key, String value) { diff --git a/src/main/java/run/halo/app/model/entity/Photo.java b/src/main/java/run/halo/app/model/entity/Photo.java index b001982c6..5c7dc4ea1 100644 --- a/src/main/java/run/halo/app/model/entity/Photo.java +++ b/src/main/java/run/halo/app/model/entity/Photo.java @@ -3,6 +3,7 @@ package run.halo.app.model.entity; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; import java.util.Date; @@ -21,8 +22,8 @@ import java.util.Date; public class Photo extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id") + @GenericGenerator(name = "custom-id", strategy = "run.halo.app.model.entity.support.CustomIdGenerator") private Integer id; /** diff --git a/src/main/java/run/halo/app/model/entity/PostCategory.java b/src/main/java/run/halo/app/model/entity/PostCategory.java index ba7a43a3f..ee4182e9f 100644 --- a/src/main/java/run/halo/app/model/entity/PostCategory.java +++ b/src/main/java/run/halo/app/model/entity/PostCategory.java @@ -2,6 +2,7 @@ package run.halo.app.model.entity; import lombok.Data; import lombok.ToString; +import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; import java.util.Objects; @@ -20,7 +21,8 @@ import java.util.Objects; public class PostCategory extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id") + @GenericGenerator(name = "custom-id", strategy = "run.halo.app.model.entity.support.CustomIdGenerator") private Integer id; /** diff --git a/src/main/java/run/halo/app/model/entity/PostTag.java b/src/main/java/run/halo/app/model/entity/PostTag.java index 6e2f9f1fd..fd4e61b4a 100644 --- a/src/main/java/run/halo/app/model/entity/PostTag.java +++ b/src/main/java/run/halo/app/model/entity/PostTag.java @@ -2,6 +2,7 @@ package run.halo.app.model.entity; import lombok.Data; import lombok.ToString; +import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; import java.util.Objects; @@ -21,8 +22,8 @@ import java.util.Objects; public class PostTag extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id") + @GenericGenerator(name = "custom-id", strategy = "run.halo.app.model.entity.support.CustomIdGenerator") private Integer id; /** diff --git a/src/main/java/run/halo/app/model/entity/Tag.java b/src/main/java/run/halo/app/model/entity/Tag.java index a28d998f1..a63f9dcb3 100644 --- a/src/main/java/run/halo/app/model/entity/Tag.java +++ b/src/main/java/run/halo/app/model/entity/Tag.java @@ -3,6 +3,7 @@ package run.halo.app.model.entity; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; @@ -20,8 +21,8 @@ import javax.persistence.*; public class Tag extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id") + @GenericGenerator(name = "custom-id", strategy = "run.halo.app.model.entity.support.CustomIdGenerator") private Integer id; /** diff --git a/src/main/java/run/halo/app/model/entity/ThemeSetting.java b/src/main/java/run/halo/app/model/entity/ThemeSetting.java index cb3d9f0b6..586ea9070 100644 --- a/src/main/java/run/halo/app/model/entity/ThemeSetting.java +++ b/src/main/java/run/halo/app/model/entity/ThemeSetting.java @@ -3,6 +3,7 @@ package run.halo.app.model.entity; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; @@ -22,7 +23,8 @@ import javax.persistence.*; public class ThemeSetting extends BaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id") + @GenericGenerator(name = "custom-id", strategy = "run.halo.app.model.entity.support.CustomIdGenerator") private Integer id; /** @@ -35,6 +37,7 @@ public class ThemeSetting extends BaseEntity { * Setting value */ @Column(name = "setting_value", nullable = false) + @Lob private String value; /** diff --git a/src/main/java/run/halo/app/model/entity/support/CustomIdGenerator.java b/src/main/java/run/halo/app/model/entity/support/CustomIdGenerator.java new file mode 100644 index 000000000..3e3105e6e --- /dev/null +++ b/src/main/java/run/halo/app/model/entity/support/CustomIdGenerator.java @@ -0,0 +1,22 @@ +package run.halo.app.model.entity.support; + +import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.id.IdentityGenerator; +import run.halo.app.utils.ReflectionUtils; + +import java.io.Serializable; + +/** + * @author ryanwang + * @date 2020-03-16 + */ +public class CustomIdGenerator extends IdentityGenerator { + @Override + public Serializable generate(SharedSessionContractImplementor session, Object object) { + Object id = ReflectionUtils.getFieldValue("id", object); + if (id != null) { + return (Serializable) id; + } + return super.generate(session, object); + } +} diff --git a/src/main/java/run/halo/app/model/enums/MigrateType.java b/src/main/java/run/halo/app/model/enums/MigrateType.java index 74a952cc8..c38e3b5c2 100644 --- a/src/main/java/run/halo/app/model/enums/MigrateType.java +++ b/src/main/java/run/halo/app/model/enums/MigrateType.java @@ -9,9 +9,9 @@ package run.halo.app.model.enums; public enum MigrateType implements ValueEnum { /** - * Halo version 0.4.4 + * Halo */ - OLD_VERSION(0), + HALO(0), /** * WordPress diff --git a/src/main/java/run/halo/app/security/filter/AdminAuthenticationFilter.java b/src/main/java/run/halo/app/security/filter/AdminAuthenticationFilter.java index de743435f..3e3479d44 100644 --- a/src/main/java/run/halo/app/security/filter/AdminAuthenticationFilter.java +++ b/src/main/java/run/halo/app/security/filter/AdminAuthenticationFilter.java @@ -60,7 +60,7 @@ public class AdminAuthenticationFilter extends AbstractAuthenticationFilter { "/api/admin/login", "/api/admin/refresh/*", "/api/admin/installations", - "/api/admin/migrations/**", + "/api/admin/migrations/halo", "/api/admin/is_installed", "/api/admin/password/code", "/api/admin/password/reset" diff --git a/src/main/java/run/halo/app/service/BackupService.java b/src/main/java/run/halo/app/service/BackupService.java index cd12d1a05..2f9b98e9a 100644 --- a/src/main/java/run/halo/app/service/BackupService.java +++ b/src/main/java/run/halo/app/service/BackupService.java @@ -1,6 +1,6 @@ package run.halo.app.service; -import org.json.JSONObject; +import com.alibaba.fastjson.JSONObject; import org.springframework.core.io.Resource; import org.springframework.lang.NonNull; import org.springframework.web.multipart.MultipartFile; @@ -19,29 +19,14 @@ import java.util.List; public interface BackupService { /** - * Backup posts and sheets + * Import markdown content. * * @param file file - * @return post info + * @return base post detail dto + * @throws IOException throws IOException */ BasePostDetailDTO importMarkdown(MultipartFile file) throws IOException; - - /** - * export posts by hexo formatter - * - * @return json object - */ - JSONObject exportHexoMDs(); - - /** - * Exports the specified articles to the specified dir path. - * - * @param posts - * @param path - */ - void exportHexoMd(List posts, String path); - /** * Zips work directory. * @@ -74,4 +59,21 @@ public interface BackupService { */ @NonNull Resource loadFileAsResource(@NonNull String fileName); + + + /** + * Export all database's data. + * + * @return data + */ + @NonNull + JSONObject exportData(); + + /** + * Import data + * + * @param file file + * @throws IOException throws IOException + */ + void importData(MultipartFile file) throws IOException; } diff --git a/src/main/java/run/halo/app/service/CommentBlackListService.java b/src/main/java/run/halo/app/service/CommentBlackListService.java index 703cc91b7..17c7f3654 100644 --- a/src/main/java/run/halo/app/service/CommentBlackListService.java +++ b/src/main/java/run/halo/app/service/CommentBlackListService.java @@ -1,6 +1,8 @@ package run.halo.app.service; +import run.halo.app.model.entity.CommentBlackList; import run.halo.app.model.enums.CommentViolationTypeEnum; +import run.halo.app.service.base.CrudService; /** * Comment BlackList Service @@ -8,7 +10,7 @@ import run.halo.app.model.enums.CommentViolationTypeEnum; * @author Lei XinXin * @date 2020/1/3 */ -public interface CommentBlackListService { +public interface CommentBlackListService extends CrudService { /** * 评论封禁状态 * diff --git a/src/main/java/run/halo/app/service/ThemeSettingService.java b/src/main/java/run/halo/app/service/ThemeSettingService.java index f71c33973..f2f11de8c 100644 --- a/src/main/java/run/halo/app/service/ThemeSettingService.java +++ b/src/main/java/run/halo/app/service/ThemeSettingService.java @@ -4,6 +4,7 @@ import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; import org.springframework.transaction.annotation.Transactional; import run.halo.app.model.entity.ThemeSetting; +import run.halo.app.service.base.CrudService; import java.util.List; import java.util.Map; @@ -14,7 +15,7 @@ import java.util.Map; * @author johnniang * @date 2019-04-08 */ -public interface ThemeSettingService { +public interface ThemeSettingService extends CrudService { /** diff --git a/src/main/java/run/halo/app/service/impl/BackupServiceImpl.java b/src/main/java/run/halo/app/service/impl/BackupServiceImpl.java index a46e72cd2..e9765ae63 100644 --- a/src/main/java/run/halo/app/service/impl/BackupServiceImpl.java +++ b/src/main/java/run/halo/app/service/impl/BackupServiceImpl.java @@ -1,36 +1,31 @@ package run.halo.app.service.impl; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.IdUtil; +import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.time.DateFormatUtils; -import org.json.JSONObject; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; import org.springframework.lang.NonNull; import org.springframework.stereotype.Service; import org.springframework.util.Assert; import org.springframework.web.multipart.MultipartFile; -import org.yaml.snakeyaml.Yaml; 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.NotFoundException; import run.halo.app.exception.ServiceException; import run.halo.app.model.dto.BackupDTO; import run.halo.app.model.dto.post.BasePostDetailDTO; -import run.halo.app.model.entity.Post; -import run.halo.app.model.entity.Tag; -import run.halo.app.model.enums.PostStatus; +import run.halo.app.model.entity.*; import run.halo.app.model.support.HaloConst; import run.halo.app.security.service.OneTimeTokenService; -import run.halo.app.service.BackupService; -import run.halo.app.service.OptionService; -import run.halo.app.service.PostService; -import run.halo.app.service.PostTagService; +import run.halo.app.service.*; import run.halo.app.utils.HaloUtils; -import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.nio.charset.StandardCharsets; @@ -40,7 +35,8 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.*; +import java.util.Collections; +import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -59,26 +55,79 @@ public class BackupServiceImpl implements BackupService { private static final String LINE_SEPARATOR = System.getProperty("line.separator"); + private final AttachmentService attachmentService; + + private final CategoryService categoryService; + + private final CommentBlackListService commentBlackListService; + + private final JournalService journalService; + + private final JournalCommentService journalCommentService; + + private final LinkService linkService; + + private final LogService logService; + + private final MenuService menuService; + + private final OptionService optionService; + + private final PhotoService photoService; + private final PostService postService; + private final PostCategoryService postCategoryService; + + private final PostCommentService postCommentService; + + private final PostMetaService postMetaService; + private final PostTagService postTagService; - private final OptionService optionService; + private final SheetService sheetService; + + private final SheetCommentService sheetCommentService; + + private final SheetMetaService sheetMetaService; + + private final TagService tagService; + + private final ThemeSettingService themeSettingService; + + private final UserService userService; private final OneTimeTokenService oneTimeTokenService; private final HaloProperties haloProperties; - public BackupServiceImpl(PostService postService, - PostTagService postTagService, - OptionService optionService, - OneTimeTokenService oneTimeTokenService, - HaloProperties haloProperties) { - this.postService = postService; - this.postTagService = postTagService; + private final ApplicationEventPublisher eventPublisher; + + public BackupServiceImpl(AttachmentService attachmentService, CategoryService categoryService, CommentBlackListService commentBlackListService, JournalService journalService, JournalCommentService journalCommentService, LinkService linkService, LogService logService, MenuService menuService, OptionService optionService, PhotoService photoService, PostService postService, PostCategoryService postCategoryService, PostCommentService postCommentService, PostMetaService postMetaService, PostTagService postTagService, SheetService sheetService, SheetCommentService sheetCommentService, SheetMetaService sheetMetaService, TagService tagService, ThemeSettingService themeSettingService, UserService userService, OneTimeTokenService oneTimeTokenService, HaloProperties haloProperties, ApplicationEventPublisher eventPublisher) { + this.attachmentService = attachmentService; + this.categoryService = categoryService; + this.commentBlackListService = commentBlackListService; + this.journalService = journalService; + this.journalCommentService = journalCommentService; + this.linkService = linkService; + this.logService = logService; + this.menuService = menuService; this.optionService = optionService; + this.photoService = photoService; + this.postService = postService; + this.postCategoryService = postCategoryService; + this.postCommentService = postCommentService; + this.postMetaService = postMetaService; + this.postTagService = postTagService; + this.sheetService = sheetService; + this.sheetCommentService = sheetCommentService; + this.sheetMetaService = sheetMetaService; + this.tagService = tagService; + this.themeSettingService = themeSettingService; + this.userService = userService; this.oneTimeTokenService = oneTimeTokenService; this.haloProperties = haloProperties; + this.eventPublisher = eventPublisher; } /** @@ -105,66 +154,6 @@ public class BackupServiceImpl implements BackupService { return postService.importMarkdown(markdown, file.getOriginalFilename()); } - @Override - public JSONObject exportHexoMDs() { - final JSONObject ret = new JSONObject(); - final List posts = new ArrayList<>(); - ret.put("posts", (Object) posts); - final List passwords = new ArrayList<>(); - ret.put("passwords", (Object) passwords); - final List drafts = new ArrayList<>(); - ret.put("drafts", (Object) drafts); - - List postList = postService.listAll(); - Map> talMap = postTagService.listTagListMapBy(postList.stream().map(Post::getId).collect(Collectors.toList())); - for (Post post : postList) { - final Map front = new LinkedHashMap<>(); - final String title = post.getTitle(); - front.put("title", title); - final String date = DateFormatUtils.format(post.getCreateTime(), "yyyy-MM-dd HH:mm:ss"); - front.put("date", date); - front.put("updated", DateFormatUtils.format(post.getUpdateTime(), "yyyy-MM-dd HH:mm:ss")); - final List tags = talMap.get(post.getId()).stream().map(Tag::getName).collect(Collectors.toList()); - if (tags.isEmpty()) { - tags.add("halo"); - } - front.put("tags", tags); - front.put("permalink", ""); - final JSONObject one = new JSONObject(); - one.put("front", new Yaml().dump(front)); - one.put("title", title); - one.put("content", post.getOriginalContent()); - one.put("created", post.getCreateTime().getTime()); - - if (StringUtils.isNotBlank(post.getPassword())) { - passwords.add(one); - } else if (post.getStatus() == PostStatus.DRAFT) { - drafts.add(one); - } else { - posts.add(one); - } - } - - return ret; - } - - @Override - public void exportHexoMd(List posts, String dirPath) { - posts.forEach(post -> { - final String filename = sanitizeFilename(post.optString("title")) + ".md"; - final String text = post.optString("front") + "---" + LINE_SEPARATOR + post.optString("content"); - - try { - final String date = DateFormatUtils.format(post.optLong("created"), "yyyyMM"); - final String dir = dirPath + File.separator + date + File.separator; - new File(dir).mkdirs(); - FileUtils.writeStringToFile(new File(dir + filename), text, "UTF-8"); - } catch (final Exception e) { - log.error("Write markdown file failed", e); - } - }); - } - @Override public BackupDTO zipWorkDirectory() { // Zip work directory to temporary file @@ -268,6 +257,106 @@ public class BackupServiceImpl implements BackupService { } } + @Override + public JSONObject exportData() { + JSONObject data = new JSONObject(); + data.put("version", HaloConst.HALO_VERSION); + data.put("export_date", DateUtil.now()); + data.put("attachments", attachmentService.listAll()); + data.put("categories", categoryService.listAll()); + data.put("comment_black_list", commentBlackListService.listAll()); + data.put("journals", journalService.listAll()); + data.put("journal_comments", journalCommentService.listAll()); + data.put("links", linkService.listAll()); + data.put("logs", logService.listAll()); + data.put("menus", menuService.listAll()); + data.put("options", optionService.listAll()); + data.put("photos", photoService.listAll()); + data.put("posts", postService.listAll()); + data.put("post_categories", postCategoryService.listAll()); + data.put("post_comments", postCommentService.listAll()); + data.put("post_metas", postMetaService.listAll()); + data.put("post_tags", postTagService.listAll()); + data.put("sheets", sheetService.listAll()); + data.put("sheet_comments", sheetCommentService.listAll()); + data.put("sheet_metas", sheetMetaService.listAll()); + data.put("tags", tagService.listAll()); + data.put("theme_settings", themeSettingService.listAll()); + data.put("user", userService.listAll()); + return data; + } + + @Override + public void importData(MultipartFile file) throws IOException { + String jsonContent = IoUtil.read(file.getInputStream(), StandardCharsets.UTF_8); + + JSONObject data = JSONObject.parseObject(jsonContent); + + List attachments = data.getJSONArray("attachments").toJavaList(Attachment.class); + attachmentService.createInBatch(attachments); + + List categories = data.getJSONArray("categories").toJavaList(Category.class); + categoryService.createInBatch(categories); + + List tags = data.getJSONArray("tags").toJavaList(Tag.class); + tagService.createInBatch(tags); + + List commentBlackList = data.getJSONArray("comment_black_list").toJavaList(CommentBlackList.class); + commentBlackListService.createInBatch(commentBlackList); + + List journals = data.getJSONArray("journals").toJavaList(Journal.class); + journalService.createInBatch(journals); + + List journalComments = data.getJSONArray("journal_comments").toJavaList(JournalComment.class); + journalCommentService.createInBatch(journalComments); + + List links = data.getJSONArray("links").toJavaList(Link.class); + linkService.createInBatch(links); + + List logs = data.getJSONArray("logs").toJavaList(Log.class); + logService.createInBatch(logs); + + List menus = data.getJSONArray("menus").toJavaList(Menu.class); + menuService.createInBatch(menus); + + List