mirror of
https://github.com/eiblog/eiblog.git
synced 2026-03-01 00:34:58 +08:00
完成评论服务端化
This commit is contained in:
@@ -28,8 +28,12 @@ superfeedr: deepzz
|
|||||||
disqus:
|
disqus:
|
||||||
shortname: deepzz
|
shortname: deepzz
|
||||||
publickey: wdSgxRm9rdGAlLKFcFdToBe3GT4SibmV7Y8EjJQ0r4GWXeKtxpopMAeIeoI2dTEg
|
publickey: wdSgxRm9rdGAlLKFcFdToBe3GT4SibmV7Y8EjJQ0r4GWXeKtxpopMAeIeoI2dTEg
|
||||||
url: https://disqus.com/api/3.0/threads/set.json
|
postscount: https://disqus.com/api/3.0/threads/set.json
|
||||||
|
postslist: https://disqus.com/api/3.0/threads/listPosts.json
|
||||||
interval: 5
|
interval: 5
|
||||||
|
# 热搜词配置
|
||||||
|
hotwords:
|
||||||
|
- docker
|
||||||
# 运行模式
|
# 运行模式
|
||||||
mode:
|
mode:
|
||||||
# you can fix certfile, keyfile, domain
|
# you can fix certfile, keyfile, domain
|
||||||
|
|||||||
2
db.go
2
db.go
@@ -92,7 +92,7 @@ func init() {
|
|||||||
// 启动定时器
|
// 启动定时器
|
||||||
go timer()
|
go timer()
|
||||||
// 获取评论数量
|
// 获取评论数量
|
||||||
go CommentsCount()
|
go PostsCount()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取或初始化帐号信息
|
// 读取或初始化帐号信息
|
||||||
|
|||||||
71
disqus.go
71
disqus.go
@@ -22,18 +22,18 @@ type result struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func CommentsCount() {
|
func PostsCount() {
|
||||||
if setting.Conf.Disqus.URL == "" || setting.Conf.Disqus.PublicKey == "" || setting.Conf.Disqus.ShortName == "" {
|
if setting.Conf.Disqus.PostsCount == "" || setting.Conf.Disqus.PublicKey == "" || setting.Conf.Disqus.ShortName == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
baseUrl := setting.Conf.Disqus.URL + "?api_key=" + setting.Conf.Disqus.PublicKey + "&forum=" + setting.Conf.Disqus.ShortName + "&"
|
baseUrl := setting.Conf.Disqus.PostsCount + "?api_key=" + setting.Conf.Disqus.PublicKey + "&forum=" + setting.Conf.Disqus.ShortName + "&"
|
||||||
var count, index int
|
var count, index int
|
||||||
for index < len(Ei.Articles) {
|
for index < len(Ei.Articles) {
|
||||||
logd.Debugf("count=====%d, index=======%d, length=======%d, bool=========%t", count, index, len(Ei.Articles), index < len(Ei.Articles) && count < 10)
|
logd.Debugf("count=====%d, index=======%d, length=======%d, bool=========%t", count, index, len(Ei.Articles), index < len(Ei.Articles) && count < 50)
|
||||||
var threads []string
|
var threads []string
|
||||||
for ; index < len(Ei.Articles) && count < 20; index++ {
|
for ; index < len(Ei.Articles) && count < 50; index++ {
|
||||||
artc := Ei.Articles[index]
|
artc := Ei.Articles[index]
|
||||||
threads = append(threads, fmt.Sprintf("thread=link:https://%s/post/%s.html", setting.Conf.Mode.Domain, artc.Slug))
|
threads = append(threads, fmt.Sprintf("thread:ident=post-%s", artc.Slug))
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
count = 0
|
count = 0
|
||||||
@@ -49,16 +49,16 @@ func CommentsCount() {
|
|||||||
logd.Error(err)
|
logd.Error(err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
logd.Error(string(b))
|
||||||
|
break
|
||||||
|
}
|
||||||
rst := result{}
|
rst := result{}
|
||||||
err = json.Unmarshal(b, &rst)
|
err = json.Unmarshal(b, &rst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logd.Error(err)
|
logd.Error(err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if rst.Code != SUCCESS {
|
|
||||||
logd.Error(rst.Code)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
for _, v := range rst.Response {
|
for _, v := range rst.Response {
|
||||||
i := strings.Index(v.Identifiers[0], "-")
|
i := strings.Index(v.Identifiers[0], "-")
|
||||||
artc := Ei.MapArticles[v.Identifiers[0][i+1:]]
|
artc := Ei.MapArticles[v.Identifiers[0][i+1:]]
|
||||||
@@ -67,5 +67,54 @@ func CommentsCount() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
time.AfterFunc(time.Duration(setting.Conf.Disqus.Interval)*time.Hour, CommentsCount)
|
time.AfterFunc(time.Duration(setting.Conf.Disqus.Interval)*time.Hour, PostsCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
type postsList struct {
|
||||||
|
Cursor struct {
|
||||||
|
HasNext bool
|
||||||
|
Next string
|
||||||
|
}
|
||||||
|
Code int
|
||||||
|
Response []struct {
|
||||||
|
Parent int
|
||||||
|
Id string
|
||||||
|
CreatedAt string
|
||||||
|
Message string
|
||||||
|
Author struct {
|
||||||
|
Name string
|
||||||
|
ProfileUrl string
|
||||||
|
Avatar struct {
|
||||||
|
Cache string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func PostsList(slug, cursor string) *postsList {
|
||||||
|
if setting.Conf.Disqus.PostsList == "" || setting.Conf.Disqus.PublicKey == "" || setting.Conf.Disqus.ShortName == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
url := setting.Conf.Disqus.PostsList + "?limit=50&api_key=" + setting.Conf.Disqus.PublicKey + "&forum=" + setting.Conf.Disqus.ShortName + "&cursor=" + cursor + "&thread:ident=post-" + slug
|
||||||
|
resp, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
b, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
logd.Error(err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
logd.Error(string(b))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
pl := &postsList{}
|
||||||
|
err = json.Unmarshal(b, pl)
|
||||||
|
if err != nil {
|
||||||
|
logd.Error(err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return pl
|
||||||
}
|
}
|
||||||
|
|||||||
94
front.go
94
front.go
@@ -158,13 +158,12 @@ func HandleSearchPage(c *gin.Context) {
|
|||||||
h["CurrentPage"] = "search-post"
|
h["CurrentPage"] = "search-post"
|
||||||
|
|
||||||
q := c.Query("q")
|
q := c.Query("q")
|
||||||
start, err := strconv.Atoi(c.Query("start"))
|
|
||||||
if start < 1 || err != nil {
|
|
||||||
start = 1
|
|
||||||
}
|
|
||||||
if q != "" {
|
if q != "" {
|
||||||
|
start, err := strconv.Atoi(c.Query("start"))
|
||||||
|
if start < 1 || err != nil {
|
||||||
|
start = 1
|
||||||
|
}
|
||||||
h["Word"] = q
|
h["Word"] = q
|
||||||
h["HotWords"] = []string{"docker"}
|
|
||||||
var result *ESSearchResult
|
var result *ESSearchResult
|
||||||
vals := c.Request.URL.Query()
|
vals := c.Request.URL.Query()
|
||||||
reg := regexp.MustCompile(`^[a-z]+:\w+$`)
|
reg := regexp.MustCompile(`^[a-z]+:\w+$`)
|
||||||
@@ -191,6 +190,8 @@ func HandleSearchPage(c *gin.Context) {
|
|||||||
h["Next"] = vals.Encode()
|
h["Next"] = vals.Encode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
h["HotWords"] = setting.Conf.HotWords
|
||||||
}
|
}
|
||||||
c.Status(http.StatusOK)
|
c.Status(http.StatusOK)
|
||||||
RenderHTMLFront(c, "search", h)
|
RenderHTMLFront(c, "search", h)
|
||||||
@@ -242,41 +243,58 @@ func HandleBeacon(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 服务端获取评论详细
|
// 服务端获取评论详细
|
||||||
|
type DisqusComments struct {
|
||||||
|
ErrNo int `json:"errno"`
|
||||||
|
ErrMsg string `json:"errmsg"`
|
||||||
|
Data struct {
|
||||||
|
Next string `json:"next"`
|
||||||
|
Total int `json:"total,omitempty"`
|
||||||
|
Comments []commentsDetail `json:"comments"`
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type commentsDetail struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Parent int `json:"parent"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Url string `json:"url"`
|
||||||
|
Avatar string `json:"avatar"`
|
||||||
|
CreatedAt string `json:"createdAt"`
|
||||||
|
CreatedAtStr string `json:"createdAtStr"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
func HandleDisqus(c *gin.Context) {
|
func HandleDisqus(c *gin.Context) {
|
||||||
slug := c.Query("slug")
|
slug := c.Param("slug")
|
||||||
logd.Debug(slug)
|
cursor := c.Query("cursor")
|
||||||
// TODO comments
|
dcs := DisqusComments{}
|
||||||
var ss = map[string]interface{}{
|
postsList := PostsList(slug, cursor)
|
||||||
"errno": 0,
|
if postsList != nil {
|
||||||
"errmsg": "",
|
dcs.ErrNo = postsList.Code
|
||||||
"data": map[string]interface{}{
|
if postsList.Cursor.HasNext {
|
||||||
"next": "",
|
dcs.Data.Next = postsList.Cursor.Next
|
||||||
"total": 3,
|
}
|
||||||
"comments": []map[string]interface{}{
|
if cursor == "" {
|
||||||
map[string]interface{}{
|
dcs.Data.Total = Ei.MapArticles[slug].Count
|
||||||
"id": "2361914870",
|
}
|
||||||
"name": "Rekey Luo",
|
dcs.Data.Comments = make([]commentsDetail, len(postsList.Response))
|
||||||
"parent": 0,
|
for i, v := range postsList.Response {
|
||||||
"url": "https://disqus.com/by/rekeyluo/",
|
dcs.Data.Comments[i] = commentsDetail{
|
||||||
"avatar": "//a.disquscdn.com/uploads/users/15860/7550/avatar92.jpg?1438917750",
|
Id: v.Id,
|
||||||
"createdAt": "2015-11-16T05:00:02",
|
Name: v.Author.Name,
|
||||||
"createdAtStr": "9 months ago",
|
Parent: v.Parent,
|
||||||
"message": "你最近对 http2 ssl 相关关注好多啊。",
|
Url: v.Author.ProfileUrl,
|
||||||
},
|
Avatar: v.Author.Avatar.Cache,
|
||||||
map[string]interface{}{
|
CreatedAt: v.CreatedAt,
|
||||||
"id": "2361915528",
|
CreatedAtStr: ConvertStr(v.CreatedAt),
|
||||||
"name": "Jerry Qu",
|
Message: v.Message,
|
||||||
"parent": 0,
|
}
|
||||||
"url": "https://disqus.com/by/JerryQu/",
|
}
|
||||||
"avatar": "//a.disquscdn.com/uploads/users/1668/8837/avatar92.jpg?1472281172",
|
} else {
|
||||||
"createdAt": "2015-11-16T05:01:05",
|
dcs.ErrNo = FAIL
|
||||||
"createdAtStr": "9 months ago",
|
dcs.ErrMsg = "系统错误"
|
||||||
"message": "嗯,最近对 web 性能优化这一块研究得比较多。",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, ss)
|
c.JSON(http.StatusOK, dcs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RenderHTMLFront(c *gin.Context, name string, data gin.H) {
|
func RenderHTMLFront(c *gin.Context, name string, data gin.H) {
|
||||||
|
|||||||
42
helper.go
42
helper.go
@@ -8,6 +8,9 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"path"
|
"path"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/eiblog/utils/logd"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -69,3 +72,42 @@ func PickFirstImage(html string) string {
|
|||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2016-10-22T07:03:01
|
||||||
|
const (
|
||||||
|
JUST_NOW = "几秒前"
|
||||||
|
MINUTES_AGO = "%d分钟前"
|
||||||
|
HOURS_AGO = "%d小时前"
|
||||||
|
DAYS_AGO = "%d天前"
|
||||||
|
MONTH_AGO = "%d月前"
|
||||||
|
YEARS_AGO = "%d年前"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ConvertStr(str string) string {
|
||||||
|
t, err := time.Parse("2006-01-02T15:04:05", str)
|
||||||
|
if err != nil {
|
||||||
|
logd.Error(err, str)
|
||||||
|
return JUST_NOW
|
||||||
|
}
|
||||||
|
now := time.Now()
|
||||||
|
year1, month1, day1 := t.Date()
|
||||||
|
year2, month2, day2 := now.Date()
|
||||||
|
if y := year2 - year1; y > 0 {
|
||||||
|
return fmt.Sprintf(YEARS_AGO, y)
|
||||||
|
}
|
||||||
|
if m := month2 - month1; m > 0 {
|
||||||
|
return fmt.Sprintf(MONTH_AGO, m)
|
||||||
|
}
|
||||||
|
if d := day2 - day1; d > 0 {
|
||||||
|
return fmt.Sprintf(DAYS_AGO, d)
|
||||||
|
}
|
||||||
|
hour1, minute1, _ := t.Clock()
|
||||||
|
hour2, minute2, _ := now.Clock()
|
||||||
|
if h := hour2 - hour1; h > 0 {
|
||||||
|
return fmt.Sprintf(HOURS_AGO, h)
|
||||||
|
}
|
||||||
|
if m := minute2 - minute1; m > 0 {
|
||||||
|
return fmt.Sprintf(MINUTES_AGO, m)
|
||||||
|
}
|
||||||
|
return JUST_NOW
|
||||||
|
}
|
||||||
|
|||||||
@@ -36,14 +36,16 @@ type Config struct {
|
|||||||
SearchURL string // elasticsearch 地址
|
SearchURL string // elasticsearch 地址
|
||||||
Superfeedr string // superfeedr
|
Superfeedr string // superfeedr
|
||||||
Disqus struct { // 获取文章数量相关
|
Disqus struct { // 获取文章数量相关
|
||||||
ShortName string
|
ShortName string
|
||||||
PublicKey string
|
PublicKey string
|
||||||
URL string
|
PostsCount string
|
||||||
Interval int
|
PostsList string
|
||||||
|
Interval int
|
||||||
}
|
}
|
||||||
Mode RunMode // 运行模式
|
HotWords []string // 热搜词
|
||||||
Twitter string // twitter地址
|
Mode RunMode // 运行模式
|
||||||
Blogger struct { // 初始化数据
|
Twitter string // twitter地址
|
||||||
|
Blogger struct { // 初始化数据
|
||||||
BlogName string
|
BlogName string
|
||||||
SubTitle string
|
SubTitle string
|
||||||
BeiAn string
|
BeiAn string
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user