完成评论服务端化

This commit is contained in:
deepzz0 committed 2016-10-23 00:22:04 +08:00
1 parent de79f8bd51
commit 3ce2b21588
7 files changed
+174 -59

No files matched your search

+5 -1
View File
@@ -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
+1 -1
View File
@@ -92,7 +92,7 @@ func init() {
// 启动定时器 // 启动定时器
go timer() go timer()
// 获取评论数量 // 获取评论数量
go CommentsCount() go PostsCount()
} }
// 读取或初始化帐号信息 // 读取或初始化帐号信息
+60 -11
View File
@@ -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
} }
+56 -38
View File
@@ -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
View File
@@ -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
}
+9 -7
View File
@@ -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
+1 -1
View File
@@ -1,3 +1,3 @@
{{define "blog_js"}} {{define "blog_js"}}
var stringProto=String.prototype;stringProto.stripTags=function(){return this.replace(/<[^>]*>/gi,"")},stringProto.decode4Html=function(){var t=document.createElement("div");return t.innerHTML=this.stripTags(),t.childNodes[0]?t.childNodes[0].nodeValue||"":""},stringProto.queryUrl=function(t){var a=this.replace(/^[^?=]*\?/gi,"").split("#")[0],e={};return a.replace(/(^|&)([^&=]+)=([^&]*)/g,function(t,a,n,o){try{n=decodeURIComponent(n)}catch(s){}try{o=decodeURIComponent(o)}catch(s){}n in e?e[n] instanceof Array?e[n].push(o):e[n]=[e[n],o]:e[n]=/\[\]$/.test(n)?[o]:o}),t?e[t]:e},function(t){t.disqus_shortname="deepzz",$.each(["CURRENT_PAGE","CDN_DOMAIN"],function(a,e){t[e]="";var n=$("#"+e);n&&(t[e]=n.val())})}(this),function(t){function a(a){var e,n,o={selector:null,height:200};o=$.extend(o,a),e=o.height,n=function(){var a=$(t).scrollTop(),n=$(t).height()+a;$(o.selector).find("img[data-src]").each(function(){var t=$(this);setTimeout(function(){var o,s=t.offset(),i=t.height();s.top>n+e||s.top+i<a-e||(o=t.data("src"),o&&(t.on("load",function(){t.addClass("loaded")}),t.attr("src",o),t.removeAttr("data-src")))},0)})},$(t).on("resize",n),$(t).on("scroll",n),n()}t.lazyLoad=a}(this),function(t){function a(a){var e='<li class="post" id="post-'+a.id+'"><div class="post-content clearfix"><div class="indicator"></div><div class="avatar"><div class="user">'+(a.url?'<a href="'+a.url+'"><img data-src="'+a.avatar+'" /></a>':'<img data-src="'+t.CDN_DOMAIN+'/static/img/blog/default_avatar.png" />')+'</div></div><div class="post-body"><header class="post-header"><span class="post-byline"><span class="author publisher-anchor-color">'+(a.url?'<a href="'+a.url+'">'+a.name+"</a>":a.name)+'</span></span><span class="post-meta"><span class="bullet">&nbsp;\u2022&nbsp;</span><a data-id="'+a.id+'" href="'+location.href.replace(/#.*$/,"")+"#comment-"+a.id+'" class="time-ago" title="'+a.createdAt+'">'+a.createdAtStr+'</a></span></header><div class="post-body-inner">'+a.message+'</div></div></div><ul class="children" data-id="'+a.id+'"></ul></li>';return e}function e(t){for(;t.length;){var e=[];t.forEach(function(t){var n=t.parent,o=s.find('ul[data-id="'+n+'"]');return o.length?void o.append(a(t)):void e.push(t)}),t=e}}function n(t){var a="";a=t.comments.length?'<div class="thread"><header><nav class="nav clearfix"><ul><li class="nav-tab tab-conversation active"><a class="publisher-nav-color"><span>'+t.total+' </span>Comments</span></a></li></ul></nav></header><section><div class="thread-tips">本模式仅提供基础浏览功能。如需发表评论请<a href="#disqus_thread">点击这里</a>(请确保你能流畅访问 disq.us | disquscdn.com | disqus.com)</div></section><section><ul class="post-list" data-id="0"></ul><div class="load-more"><a href="#" class="btn">Load more comments</a></div></section></div>':'<p class="no-result">没有找到任何评论数据~<br /><br /><a href="#disqus_thread">点此发表评论 \xbb</a></p>',s.html(a)}function o(){if(!i){i=!0;var a;a=r?"/disqus/"+t.simple_config.id+"/"+encodeURIComponent(r):"/disqus/"+t.simple_config.id,$.get(a,{},function(a){var o;i=!1,a&&0==a.errno?(r?e(a.data.comments):(n(a.data),e(a.data.comments),$(t).trigger("hashchange","scrollIntoView")),o=s.find(".load-more a"),a.data.next?o.removeClass("busy"):o.hide(),r=a.data.next,$(t).trigger("scroll")):s.html('<p class="no-result">获取数据失败,请稍后再试!</p>')})}}var s=$("#simple_thread"),i=!1,r="";s.on("click",".load-more a",function(t){t.preventDefault(),$(this).addClass("busy"),o()}).on("click",".time-ago",function(t){t.preventDefault(),location.hash="simple-"+$(this).data("id")}),$(t).on("hashchange",function(a,e){var n,o=location.hash.match(/#(?:comment|simple)-(\d+)/);o&&(n=s.find("#post-"+o[1]),n.length&&(s.find(".post-content.target").removeClass("target"),n.find("> .post-content").addClass("target"),e&&$(t).scrollTop(n.offset().top-90)))}),/(iPhone|Android)/.test(navigator.userAgent)&&s.addClass("mobile"),t.initSimpleThread=o}(window,document),function(t,a){return"127.0.0.1"!=a.domain&&"deepzz.com"!=a.domain?void (location.href=location.href.replace(/(https?:\/\/[^\/]+)\//i,"//deepzz.com/")):(function(){var t,a=location.search.queryUrl();"1"==a.clear_ls&&(delete a.clear_ls,t=$.param(a),setTimeout(function(){t?location.search=$.param(a):location.href=location.href.replace(/\?.*$/,"")},300))}(),void $(function(){lazyLoad({selector:"#content",height:100}),function(){var t=$("#content"),a=t.find("img"),e=t.width();a.each(function(){var t=$(this),a=0|t.attr("width"),n=0|t.attr("height"),o=t.prop("complete");a>e&&t.attr("height",Math.ceil(n/a*e)),t.prop("src")&&(o?t.addClass("loaded"):t.on("load",function(){t.addClass("loaded")}))})}(),function(){if("search-post"==CURRENT_PAGE){var t=$("#keyword");t.val()||t.focus()}}(),function(){var a,e,n,o,s=$("#disqus_thread"),i=$("#simple_thread"),r=!1,c=!1,l=$("#switch_thread_mode");l.length&&(t.disqus_config=function(){this.page.url=s.data("url"),this.page.identifier=s.dataLine truncated var stringProto=String.prototype;stringProto.stripTags=function(){return this.replace(/<[^>]*>/gi,"")},stringProto.decode4Html=function(){var t=document.createElement("div");return t.innerHTML=this.stripTags(),t.childNodes[0]?t.childNodes[0].nodeValue||"":""},stringProto.queryUrl=function(t){var a=this.replace(/^[^?=]*\?/gi,"").split("#")[0],e={};return a.replace(/(^|&)([^&=]+)=([^&]*)/g,function(t,a,n,o){try{n=decodeURIComponent(n)}catch(s){}try{o=decodeURIComponent(o)}catch(s){}n in e?e[n] instanceof Array?e[n].push(o):e[n]=[e[n],o]:e[n]=/\[\]$/.test(n)?[o]:o}),t?e[t]:e},function(t){t.disqus_shortname="deepzz",$.each(["CURRENT_PAGE","CDN_DOMAIN"],function(a,e){t[e]="";var n=$("#"+e);n&&(t[e]=n.val())})}(this),function(t){function a(a){var e,n,o={selector:null,height:200};o=$.extend(o,a),e=o.height,n=function(){var a=$(t).scrollTop(),n=$(t).height()+a;$(o.selector).find("img[data-src]").each(function(){var t=$(this);setTimeout(function(){var o,s=t.offset(),i=t.height();s.top>n+e||s.top+i<a-e||(o=t.data("src"),o&&(t.on("load",function(){t.addClass("loaded")}),t.attr("src",o),t.removeAttr("data-src")))},0)})},$(t).on("resize",n),$(t).on("scroll",n),n()}t.lazyLoad=a}(this),function(t){function a(a){var e='<li class="post" id="post-'+a.id+'"><div class="post-content clearfix"><div class="indicator"></div><div class="avatar"><div class="user">'+(a.url?'<a href="'+a.url+'"><img data-src="'+a.avatar+'" /></a>':'<img data-src="'+t.CDN_DOMAIN+'/static/img/blog/default_avatar.png" />')+'</div></div><div class="post-body"><header class="post-header"><span class="post-byline"><span class="author publisher-anchor-color">'+(a.url?'<a href="'+a.url+'">'+a.name+"</a>":a.name)+'</span></span><span class="post-meta"><span class="bullet">&nbsp;\u2022&nbsp;</span><a data-id="'+a.id+'" href="'+location.href.replace(/#.*$/,"")+"#comment-"+a.id+'" class="time-ago" title="'+a.createdAt+'">'+a.createdAtStr+'</a></span></header><div class="post-body-inner">'+a.message+'</div></div></div><ul class="children" data-id="'+a.id+'"></ul></li>';return e}function e(t){for(;t.length;){var e=[];t.forEach(function(t){var n=t.parent,o=s.find('ul[data-id="'+n+'"]');return o.length?void o.append(a(t)):void e.push(t)}),t=e}}function n(t){var a="";a=t.comments.length?'<div class="thread"><header><nav class="nav clearfix"><ul><li class="nav-tab tab-conversation active"><a class="publisher-nav-color"><span>'+t.total+' </span>Comments</span></a></li></ul></nav></header><section><div class="thread-tips">本模式仅提供基础浏览功能。如需发表评论请<a href="#disqus_thread">点击这里</a>(请确保你能流畅访问 disq.us | disquscdn.com | disqus.com)</div></section><section><ul class="post-list" data-id="0"></ul><div class="load-more"><a href="#" class="btn">Load more comments</a></div></section></div>':'<p class="no-result">没有找到任何评论数据~<br /><br /><a href="#disqus_thread">点此发表评论 \xbb</a></p>',s.html(a)}function o(){if(!i){i=!0;var a;a=r?"/disqus/"+t.simple_config.id+"?cursor="+r:"/disqus/"+t.simple_config.id,$.get(a,{},function(a){var o;i=!1,a&&0==a.errno?(r?e(a.data.comments):(n(a.data),e(a.data.comments),$(t).trigger("hashchange","scrollIntoView")),o=s.find(".load-more a"),a.data.next?o.removeClass("busy"):o.hide(),r=a.data.next,$(t).trigger("scroll")):s.html('<p class="no-result">获取数据失败,请稍后再试!</p>')})}}var s=$("#simple_thread"),i=!1,r="";s.on("click",".load-more a",function(t){t.preventDefault(),$(this).addClass("busy"),o()}).on("click",".time-ago",function(t){t.preventDefault(),location.hash="simple-"+$(this).data("id")}),$(t).on("hashchange",function(a,e){var n,o=location.hash.match(/#(?:comment|simple)-(\d+)/);o&&(n=s.find("#post-"+o[1]),n.length&&(s.find(".post-content.target").removeClass("target"),n.find("> .post-content").addClass("target"),e&&$(t).scrollTop(n.offset().top-90)))}),/(iPhone|Android)/.test(navigator.userAgent)&&s.addClass("mobile"),t.initSimpleThread=o}(window,document),function(t,a){return"127.0.0.1"!=a.domain&&"deepzz.com"!=a.domain?void (location.href=location.href.replace(/(https?:\/\/[^\/]+)\//i,"//deepzz.com/")):(function(){var t,a=location.search.queryUrl();"1"==a.clear_ls&&(delete a.clear_ls,t=$.param(a),setTimeout(function(){t?location.search=$.param(a):location.href=location.href.replace(/\?.*$/,"")},300))}(),void $(function(){lazyLoad({selector:"#content",height:100}),function(){var t=$("#content"),a=t.find("img"),e=t.width();a.each(function(){var t=$(this),a=0|t.attr("width"),n=0|t.attr("height"),o=t.prop("complete");a>e&&t.attr("height",Math.ceil(n/a*e)),t.prop("src")&&(o?t.addClass("loaded"):t.on("load",function(){t.addClass("loaded")}))})}(),function(){if("search-post"==CURRENT_PAGE){var t=$("#keyword");t.val()||t.focus()}}(),function(){var a,e,n,o,s=$("#disqus_thread"),i=$("#simple_thread"),r=!1,c=!1,l=$("#switch_thread_mode");l.length&&(t.disqus_config=function(){this.page.url=s.data("url"),this.page.identifier=s.data("identifier"Line truncated
{{end}} {{end}}