mirror of https://github.com/halo-dev/halo
commit
bc322b271f
6
pom.xml
6
pom.xml
|
@ -55,6 +55,12 @@
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-devtools</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
package cc.ryanc.halo.utils;
|
package cc.ryanc.halo.utils;
|
||||||
|
|
||||||
import cc.ryanc.halo.model.domain.Comment;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import cc.ryanc.halo.model.domain.Comment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
* 拼装评论
|
* 拼装评论
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author : RYAN0UP
|
* @author : RYAN0UP
|
||||||
|
@ -23,6 +26,10 @@ public class CommentUtil {
|
||||||
* @return List
|
* @return List
|
||||||
*/
|
*/
|
||||||
public static List<Comment> getComments(List<Comment> commentsRoot) {
|
public static List<Comment> getComments(List<Comment> commentsRoot) {
|
||||||
|
if (CollectionUtils.isEmpty(commentsRoot)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
List<Comment> commentsResult = new ArrayList<>();
|
List<Comment> commentsResult = new ArrayList<>();
|
||||||
|
|
||||||
for (Comment comment : commentsRoot) {
|
for (Comment comment : commentsRoot) {
|
||||||
|
@ -34,7 +41,7 @@ public class CommentUtil {
|
||||||
for (Comment comment : commentsResult) {
|
for (Comment comment : commentsResult) {
|
||||||
comment.setChildComments(getChild(comment.getCommentId(), commentsRoot));
|
comment.setChildComments(getChild(comment.getCommentId(), commentsRoot));
|
||||||
}
|
}
|
||||||
//集合倒序,最新的评论在最前面
|
// 集合倒序,最新的评论在最前面
|
||||||
Collections.reverse(commentsResult);
|
Collections.reverse(commentsResult);
|
||||||
return commentsResult;
|
return commentsResult;
|
||||||
}
|
}
|
||||||
|
@ -47,6 +54,12 @@ public class CommentUtil {
|
||||||
* @return List
|
* @return List
|
||||||
*/
|
*/
|
||||||
private static List<Comment> getChild(Long id, List<Comment> commentsRoot) {
|
private static List<Comment> getChild(Long id, List<Comment> commentsRoot) {
|
||||||
|
Assert.notNull(id, "comment id must not be null");
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(commentsRoot)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
List<Comment> commentsChild = new ArrayList<>();
|
List<Comment> commentsChild = new ArrayList<>();
|
||||||
for (Comment comment : commentsRoot) {
|
for (Comment comment : commentsRoot) {
|
||||||
if (comment.getCommentParent() != 0) {
|
if (comment.getCommentParent() != 0) {
|
||||||
|
|
|
@ -16,6 +16,8 @@ import com.sun.syndication.io.FeedException;
|
||||||
import com.sun.syndication.io.WireFeedOutput;
|
import com.sun.syndication.io.WireFeedOutput;
|
||||||
import io.github.biezhi.ome.OhMyEmail;
|
import io.github.biezhi.ome.OhMyEmail;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ResourceUtils;
|
import org.springframework.util.ResourceUtils;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
@ -34,7 +36,7 @@ import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
* 常用工具
|
* 常用工具
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author : RYAN0UP
|
* @author : RYAN0UP
|
||||||
|
@ -55,7 +57,7 @@ public class HaloUtils {
|
||||||
File[] files = srcPath.listFiles();
|
File[] files = srcPath.listFiles();
|
||||||
List<BackupDto> backupDtos = new ArrayList<>();
|
List<BackupDto> backupDtos = new ArrayList<>();
|
||||||
BackupDto backupDto = null;
|
BackupDto backupDto = null;
|
||||||
//遍历文件
|
// 遍历文件
|
||||||
if (null != files) {
|
if (null != files) {
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
if (file.isFile()) {
|
if (file.isFile()) {
|
||||||
|
@ -109,7 +111,8 @@ public class HaloUtils {
|
||||||
*/
|
*/
|
||||||
public static Date getCreateTime(String srcPath) {
|
public static Date getCreateTime(String srcPath) {
|
||||||
Path path = Paths.get(srcPath);
|
Path path = Paths.get(srcPath);
|
||||||
BasicFileAttributeView basicview = Files.getFileAttributeView(path, BasicFileAttributeView.class, LinkOption.NOFOLLOW_LINKS);
|
BasicFileAttributeView basicview = Files.getFileAttributeView(path, BasicFileAttributeView.class,
|
||||||
|
LinkOption.NOFOLLOW_LINKS);
|
||||||
BasicFileAttributes attr;
|
BasicFileAttributes attr;
|
||||||
try {
|
try {
|
||||||
attr = basicview.readAttributes();
|
attr = basicview.readAttributes();
|
||||||
|
@ -147,9 +150,9 @@ public class HaloUtils {
|
||||||
public static List<Theme> getThemes() {
|
public static List<Theme> getThemes() {
|
||||||
List<Theme> themes = new ArrayList<>();
|
List<Theme> themes = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
//获取项目根路径
|
// 获取项目根路径
|
||||||
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
|
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
|
||||||
//获取主题路径
|
// 获取主题路径
|
||||||
File themesPath = new File(basePath.getAbsolutePath(), "templates/themes");
|
File themesPath = new File(basePath.getAbsolutePath(), "templates/themes");
|
||||||
File[] files = themesPath.listFiles();
|
File[] files = themesPath.listFiles();
|
||||||
if (null != files) {
|
if (null != files) {
|
||||||
|
@ -161,7 +164,8 @@ public class HaloUtils {
|
||||||
}
|
}
|
||||||
theme = new Theme();
|
theme = new Theme();
|
||||||
theme.setThemeName(file.getName());
|
theme.setThemeName(file.getName());
|
||||||
File optionsPath = new File(themesPath.getAbsolutePath(), file.getName() + "/module/options.ftl");
|
File optionsPath = new File(themesPath.getAbsolutePath(),
|
||||||
|
file.getName() + "/module/options.ftl");
|
||||||
if (optionsPath.exists()) {
|
if (optionsPath.exists()) {
|
||||||
theme.setHasOptions(true);
|
theme.setHasOptions(true);
|
||||||
} else {
|
} else {
|
||||||
|
@ -192,9 +196,9 @@ public class HaloUtils {
|
||||||
public static List<String> getTplName(String theme) {
|
public static List<String> getTplName(String theme) {
|
||||||
List<String> tpls = new ArrayList<>();
|
List<String> tpls = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
//获取项目根路径
|
// 获取项目根路径
|
||||||
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
|
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
|
||||||
//获取主题路径
|
// 获取主题路径
|
||||||
File themesPath = new File(basePath.getAbsolutePath(), "templates/themes/" + theme);
|
File themesPath = new File(basePath.getAbsolutePath(), "templates/themes/" + theme);
|
||||||
File modulePath = new File(themesPath.getAbsolutePath(), "module");
|
File modulePath = new File(themesPath.getAbsolutePath(), "module");
|
||||||
File[] baseFiles = themesPath.listFiles();
|
File[] baseFiles = themesPath.listFiles();
|
||||||
|
@ -220,8 +224,7 @@ public class HaloUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取定制模板
|
* 获取定制模板 格式 page_xxx
|
||||||
* 格式 page_xxx
|
|
||||||
*
|
*
|
||||||
* @return List
|
* @return List
|
||||||
*/
|
*/
|
||||||
|
@ -229,7 +232,7 @@ public class HaloUtils {
|
||||||
List<String> tpls = new ArrayList<>();
|
List<String> tpls = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
|
File basePath = new File(ResourceUtils.getURL("classpath:").getPath());
|
||||||
//获取主题路径
|
// 获取主题路径
|
||||||
File themePath = new File(basePath.getAbsolutePath(), "templates/themes/" + theme);
|
File themePath = new File(basePath.getAbsolutePath(), "templates/themes/" + theme);
|
||||||
File[] themeFiles = themePath.listFiles();
|
File[] themeFiles = themePath.listFiles();
|
||||||
if (null != themeFiles && themeFiles.length > 0) {
|
if (null != themeFiles && themeFiles.length > 0) {
|
||||||
|
@ -284,6 +287,8 @@ public class HaloUtils {
|
||||||
* @throws FeedException
|
* @throws FeedException
|
||||||
*/
|
*/
|
||||||
public static String getRss(List<Post> posts) throws FeedException {
|
public static String getRss(List<Post> posts) throws FeedException {
|
||||||
|
Assert.notEmpty(posts, "posts must not be empty");
|
||||||
|
|
||||||
Channel channel = new Channel("rss_2.0");
|
Channel channel = new Channel("rss_2.0");
|
||||||
if (null == HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_TITLE.getProp())) {
|
if (null == HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_TITLE.getProp())) {
|
||||||
channel.setTitle("");
|
channel.setTitle("");
|
||||||
|
@ -318,7 +323,8 @@ public class HaloUtils {
|
||||||
value = new String(xmlChar);
|
value = new String(xmlChar);
|
||||||
content.setValue(value);
|
content.setValue(value);
|
||||||
item.setContent(content);
|
item.setContent(content);
|
||||||
item.setLink(HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/archives/" + post.getPostUrl());
|
item.setLink(
|
||||||
|
HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/archives/" + post.getPostUrl());
|
||||||
item.setPubDate(post.getPostDate());
|
item.setPubDate(post.getPostDate());
|
||||||
items.add(item);
|
items.add(item);
|
||||||
}
|
}
|
||||||
|
@ -334,12 +340,15 @@ public class HaloUtils {
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
public static String getSiteMap(List<Post> posts) {
|
public static String getSiteMap(List<Post> posts) {
|
||||||
|
Assert.notEmpty(posts, "post mut not be empty");
|
||||||
|
|
||||||
String head = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">";
|
String head = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">";
|
||||||
String urlBody = "";
|
String urlBody = "";
|
||||||
String urlItem;
|
String urlItem;
|
||||||
String urlPath = HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/archives/";
|
String urlPath = HaloConst.OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/archives/";
|
||||||
for (Post post : posts) {
|
for (Post post : posts) {
|
||||||
urlItem = "<url><loc>" + urlPath + post.getPostUrl() + "</loc><lastmod>" + DateUtil.format(post.getPostDate(), "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") + "</lastmod>" + "</url>";
|
urlItem = "<url><loc>" + urlPath + post.getPostUrl() + "</loc><lastmod>"
|
||||||
|
+ DateUtil.format(post.getPostDate(), "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") + "</lastmod>" + "</url>";
|
||||||
urlBody += urlItem;
|
urlBody += urlItem;
|
||||||
}
|
}
|
||||||
return head + urlBody + "</urlset>";
|
return head + urlBody + "</urlset>";
|
||||||
|
@ -365,6 +374,8 @@ public class HaloUtils {
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
public static String getHttpResponse(String enterUrl) {
|
public static String getHttpResponse(String enterUrl) {
|
||||||
|
Assert.hasText(enterUrl, "enter url must not be blank");
|
||||||
|
|
||||||
BufferedReader in = null;
|
BufferedReader in = null;
|
||||||
StringBuffer result = null;
|
StringBuffer result = null;
|
||||||
try {
|
try {
|
||||||
|
@ -396,7 +407,6 @@ public class HaloUtils {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 百度主动推送
|
* 百度主动推送
|
||||||
*
|
*
|
||||||
|
@ -406,29 +416,33 @@ public class HaloUtils {
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
public static String baiduPost(String blogUrl, String token, String urls) {
|
public static String baiduPost(String blogUrl, String token, String urls) {
|
||||||
|
Assert.hasText(blogUrl, "blog url must not be blank");
|
||||||
|
Assert.hasText(token, "token must not be blank");
|
||||||
|
Assert.hasText(urls, "urls must not be blank");
|
||||||
|
|
||||||
String url = "http://data.zz.baidu.com/urls?site=" + blogUrl + "&token=" + token;
|
String url = "http://data.zz.baidu.com/urls?site=" + blogUrl + "&token=" + token;
|
||||||
String result = "";
|
String result = "";
|
||||||
PrintWriter out = null;
|
PrintWriter out = null;
|
||||||
BufferedReader in = null;
|
BufferedReader in = null;
|
||||||
try {
|
try {
|
||||||
//建立URL之间的连接
|
// 建立URL之间的连接
|
||||||
URLConnection conn = new URL(url).openConnection();
|
URLConnection conn = new URL(url).openConnection();
|
||||||
//设置通用的请求属性
|
// 设置通用的请求属性
|
||||||
conn.setRequestProperty("Host", "data.zz.baidu.com");
|
conn.setRequestProperty("Host", "data.zz.baidu.com");
|
||||||
conn.setRequestProperty("User-Agent", "curl/7.12.1");
|
conn.setRequestProperty("User-Agent", "curl/7.12.1");
|
||||||
conn.setRequestProperty("Content-Length", "83");
|
conn.setRequestProperty("Content-Length", "83");
|
||||||
conn.setRequestProperty("Content-Type", "text/plain");
|
conn.setRequestProperty("Content-Type", "text/plain");
|
||||||
|
|
||||||
//发送POST请求必须设置如下两行
|
// 发送POST请求必须设置如下两行
|
||||||
conn.setDoInput(true);
|
conn.setDoInput(true);
|
||||||
conn.setDoOutput(true);
|
conn.setDoOutput(true);
|
||||||
|
|
||||||
//获取conn对应的输出流
|
// 获取conn对应的输出流
|
||||||
out = new PrintWriter(conn.getOutputStream());
|
out = new PrintWriter(conn.getOutputStream());
|
||||||
out.print(urls.trim());
|
out.print(urls.trim());
|
||||||
//进行输出流的缓冲
|
// 进行输出流的缓冲
|
||||||
out.flush();
|
out.flush();
|
||||||
//通过BufferedReader输入流来读取Url的响应
|
// 通过BufferedReader输入流来读取Url的响应
|
||||||
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||||
String line;
|
String line;
|
||||||
while ((line = in.readLine()) != null) {
|
while ((line = in.readLine()) != null) {
|
||||||
|
|
|
@ -238,7 +238,7 @@
|
||||||
<span class="label bg-red"><@spring.message code='common.status.recycle-bin' /></span>
|
<span class="label bg-red"><@spring.message code='common.status.recycle-bin' /></span>
|
||||||
</#if>
|
</#if>
|
||||||
</td>
|
</td>
|
||||||
<td>${post.postDate?if_exists?string("yyyy-MM-dd HH:mm")}</td>
|
<td><@common.timeline datetime="${post.postDate?if_exists}"?datetime /></td>
|
||||||
</tr>
|
</tr>
|
||||||
</#list>
|
</#list>
|
||||||
<#else>
|
<#else>
|
||||||
|
@ -310,7 +310,7 @@
|
||||||
<#break >
|
<#break >
|
||||||
</#switch>
|
</#switch>
|
||||||
</td>
|
</td>
|
||||||
<td>${comment.commentDate?string("yyyy-MM-dd HH:mm")}</td>
|
<td><@common.timeline datetime="${comment.commentDate}"?datetime /></td>
|
||||||
</tr>
|
</tr>
|
||||||
</#list>
|
</#list>
|
||||||
<#else>
|
<#else>
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
</div>
|
</div>
|
||||||
<h4>
|
<h4>
|
||||||
${comment.commentAuthor}
|
${comment.commentAuthor}
|
||||||
<small> ${comment.commentDate?string("yyyy/MM/dd HH:mm")}</small>
|
<small> <@common.timeline datetime="${comment.commentDate}"?datetime /></small>
|
||||||
</h4>
|
</h4>
|
||||||
<object>${comment.commentContent}</object>
|
<object>${comment.commentContent}</object>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<#macro head>
|
<#macro head>
|
||||||
|
<#import "/common/macro/common_macro.ftl" as common>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
|
|
@ -31,4 +31,18 @@
|
||||||
<#if options.blog_verification_qihu??>
|
<#if options.blog_verification_qihu??>
|
||||||
<meta name="360-site-verification" content="${options.blog_verification_qihu}" />
|
<meta name="360-site-verification" content="${options.blog_verification_qihu}" />
|
||||||
</#if>
|
</#if>
|
||||||
|
</#macro>
|
||||||
|
|
||||||
|
<#-- 时间格式化 几...前 -->
|
||||||
|
<#macro timeline datetime=.now>
|
||||||
|
<#assign ct = (.now?long-datetime?long)/1000>
|
||||||
|
<#if ct gte 31104000>${(ct/31104000)?int}年前
|
||||||
|
<#t><#elseif ct gte 2592000>${(ct/2592000)?int}个月前
|
||||||
|
<#t><#elseif ct gte 86400*2>${(ct/86400)?int}天前
|
||||||
|
<#t><#elseif ct gte 86400>昨天
|
||||||
|
<#t><#elseif ct gte 3600>${(ct/3600)?int}小时前
|
||||||
|
<#t><#elseif ct gte 60>${(ct/60)?int}分钟前
|
||||||
|
<#t><#elseif ct gt 0>${ct?int}秒前
|
||||||
|
<#t><#else>刚刚
|
||||||
|
</#if>
|
||||||
</#macro>
|
</#macro>
|
Loading…
Reference in New Issue