🍎 新增自动备份

每天1点备份所有资源
pull/18/head
ruibaby 2018-06-05 10:57:09 +08:00
parent 3c1f251b88
commit 86d0eee96e
4 changed files with 92 additions and 150 deletions

View File

@ -7,6 +7,7 @@ import cc.ryanc.halo.service.AttachmentService;
import cc.ryanc.halo.service.OptionsService;
import cc.ryanc.halo.utils.HaloUtils;
import cc.ryanc.halo.web.controller.core.BaseController;
import cn.hutool.cron.CronUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
@ -38,6 +39,9 @@ public class StartupConfig implements ApplicationListener<ContextRefreshedEvent>
this.loadOptions();
this.loadFiles();
this.loadThemes();
//启动定时任务
CronUtil.start();
log.info("定时任务启动成功!");
}
/**

View File

@ -8,6 +8,7 @@ import cc.ryanc.halo.model.dto.JsonResult;
import cc.ryanc.halo.service.MailService;
import cc.ryanc.halo.service.PostService;
import cc.ryanc.halo.utils.HaloUtils;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import lombok.extern.slf4j.Slf4j;
@ -23,6 +24,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -52,13 +54,19 @@ public class BackupController {
* @return admin/admin_backup
*/
@GetMapping
public String backup(Model model) {
List<BackupDto> resourcesBackup = HaloUtils.getBackUps("resources");
List<BackupDto> databasesBackup = HaloUtils.getBackUps("databases");
List<BackupDto> postsBackup = HaloUtils.getBackUps("posts");
model.addAttribute("resourcesBackup", resourcesBackup);
model.addAttribute("databasesBackup", databasesBackup);
model.addAttribute("postsBackup", postsBackup);
public String backup(@RequestParam(value = "type",defaultValue = "resources") String type,Model model) {
List<BackupDto> backups = null;
if(StringUtils.equals(type,"resources")){
backups = HaloUtils.getBackUps("resources");
}else if(StringUtils.equals(type,"databases")){
backups = HaloUtils.getBackUps("databases");
}else if(StringUtils.equals(type,"posts")){
backups = HaloUtils.getBackUps("posts");
}else{
backups = new ArrayList<>();
}
model.addAttribute("backups", backups);
model.addAttribute("type", type);
return "admin/admin_backup";
}
@ -73,7 +81,7 @@ public class BackupController {
public JsonResult doBackup(@RequestParam("type") String type) {
if (StringUtils.equals("resources", type)) {
return this.backupResources();
} else if (StringUtils.equals("db", type)) {
} else if (StringUtils.equals("databases", type)) {
return this.backupDatabase();
} else if (StringUtils.equals("posts", type)) {
return this.backupPosts();
@ -89,9 +97,14 @@ public class BackupController {
*/
public JsonResult backupDatabase() {
try {
String srcPath = System.getProperties().getProperty("user.home") + "/halo";
if(HaloUtils.getBackUps("databases").size()>10){
FileUtil.del(System.getProperties().getProperty("user.home") + "/halo/backup/databases/");
}
String srcPath = System.getProperties().getProperty("user.home") + "/halo/";
String distName = "databases_backup_" + HaloUtils.getStringDate("yyyyMMddHHmmss");
ZipUtil.zip(srcPath + "/halo.mv.db", System.getProperties().getProperty("user.home") + "/halo/backup/databases/" + distName + ".zip");
//压缩文件
ZipUtil.zip(srcPath + "halo.mv.db", System.getProperties().getProperty("user.home") + "/halo/backup/databases/" + distName + ".zip");
log.info("当前时间:"+DateUtil.now()+",执行了数据库备份。");
return new JsonResult(1, "备份成功!");
} catch (Exception e) {
log.error("未知错误:", e.getMessage());
@ -106,11 +119,15 @@ public class BackupController {
*/
public JsonResult backupResources() {
try {
if(HaloUtils.getBackUps("resources").size()>10){
FileUtil.del(System.getProperties().getProperty("user.home") + "/halo/backup/resources/");
}
File path = new File(ResourceUtils.getURL("classpath:").getPath());
String srcPath = path.getAbsolutePath();
String distName = "resources_backup_" + HaloUtils.getStringDate("yyyyMMddHHmmss");
//执行打包
ZipUtil.zip(srcPath, System.getProperties().getProperty("user.home") + "/halo/backup/resources/" + distName + ".zip");
log.info("当前时间:"+DateUtil.now()+",执行了资源文件备份。");
return new JsonResult(1, "备份成功!");
} catch (Exception e) {
e.printStackTrace();
@ -127,6 +144,9 @@ public class BackupController {
List<Post> posts = postService.findAllPosts(HaloConst.POST_TYPE_POST);
posts.addAll(postService.findAllPosts(HaloConst.POST_TYPE_PAGE));
try {
if(HaloUtils.getBackUps("posts").size()>10){
FileUtil.del(System.getProperties().getProperty("user.home") + "/halo/backup/posts/");
}
//打包好的文件名
String distName = "posts_backup_" + HaloUtils.getStringDate("yyyyMMddHHmmss");
String srcPath = System.getProperties().getProperty("user.home") + "/halo/backup/posts/" + distName;
@ -134,8 +154,9 @@ public class BackupController {
HaloUtils.postToFile(post.getPostContentMd(), srcPath, post.getPostTitle() + ".md");
}
//打包导出好的文章
ZipUtil.zip(srcPath, System.getProperties().getProperty("user.home") + "/halo/backup/posts/" + distName + ".zip");
ZipUtil.zip(srcPath, srcPath + ".zip");
FileUtil.del(srcPath);
log.info("当前时间:"+DateUtil.now()+",执行了文章备份。");
return new JsonResult(1, "备份成功!");
} catch (Exception e) {
e.printStackTrace();

View File

@ -0,0 +1,3 @@
cc.ryanc.halo.web.controller.admin.BackupController.backupResources = 0 0 1 * * ?
cc.ryanc.halo.web.controller.admin.BackupController.backupDatabase = 0 0 1 * * ?
cc.ryanc.halo.web.controller.admin.BackupController.backupPosts = 0 0 1 * * ?

View File

@ -6,6 +6,9 @@
<!-- 菜单栏模块 -->
<#include "module/_sidebar.ftl">
<div class="content-wrapper">
<style type="text/css" rel="stylesheet">
.resourceType,.databaseType,.postType{list-style:none;float:left;margin:0;padding-bottom:10px}
</style>
<section class="content-header">
<h1 style="display: inline-block;">博客备份</h1>
<ol class="breadcrumb">
@ -18,143 +21,57 @@
</section>
<section class="content container-fluid">
<div class="row">
<div class="col-md-12">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li class="active">
<a href="#resources" data-toggle="tab">资源目录备份</a>
</li>
<li>
<a href="#database" data-toggle="tab">数据库备份</a>
</li>
<li>
<a href="#post" data-toggle="tab">文章备份</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="resources">
<form method="post" class="form-horizontal" id="resourcesBackup">
<div class="box-body table-responsive" style="padding: 10px 0;">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>文件名称</th>
<th>备份时间</th>
<th>文件大小</th>
<th>文件类型</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<#if resourcesBackup?size gt 0>
<#list resourcesBackup as resource>
<tr>
<td>${resource.fileName}</td>
<td>${resource.createAt?string("yyyy-MM-dd HH:mm")}</td>
<td>${resource.fileSize}</td>
<td>${resource.fileType}</td>
<td>
<a href="/backup/resources/${resource.fileName}" class="btn btn-xs btn-primary" download="${resource.fileName}">下载</a>
<button type="button" class="btn btn-xs btn-info" onclick="sendToEmail('${resource.fileName}','${resource.backupType}')">发送到邮箱</button>
<button type="button" class="btn btn-xs btn-danger" onclick="delBackup('${resource.fileName}','${resource.backupType}')">删除</button>
</td>
</tr>
</#list>
<#else>
<tr>
<td colspan="5" style="text-align: center">暂无备份</td>
</tr>
</#if>
</tbody>
</table>
</div>
<div class="box-footer">
<button type="button" class="btn btn-primary btn-sm " onclick="btn_backup('resources')">备份</button>
</div>
</form>
</div>
<div class="tab-pane" id="database">
<form method="post" class="form-horizontal" id="databaseBackup">
<div class="box-body table-responsive" style="padding: 10px 0;">
<table class="table table-bordered table-hover">
<thead>
<div class="col-xs-12">
<ul style="list-style: none;padding-left: 0">
<li class="resourceType">
<a data-pjax="true" href="/admin/backup?type=resources" <#if type=='resources'>style="color: #000" </#if>>资源文件备份</a>&nbsp;|&nbsp;
</li>
<li class="databaseType">
<a data-pjax="true" href="/admin/backup?type=databases" <#if type=='databases'>style="color: #000" </#if>>数据库备份</a>&nbsp;|&nbsp;
</li>
<li class="postType">
<a data-pjax="true" href="/admin/backup?type=posts" <#if type=='posts'>style="color: #000" </#if>>文章备份</a>
</li>
</ul>
</div>
<div class="col-xs-12">
<div class="box box-primary">
<div class="box-body table-responsive">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>文件名称</th>
<th>备份时间</th>
<th>文件大小</th>
<th>文件类型</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<#if backups?size gt 0>
<#list backups as backup>
<tr>
<th>文件名称</th>
<th>备份时间</th>
<th>文件大小</th>
<th>文件类型</th>
<th>操作</th>
<td>${backup.fileName}</td>
<td>${backup.createAt?string("yyyy-MM-dd HH:mm")}</td>
<td>${backup.fileSize}</td>
<td>${backup.fileType}</td>
<td>
<a href="/backup/${type}/${backup.fileName}" class="btn btn-xs btn-primary" download="${backup.fileName}">下载</a>
<button type="button" class="btn btn-xs btn-info" onclick="sendToEmail('${backup.fileName}','${backup.backupType}')">发送到邮箱</button>
<button type="button" class="btn btn-xs btn-danger" onclick="delBackup('${backup.fileName}','${backup.backupType}')">删除</button>
</td>
</tr>
</thead>
<tbody>
<#if databasesBackup?size gt 0>
<#list databasesBackup as database>
<tr>
<td>${database.fileName}</td>
<td>${database.createAt?string("yyyy-MM-dd HH:mm")}</td>
<td>${database.fileSize}</td>
<td>${database.fileType}</td>
<td>
<a href="/backup/databases/${database.fileName}" class="btn btn-xs btn-primary" download="${database.fileName}">下载</a>
<button type="button" class="btn btn-xs btn-info" onclick="sendToEmail('${database.fileName}','${database.backupType}')">发送到邮箱</button>
<button type="button" class="btn btn-xs btn-danger" onclick="delBackup('${database.fileName}','${database.backupType}')">删除</button>
</td>
</tr>
</#list>
<#else>
<tr>
<td colspan="5" style="text-align: center">暂无备份</td>
</tr>
</#if>
</tbody>
</table>
</div>
<div class="box-footer">
<button type="button" class="btn btn-primary btn-sm " onclick="btn_backup('db')">备份</button>
</div>
</form>
</div>
<div class="tab-pane" id="post">
<form method="post" class="form-horizontal" id="postBackup">
<div class="box-body table-responsive" style="padding: 10px 0;">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>文件名称</th>
<th>备份时间</th>
<th>文件大小</th>
<th>文件类型</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<#if postsBackup?size gt 0>
<#list postsBackup as post>
<tr>
<td>${post.fileName}</td>
<td>${post.createAt?string("yyyy-MM-dd HH:mm")}</td>
<td>${post.fileSize}</td>
<td>${post.fileType}</td>
<td>
<a href="/backup/posts/${post.fileName}" class="btn btn-xs btn-primary" download="${post.fileName}">下载</a>
<button type="button" class="btn btn-xs btn-info" onclick="sendToEmail('${post.fileName}','${post.backupType}')">发送到邮箱</button>
<button type="button" class="btn btn-xs btn-danger" onclick="delBackup('${post.fileName}','${post.backupType}')">删除</button>
</td>
</tr>
</#list>
<#else>
<tr>
<td colspan="5" style="text-align: center">暂无备份</td>
</tr>
</#if>
</tbody>
</table>
</div>
<div class="box-footer">
<button type="button" class="btn btn-primary btn-sm " onclick="btn_backup('posts')">备份</button>
</div>
</form>
</div>
</#list>
<#else>
<tr>
<th colspan="5" style="text-align: center">暂无备份</th>
</tr>
</#if>
</tbody>
</table>
</div>
<div class="box-footer clearfix">
<button type="button" class="btn btn-primary btn-sm " onclick="btn_backup('${type}')">备份</button>
</div>
</div>
</div>
@ -238,10 +155,7 @@
position: 'top-center',
textAlign: 'left',
loader: true,
loaderBg: '#ffffff',
afterHidden: function () {
window.location.reload();
}
loaderBg: '#ffffff'
});
}else{
$.toast({