Commit 9068879a authored by Liang Ding's avatar Liang Ding

#12130

parent 14032878
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Description: Solo POM. Description: Solo POM.
Version: 3.11.1.24, Jul 11, 2016 Version: 3.12.1.24, Jul 27, 2016
Author: <a href="http://88250.b3log.org">Liang Ding</a> Author: <a href="http://88250.b3log.org">Liang Ding</a>
Author: <a href="http://www.annpeter.cn">Ann Peter</a> Author: <a href="http://www.annpeter.cn">Ann Peter</a>
--> -->
...@@ -106,7 +106,7 @@ ...@@ -106,7 +106,7 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<org.b3log.latke.version>2.2.7</org.b3log.latke.version> <org.b3log.latke.version>2.2.8</org.b3log.latke.version>
<servlet.version>3.1.0</servlet.version> <servlet.version>3.1.0</servlet.version>
<slf4j.version>1.7.5</slf4j.version> <slf4j.version>1.7.5</slf4j.version>
...@@ -116,6 +116,7 @@ ...@@ -116,6 +116,7 @@
<jetty.version>9.2.13.v20150730</jetty.version> <jetty.version>9.2.13.v20150730</jetty.version>
<commons-cli.version>1.3.1</commons-cli.version> <commons-cli.version>1.3.1</commons-cli.version>
<emoji-java.version>3.0.0</emoji-java.version> <emoji-java.version>3.0.0</emoji-java.version>
<jodd.version>3.6.6</jodd.version>
<!-- maven plugin --> <!-- maven plugin -->
<maven-compiler-plugin.version>3.3</maven-compiler-plugin.version> <maven-compiler-plugin.version>3.3</maven-compiler-plugin.version>
...@@ -215,6 +216,12 @@ ...@@ -215,6 +216,12 @@
<artifactId>commons-cli</artifactId> <artifactId>commons-cli</artifactId>
<version>${commons-cli.version}</version> <version>${commons-cli.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.jodd</groupId>
<artifactId>jodd-http</artifactId>
<version>${jodd.version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
...@@ -16,15 +16,25 @@ ...@@ -16,15 +16,25 @@
package org.b3log.solo.processor.console; package org.b3log.solo.processor.console;
import com.qiniu.util.Auth; import com.qiniu.util.Auth;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Calendar; import java.util.Calendar;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.UUID;
import javax.inject.Inject; import javax.inject.Inject;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jodd.io.ZipUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.Latkes; import org.b3log.latke.Latkes;
import org.b3log.latke.RuntimeDatabase;
import org.b3log.latke.event.Event; import org.b3log.latke.event.Event;
import org.b3log.latke.event.EventException; import org.b3log.latke.event.EventException;
import org.b3log.latke.event.EventManager; import org.b3log.latke.event.EventManager;
...@@ -40,6 +50,7 @@ import org.b3log.latke.servlet.HTTPRequestMethod; ...@@ -40,6 +50,7 @@ import org.b3log.latke.servlet.HTTPRequestMethod;
import org.b3log.latke.servlet.annotation.RequestProcessing; import org.b3log.latke.servlet.annotation.RequestProcessing;
import org.b3log.latke.servlet.annotation.RequestProcessor; import org.b3log.latke.servlet.annotation.RequestProcessor;
import org.b3log.latke.servlet.renderer.freemarker.AbstractFreeMarkerRenderer; import org.b3log.latke.servlet.renderer.freemarker.AbstractFreeMarkerRenderer;
import org.b3log.latke.util.Execs;
import org.b3log.latke.util.Strings; import org.b3log.latke.util.Strings;
import org.b3log.solo.SoloServletListener; import org.b3log.solo.SoloServletListener;
import org.b3log.solo.model.Common; import org.b3log.solo.model.Common;
...@@ -58,7 +69,7 @@ import org.json.JSONObject; ...@@ -58,7 +69,7 @@ import org.json.JSONObject;
* Admin console render processing. * Admin console render processing.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.2.1.8, Nov 20, 2015 * @version 1.3.1.8, Jul 27, 2016
* @since 0.4.1 * @since 0.4.1
*/ */
@RequestProcessor @RequestProcessor
...@@ -283,6 +294,82 @@ public class AdminConsole { ...@@ -283,6 +294,82 @@ public class AdminConsole {
fireFreeMarkerActionEvent(templateName, dataModel); fireFreeMarkerActionEvent(templateName, dataModel);
} }
/**
* Exports data as SQL file.
*
* @param request the specified HTTP servlet request
* @param response the specified HTTP servlet response
* @param context the specified HTTP request context
* @throws Exception exception
*/
@RequestProcessing(value = "/console/export/sql", method = HTTPRequestMethod.GET)
public void exportSQL(final HttpServletRequest request, final HttpServletResponse response, final HTTPRequestContext context)
throws Exception {
if (!userQueryService.isAdminLoggedIn(request)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
if (!Latkes.runsWithJDBCDatabase() || RuntimeDatabase.MYSQL != Latkes.getRuntimeDatabase()) {
context.renderJSON().renderMsg("Just support MySQL export now");
return;
}
final String dbUser = Latkes.getLocalProperty("jdbc.username");
final String dbPwd = Latkes.getLocalProperty("jdbc.password");
final String dbURL = Latkes.getLocalProperty("jdbc.URL");
String db = StringUtils.substringAfterLast(dbURL, "/");
db = StringUtils.substringBefore(db, "?");
String sql;
try {
if (StringUtils.isNotBlank(dbPwd)) {
sql = Execs.exec("mysqldump -u" + dbUser + " -p" + dbPwd + " --database " + db);
} else {
sql = Execs.exec("mysqldump -u" + dbUser + " --database " + db);
}
} catch (final Exception e) {
LOGGER.log(Level.ERROR, "Export failed", e);
context.renderJSON().renderMsg("Export failed, please check log");
return;
}
final String tmpDir = System.getProperty("java.io.tmpdir");
String localFilePath = tmpDir + "/b3_solo_" + UUID.randomUUID().toString() + ".sql";
LOGGER.info(localFilePath);
final File localFile = new File(localFilePath);
try {
final byte[] data = sql.getBytes("UTF-8");
OutputStream output = new FileOutputStream(localFile);
IOUtils.write(data, output);
IOUtils.closeQuietly(output);
final File zipFile = ZipUtil.zip(localFile);
final FileInputStream inputStream = new FileInputStream(zipFile);
final byte[] zipData = IOUtils.toByteArray(inputStream);
IOUtils.closeQuietly(inputStream);
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=\"solo.sql.zip\"");
final ServletOutputStream outputStream = response.getOutputStream();
outputStream.write(zipData);
outputStream.flush();
outputStream.close();
} catch (final Exception e) {
LOGGER.log(Level.ERROR, "Export failed", e);
context.renderJSON().renderMsg("Export failed, please check log");
return;
}
}
/** /**
* Fires FreeMarker action event with the host template name and data model. * Fires FreeMarker action event with the host template name and data model.
* *
......
...@@ -16,12 +16,13 @@ ...@@ -16,12 +16,13 @@
# #
# Description: Solo language configurations(en_US). # Description: Solo language configurations(en_US).
# Version: 2.5.2.10, Feb 20, 2016 # Version: 2.6.2.10, Jul 27, 2016
# Author: Liang Ding # Author: Liang Ding
# Author: Liyuan Li # Author: Liyuan Li
# Author: Dongxu Wang # Author: Dongxu Wang
# #
exportSQLLabel=Export SQL file
notAllowRegisterLabel=Not allow register notAllowRegisterLabel=Not allow register
allowRegister1Label=Allow Register: allowRegister1Label=Allow Register:
footerContent1Label=Footer: footerContent1Label=Footer:
......
...@@ -16,12 +16,13 @@ ...@@ -16,12 +16,13 @@
# #
# Description: Solo default language configurations(zh_CN). # Description: Solo default language configurations(zh_CN).
# Version: 2.5.4.17, Feb 20, 2016 # Version: 2.6.4.17, Jul 27, 2016
# Author: Liang Ding # Author: Liang Ding
# Author: Liyuan Li # Author: Liyuan Li
# Author: Dongxu Wang # Author: Dongxu Wang
# #
exportSQLLabel=\u5bfc\u51fa SQL \u6587\u4ef6
notAllowRegisterLabel=\u6682\u4e0d\u5f00\u653e\u6ce8\u518c\uff01 notAllowRegisterLabel=\u6682\u4e0d\u5f00\u653e\u6ce8\u518c\uff01
allowRegister1Label=\u5141\u8bb8\u6ce8\u518c\uff1a allowRegister1Label=\u5141\u8bb8\u6ce8\u518c\uff1a
footerContent1Label=\u9875\u811a\uff1a footerContent1Label=\u9875\u811a\uff1a
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
</div> </div>
<div id="tabOthersPanel_other" class="none"> <div id="tabOthersPanel_other" class="none">
<button class="margin12" onclick="admin.others.removeUnusedTags();">${removeUnusedTagsLabel}</button> <button class="margin12" onclick="admin.others.removeUnusedTags();">${removeUnusedTagsLabel}</button>
<button class="margin12" onclick="admin.others.exportSQL();">${exportSQLLabel}</button>
</div> </div>
</div> </div>
${plugins} ${plugins}
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* *
* @author <a href="http://vanessa.b3log.org">Liyuan Li</a> * @author <a href="http://vanessa.b3log.org">Liyuan Li</a>
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.8, May 28, 2013 * @version 1.1.0.8, Jul 27, 2016
*/ */
/* oterhs 相关操作 */ /* oterhs 相关操作 */
...@@ -28,42 +28,61 @@ admin.others = { ...@@ -28,42 +28,61 @@ admin.others = {
*/ */
init: function () { init: function () {
$("#tabOthers").tabs(); $("#tabOthers").tabs();
$.ajax({ $.ajax({
url: latkeConfig.servePath + "/console/reply/notification/template", url: latkeConfig.servePath + "/console/reply/notification/template",
type: "GET", type: "GET",
cache: false, cache: false,
success: function(result, textStatus){ success: function (result, textStatus) {
$("#tipMsg").text(result.msg); $("#tipMsg").text(result.msg);
if (!result.sc) { if (!result.sc) {
$("#loadMsg").text(""); $("#loadMsg").text("");
return; return;
} }
$("#replayEmailTemplateTitle").val(result.replyNotificationTemplate.subject); $("#replayEmailTemplateTitle").val(result.replyNotificationTemplate.subject);
$("#replayEmailTemplateBody").val(result.replyNotificationTemplate.body); $("#replayEmailTemplateBody").val(result.replyNotificationTemplate.body);
$("#loadMsg").text(""); $("#loadMsg").text("");
} }
}); });
}, },
/* /*
* @description 移除未使用的标签。 * @description 移除未使用的标签。
*/ */
removeUnusedTags: function () { removeUnusedTags: function () {
$("#tipMsg").text(""); $("#tipMsg").text("");
$.ajax({ $.ajax({
url: latkeConfig.servePath + "/console/tag/unused", url: latkeConfig.servePath + "/console/tag/unused",
type: "DELETE", type: "DELETE",
cache: false, cache: false,
success: function(result, textStatus){ success: function (result, textStatus) {
$("#tipMsg").text(result.msg); $("#tipMsg").text(result.msg);
}
});
},
/*
* @description 移除未使用的标签。
*/
exportSQL: function () {
$("#tipMsg").text("");
$.ajax({
url: latkeConfig.servePath + "/console/export/sql",
type: "GET",
cache: false,
success: function (result, textStatus) {
// AJAX 下载文件的话这里会发两次请求,用 sc 来判断是否是文件,如果没有 sc 说明文件可以下载(实际上就是 result)
if (!result.sc) {
// 再发一次请求进行正式下载
window.location = latkeConfig.servePath + "/console/export/sql";
} else {
$("#tipMsg").text(result.msg);
}
} }
}); });
}, },
/* /*
* 获取未使用的标签。 * 获取未使用的标签。
* XXX: Not used this function yet. * XXX: Not used this function yet.
...@@ -73,13 +92,13 @@ admin.others = { ...@@ -73,13 +92,13 @@ admin.others = {
url: latkeConfig.servePath + "/console/tag/unused", url: latkeConfig.servePath + "/console/tag/unused",
type: "GET", type: "GET",
cache: false, cache: false,
success: function(result, textStatus){ success: function (result, textStatus) {
$("#tipMsg").text(result.msg); $("#tipMsg").text(result.msg);
if (!result.sc) { if (!result.sc) {
$("#loadMsg").text(""); $("#loadMsg").text("");
return; return;
} }
var unusedTags = result.unusedTags; var unusedTags = result.unusedTags;
if (0 === unusedTags.length) { if (0 === unusedTags.length) {
return; return;
...@@ -87,21 +106,20 @@ admin.others = { ...@@ -87,21 +106,20 @@ admin.others = {
} }
}); });
}, },
/* /*
* @description 跟新回复提醒邮件模版 * @description 跟新回复提醒邮件模版
*/ */
update: function () { update: function () {
$("#loadMsg").text(Label.loadingLabel); $("#loadMsg").text(Label.loadingLabel);
$("#tipMsg").text(""); $("#tipMsg").text("");
var requestJSONObject = { var requestJSONObject = {
"replyNotificationTemplate": { "replyNotificationTemplate": {
"subject": $("#replayEmailTemplateTitle").val(), "subject": $("#replayEmailTemplateTitle").val(),
"body": $("#replayEmailTemplateBody").val() "body": $("#replayEmailTemplateBody").val()
} }
}; };
$.ajax({ $.ajax({
url: latkeConfig.servePath + "/console/reply/notification/template", url: latkeConfig.servePath + "/console/reply/notification/template",
type: "PUT", type: "PUT",
...@@ -111,16 +129,16 @@ admin.others = { ...@@ -111,16 +129,16 @@ admin.others = {
$("#tipMsg").text(result.msg); $("#tipMsg").text(result.msg);
$("#loadMsg").text(""); $("#loadMsg").text("");
} }
}); });
} }
}; };
/* /*
* 注册到 admin 进行管理 * 注册到 admin 进行管理
*/ */
admin.register.others = { admin.register.others = {
"obj": admin.others, "obj": admin.others,
"init":admin.others.init, "init": admin.others.init,
"refresh": function () { "refresh": function () {
admin.clearTip(); admin.clearTip();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment