bilibili-backup/app/interface/main/reply/http/reply.go
2019-04-22 02:59:20 +00:00

1451 lines
36 KiB
Go
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package http
import (
"net/url"
"regexp"
"strconv"
"strings"
"go-common/app/interface/main/reply/conf"
"go-common/app/interface/main/reply/model/adminlog"
model "go-common/app/interface/main/reply/model/reply"
xmodel "go-common/app/interface/main/reply/model/xreply"
"go-common/app/interface/main/reply/service"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/xstr"
)
// regexp utf8 char 0x0e0d~0e4A
var (
_emptyUnicodeReg = []*regexp.Regexp{
regexp.MustCompile(`[\x{202e}]+`), // right-to-left override
regexp.MustCompile(`[\x{200b}]+`), // zeroWithChar
regexp.MustCompile(`[\x{1f6ab}]+`), // no_entry_sign
}
re = regexp.MustCompile(`[\x{0E0D}\x{0E4A}]+`)
_emojis = regexp.MustCompile(`\[[^\[+][^]]+]`)
// trim
returnReg = regexp.MustCompile(`[\n]{3,}`)
returnReg2 = regexp.MustCompile(`(\r\n){3,}`)
spaceReg = regexp.MustCompile(`[ ]{5,}`) // Chinese quanjiao space character
)
func isMobile(params url.Values) bool {
//return (params.Get("appkey") == "c1b107428d337928" || params.Get("appkey") == "27eb53fc9058f8c3") && len(params.Get("access_key")) == 32
return params.Get("mobi_app") != ""
}
// replyInfo get reply info by rpID.
func replyInfo(c *bm.Context) {
params := c.Request.Form
oidStr := params.Get("oid")
tpStr := params.Get("type")
rpStr := params.Get("rpid")
// check params
oid, err := strconv.ParseInt(oidStr, 10, 64)
if err != nil || oid <= 0 {
log.Warn("strconv.ParseInt(%s) error(%v)", oidStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
tp, err := strconv.ParseInt(tpStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", tpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
rpID, err := strconv.ParseInt(rpStr, 10, 64)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", rpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
rp, err := rpSvr.Reply(c, oid, int8(tp), rpID)
if err != nil {
log.Warn("rpSvr.Reply(%d, %d, %d) error(%s)", oid, tp, rpID, err)
c.JSON(nil, err)
return
}
c.JSON(rp, nil)
}
func replyMultiInfo(c *bm.Context) {
params := c.Request.Form
oidStr := params.Get("oid")
tpStr := params.Get("type")
rpStr := params.Get("rpid")
// check params
oids, err := xstr.SplitInts(oidStr)
if err != nil {
log.Warn("xstr.SplitInts(%s) err(%v)", err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
tp, err := strconv.ParseInt(tpStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", tpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
rpIDs, err := xstr.SplitInts(rpStr)
if err != nil {
log.Warn("xstr.SplintInt(%s) err(%v)", rpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if len(oids) != len(rpIDs) {
log.Warn("miss oid:%v rpid:%v", oidStr, rpStr)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
data := map[string]*model.Reply{}
for i := 0; i < len(oids); i++ {
rp, err := rpSvr.Reply(c, oids[i], int8(tp), rpIDs[i])
if err != nil {
log.Warn("rpSvr.Reply(%d, %d, %d) error(%s)", oids[i], tp, rpIDs[i], err)
continue
}
data[strconv.FormatInt(rpIDs[i], 10)] = rp
}
c.JSON(data, nil)
}
// reply range subject replies.
func reply(c *bm.Context) {
var (
showEntry = int(1)
showAdmin = int(1)
showFloor = int(1)
mid int64
sort int64
build int64
plat int64
oid int64
curPage int
err error
nohot bool
)
params := c.Request.Form
oidStr := params.Get("oid")
otypStr := params.Get("type")
sortStr := params.Get("sort")
curPageStr := params.Get("pn")
perPageStr := params.Get("ps")
nohotStr := params.Get("nohot")
platStr := params.Get("plat")
buildStr := params.Get("build")
appStr := params.Get("mobi_app")
buvid := c.Request.Header.Get("buvid")
if m, ok := c.Get("mid"); ok {
mid = m.(int64)
}
if platStr == "" {
plat = int64(model.PlatWeb)
} else {
plat, err = strconv.ParseInt(platStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(platStr %s) err(%v)", platStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
}
if buildStr != "" {
build, err = strconv.ParseInt(buildStr, 10, 64)
if err != nil {
log.Warn("strconv.ParseInt(build %s) err(%v)", buildStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
}
oid, err = strconv.ParseInt(oidStr, 10, 64)
if err != nil || oid <= 0 {
log.Warn("strconv.ParseInt(%s) error(%v)", oidStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
otyp, err := strconv.ParseInt(otypStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", otypStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if sortStr != "" {
sort, err = strconv.ParseInt(sortStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", sortStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
}
curPage, err = strconv.Atoi(curPageStr)
if err != nil || curPage < 1 {
curPage = 1
}
perPage, err := strconv.Atoi(perPageStr)
if err != nil || perPage > conf.Conf.Reply.MaxPageSize || perPage <= 0 {
perPage = conf.Conf.Reply.MaxPageSize
}
htmlEscape := true
needSndReply := true
// check android and ios appkey
if appStr != "" {
// if mobile, no html escape
htmlEscape = false
// if mobile, no return second replies of hot and top reply
if int8(sort) == model.SortByFloor {
needSndReply = false
}
}
if nohotStr != "" {
nohot, _ = strconv.ParseBool(nohotStr)
}
pageParams := &model.PageParams{
Mid: mid,
Oid: oid,
Type: int8(otyp),
Sort: int8(sort),
PageNum: curPage,
PageSize: perPage,
NeedSecond: needSndReply,
Escape: htmlEscape,
NeedHot: !nohot,
}
pageRes, err := rpSvr.RootReplies(c, pageParams)
if err != nil {
log.Warn("rpSvr.RootReplies(%+v) error(%v)", pageParams, err)
c.JSON(nil, err)
return
}
if config, _ := rpSvr.GetReplyLogConfig(c, pageRes.Subject, 1); config != nil {
showEntry = int(config.ShowEntry)
showAdmin = int(config.ShowAdmin)
}
if !rpSvr.ShowFloor(pageParams.Oid, pageParams.Type) {
showFloor = int(0)
if !isMobile(params) {
rpSvr.ResetFloor(pageRes.Roots...)
rpSvr.ResetFloor(pageRes.TopAdmin)
rpSvr.ResetFloor(pageRes.TopUpper)
rpSvr.ResetFloor(pageRes.Hots...)
}
}
rpSvr.EmojiReplace(int8(plat), build, pageRes.Roots...)
rpSvr.EmojiReplace(int8(plat), build, pageRes.TopAdmin)
rpSvr.EmojiReplace(int8(plat), build, pageRes.TopUpper)
rpSvr.EmojiReplace(int8(plat), build, pageRes.Hots...)
rpSvr.EmojiReplaceI(appStr, build, pageRes.Roots...)
rpSvr.EmojiReplaceI(appStr, build, pageRes.TopAdmin)
rpSvr.EmojiReplaceI(appStr, build, pageRes.TopUpper)
rpSvr.EmojiReplaceI(appStr, build, pageRes.Hots...)
pageRes.Roots = rpSvr.FilDelReply(pageRes.Roots)
pageRes.Hots = rpSvr.FilDelReply(pageRes.Hots)
data := map[string]interface{}{
"page": map[string]int{
"num": curPage,
"size": perPage,
"count": pageRes.Total,
"acount": pageRes.AllCount,
},
"config": map[string]int{
"showentry": showEntry,
"showadmin": showAdmin,
"showfloor": showFloor,
},
"replies": pageRes.Roots,
"hots": pageRes.Hots,
"upper": map[string]interface{}{
"mid": pageRes.Subject.Mid,
"top": pageRes.TopUpper,
},
"top": pageRes.TopAdmin,
"notice": rpSvr.RplyNotice(c, int8(plat), build, appStr, buvid),
}
if mid > 0 {
if !(rpSvr.IsWhiteAid(oid, int8(otyp))) {
if rpSvr.RelationBlocked(c, pageRes.Subject.Mid, mid) {
data["blacklist"] = 1
}
if ok, _ := rpSvr.CheckAssist(c, pageRes.Subject.Mid, mid); ok {
data["assist"] = 1
}
}
}
c.JSON(data, nil)
}
// replyReply range replies from root reply.
func replyReply(c *bm.Context) {
var (
err error
mid int64
root int64
jumpID int64
escape = true
)
params := c.Request.Form
oidStr := params.Get("oid")
tpStr := params.Get("type")
rtStr := params.Get("root")
jumpStr := params.Get("jump")
pnStr := params.Get("pn")
psStr := params.Get("ps")
midS, ok := c.Get("mid")
if !ok {
log.Warn("user no login")
mid = 0
} else {
mid = midS.(int64)
}
// check params
oid, err := strconv.ParseInt(oidStr, 10, 64)
if err != nil || oid <= 0 {
log.Warn("strconv.ParseInt(%s) error(%v)", oidStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
tp, err := strconv.ParseInt(tpStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", tpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
pn, err := strconv.Atoi(pnStr)
if err != nil || pn < 1 {
pn = 1
}
ps, err := strconv.Atoi(psStr)
if err != nil || ps > conf.Conf.Reply.MaxPageSize || ps <= 0 {
ps = conf.Conf.Reply.MaxPageSize
}
if jumpStr != "" {
if jumpID, err = strconv.ParseInt(jumpStr, 10, 64); err != nil {
log.Warn("strconv.ParseInt(jump:%s) error(%v)", jumpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
} else {
if root, err = strconv.ParseInt(rtStr, 10, 64); err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", rtStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
}
// check android and ios appkey
if isMobile(params) {
// if mobile, no html escape
escape = false
}
var config xmodel.ReplyConfig
config.ShowFloor = 1
if !rpSvr.ShowFloor(oid, int8(tp)) {
config.ShowFloor = 0
}
rs, rtRp, umid, pn, err := rpSvr.SecondReplies(c, mid, oid, root, jumpID, int8(tp), pn, ps, escape)
if err == nil {
if config.ShowFloor == 0 && !isMobile(params) {
rpSvr.ResetFloor(rs...)
rpSvr.ResetFloor(rtRp)
}
data := make(map[string]interface{}, 2)
data["page"] = map[string]int{
"num": pn,
"size": ps,
"count": rtRp.RCount,
}
data["upper"] = map[string]int64{
"mid": umid,
}
data["replies"] = rs
data["root"] = rtRp
data["config"] = config
if mid > 0 {
if !(rpSvr.IsWhiteAid(oid, int8(tp))) {
if rpSvr.RelationBlocked(c, rtRp.Mid, mid) {
data["blacklist"] = 1
}
if ok, _ := rpSvr.CheckAssist(c, umid, mid); ok {
data["assist"] = 1
}
}
}
c.JSON(data, nil)
} else {
log.Warn("rpSvr.ReplyReplies(%d, %d, %d) error(%d)", oid, root, tp, err)
c.JSON(nil, err)
}
}
func getTopics(c *bm.Context) {
var (
err error
mid int64
)
params := c.Request.Form
midStr, ok := c.Get("mid")
if ok {
mid = midStr.(int64)
} else {
midStr := params.Get("mid")
mid, err = strconv.ParseInt(midStr, 10, 64)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", midStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
}
oidStr := params.Get("oid")
tpStr := params.Get("type")
msg := params.Get("message")
tp, err := strconv.ParseInt(tpStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", tpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if !model.LegalSubjectType(int8(tp)) {
err = ecode.ReplyIllegalSubType
c.JSON(nil, err)
return
}
oid, err := strconv.ParseInt(oidStr, 10, 64)
if err != nil || oid <= 0 {
log.Warn("strconv.ParseInt(%s) error(%v)", oidStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if int8(tp) == model.SubTypeDynamic || int8(tp) == model.SubTypeLivePicture || int8(tp) == model.SubTypeLive {
data := map[string]interface{}{
"topics": []string{},
}
c.JSON(data, nil)
return
}
topics, err := rpSvr.Topics(c, mid, oid, int8(tp), msg)
if err != nil {
log.Warn("rpSvr.Topics(%d,%d,%d,%s) error(%v)", mid, oid, tp, msg, err)
topics = make([]string, 0)
}
data := map[string]interface{}{
"topics": topics,
}
c.JSON(data, nil)
}
// addReply add a reply.
func addReply(c *bm.Context) {
var (
err error
rp *model.Reply
captchaURL string
ats []int64
root, parent int64
plat int64
build int64
)
params := c.Request.Form
midStr, _ := c.Get("mid")
mid := midStr.(int64)
oidStr := params.Get("oid")
tpStr := params.Get("type")
rtStr := params.Get("root")
paStr := params.Get("parent")
atStr := params.Get("at")
msg := params.Get("message")
platStr := params.Get("plat")
device := params.Get("device")
version := params.Get("version")
captcha := params.Get("code")
ak := params.Get("access_key")
platform := params.Get("platform")
buildStr := params.Get("build")
buvid := c.Request.Header.Get("buvid")
// check params
msg = strings.TrimSpace(msg)
msg = re.ReplaceAllString(msg, " ")
msg = spaceReg.ReplaceAllString(msg, "   ")
msg = returnReg.ReplaceAllString(msg, "\n\n\n")
msg = returnReg2.ReplaceAllString(msg, "\n\n\n")
// checkout empty
for _, reg := range _emptyUnicodeReg {
msg = reg.ReplaceAllString(msg, "")
}
// check len
tmp := _emojis.ReplaceAllString(msg, "")
tmp = strings.TrimSpace(tmp)
ml := len([]rune(tmp))
if conf.Conf.Reply.MaxConLen < ml || ml < conf.Conf.Reply.MinConLen {
log.Warn("content(%s) length %d, max %d, min %d", msg, ml, conf.Conf.Reply.MaxConLen, conf.Conf.Reply.MinConLen)
err = ecode.ReplyContentOver
c.JSON(nil, err)
return
}
oid, err := strconv.ParseInt(oidStr, 10, 64)
if err != nil || oid <= 0 {
log.Warn("strconv.ParseInt(%s) error(%v)", oidStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if rtStr != "" {
root, err = strconv.ParseInt(rtStr, 10, 64)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", rtStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
}
if paStr != "" {
parent, err = strconv.ParseInt(paStr, 10, 64)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", paStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
}
if !((root == 0 && parent == 0) || (root > 0 && parent > 0)) {
log.Warn("the wrong root(%d) and parent(%d)", root, parent)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
tp, err := strconv.ParseInt(tpStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", tpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if !model.LegalSubjectType(int8(tp)) {
err = ecode.ReplyIllegalSubType
c.JSON(nil, err)
return
}
if atStr != "" {
ats, err = xstr.SplitInts(atStr)
if err != nil {
log.Warn("utils.SplitInts(%s) error(%v)", atStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
}
if len(ats) > 10 {
log.Warn("too many people to be at len(%d)", len(ats))
err = ecode.ReplyTooManyAts
c.JSON(nil, err)
return
}
if platStr != "" {
plat, err = strconv.ParseInt(platStr, 10, 8)
if err != nil || !model.CheckPlat(int8(plat)) {
log.Warn("the wrong plat(%s)", platStr)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
}
if device != "" && len([]rune(device)) > 30 {
log.Warn("device len(%d)", len([]rune(device)))
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if int8(tp) == model.SubTypeArchive {
for _, aid := range cnf.Reply.ForbidList {
if aid == oid {
err = ecode.ReplyForbidList
c.JSON(nil, err)
return
}
}
}
if buildStr != "" {
build, err = strconv.ParseInt(buildStr, 10, 64)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", buildStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
}
var status int
if status, err = rpSvr.UserBlockStatus(c, mid); err != nil {
err = ecode.ServerErr
c.JSON(nil, err)
return
}
if status == service.StatusForbidden {
// "账号被封停"
err = ecode.UserDisabled
c.JSON(nil, err)
return
}
if status == service.StatusNeedContest {
// 该账号处于封禁中,点击申请答题
err = ecode.ReplyContestNotPassed
c.JSON(nil, err)
return
}
if root == 0 && parent == 0 {
rp, captchaURL, err = rpSvr.AddReply(c, mid, oid, int8(tp), int8(plat), ats, ak, c.Request.Header.Get("Cookie"), captcha, msg, device, version, platform, build, buvid)
} else {
rp, captchaURL, err = rpSvr.AddReplyReply(c, mid, oid, root, parent, int8(tp), int8(plat), ats, ak, c.Request.Header.Get("Cookie"), captcha, msg, device, version, platform, build, buvid)
}
if err != nil && err != ecode.ReplyMosaicByFilter {
log.Warn("rpSvr.AddReply or ReplyReply failed mid(%d) oid(%d) error(%d)", mid, oid, err)
data := map[string]interface{}{
"need_captcha": (captchaURL != ""),
"url": captchaURL,
}
c.JSON(data, err)
return
}
data := map[string]interface{}{
"rpid": rp.RpID,
"rpid_str": strconv.FormatInt(rp.RpID, 10),
"dialog": rp.Dialog,
"dialog_str": strconv.FormatInt(rp.Dialog, 10),
"root": rp.Root,
"root_str": strconv.FormatInt(rp.Root, 10),
"parent": rp.Parent,
"parent_str": strconv.FormatInt(rp.Parent, 10),
}
c.JSON(data, nil)
}
// likeReply do like or cancel like for reply.
func likeReply(c *bm.Context) {
params := c.Request.Form
mid, _ := c.Get("mid")
oidStr := params.Get("oid")
tpStr := params.Get("type")
rpStr := params.Get("rpid")
actStr := params.Get("action")
ak := params.Get("access_key")
platform := params.Get("platform")
buildStr := params.Get("build")
buvid := c.Request.Header.Get("buvid")
var build int64
var err error
if buildStr != "" {
build, err = strconv.ParseInt(buildStr, 10, 64)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", buildStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
}
// check parameters
oid, err := strconv.ParseInt(oidStr, 10, 64)
if err != nil || oid <= 0 {
log.Warn("strconv.ParseInt(%s) error(%v)", oidStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
rpID, err := strconv.ParseInt(rpStr, 10, 64)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", rpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
tp, err := strconv.ParseInt(tpStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", tpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
act, err := strconv.ParseInt(actStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", actStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
err = rpSvr.AddAction(c, mid.(int64), oid, rpID, int8(tp), int8(act), ak, c.Request.Header.Get("Cookie"), "like", platform, buvid, build)
c.JSON(nil, err)
}
// hateReply do hate or cancel hate for reply.
func hateReply(c *bm.Context) {
params := c.Request.Form
mid, _ := c.Get("mid")
oidStr := params.Get("oid")
tpStr := params.Get("type")
rpStr := params.Get("rpid")
actStr := params.Get("action")
ak := params.Get("access_key")
platform := params.Get("platform")
buildStr := params.Get("build")
buvid := c.Request.Header.Get("buvid")
var build int64
var err error
if buildStr != "" {
build, err = strconv.ParseInt(buildStr, 10, 64)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", buildStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
}
// check parameters
oid, err := strconv.ParseInt(oidStr, 10, 64)
if err != nil || oid <= 0 {
log.Warn("strconv.ParseInt(%s) error(%v)", oidStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
rpID, err := strconv.ParseInt(rpStr, 10, 64)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", rpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
tp, err := strconv.ParseInt(tpStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", tpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
act, err := strconv.ParseInt(actStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", actStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
err = rpSvr.AddAction(c, mid.(int64), oid, rpID, int8(tp), int8(act), ak, c.Request.Header.Get("Cookie"), "hate", platform, buvid, build)
c.JSON(nil, err)
}
// jump to specified reply.
func jumpReply(c *bm.Context) {
var (
showEntry = int(1)
showAdmin = int(1)
mid int64
escape = true
)
params := c.Request.Form
oidStr := params.Get("oid")
tpStr := params.Get("type")
rpIDStr := params.Get("rpid")
psStr := params.Get("ps")
rppsStr := params.Get("rpps")
platStr := params.Get("plat")
buildStr := params.Get("build")
appStr := params.Get("mobi_app")
midS, ok := c.Get("mid")
buvid := c.Request.Header.Get("buvid")
if !ok {
log.Warn("user no login")
mid = 0
} else {
mid = midS.(int64)
}
// check params
plat, err := strconv.ParseInt(platStr, 10, 8)
if err != nil {
plat = 1 // default pc
}
var build int64
if buildStr != "" {
build, err = strconv.ParseInt(buildStr, 10, 64)
if err != nil {
log.Warn("strconv.ParseInt(build %s) err(%v)", buildStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
}
oid, err := strconv.ParseInt(oidStr, 10, 64)
if err != nil || oid <= 0 {
log.Warn("strconv.ParseInt(%s) error(%v)", oidStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
tp, err := strconv.ParseInt(tpStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", tpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
rpID, err := strconv.ParseInt(rpIDStr, 10, 64)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", rpIDStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
ps, _ := strconv.Atoi(psStr)
if ps > conf.Conf.Reply.MaxPageSize || ps <= 0 {
ps = conf.Conf.Reply.MaxPageSize
}
rpPs, _ := strconv.Atoi(rppsStr)
if rpPs <= 0 || rpPs > conf.Conf.Reply.MaxPageSize {
rpPs = 10
}
// check android and ios appkey
if isMobile(params) {
// if mobile, no html escape
escape = false
}
rs, hots, topAdmin, topUpper, sub, pn, rtpn, total, err := rpSvr.JumpReplies(c, mid, oid, rpID, int8(tp), ps, rpPs, escape)
if err != nil && err != ecode.ReplyNotExist {
log.Warn("rpSvr.JumpReplies(%d,%d,%d,%d) error(%d)", oid, tp, rpID, ps, err)
c.JSON(nil, err)
return
}
if err == ecode.ReplyNotExist {
var pageRes *model.PageResult
pn = 1
pageParams := &model.PageParams{
Mid: mid, Oid: oid, Type: int8(tp), Sort: model.SortByFloor, PageNum: pn, PageSize: ps, NeedHot: false, NeedSecond: false, Escape: escape,
}
if pageRes, err = rpSvr.RootReplies(c, pageParams); err != nil {
log.Warn("rpSvr.RootReplies(%d,%d,%d,%d) error(%d)", oid, tp, rpID, ps, err)
c.JSON(nil, err)
return
}
rs = pageRes.Roots
sub = pageRes.Subject
hots = pageRes.Hots
topAdmin = pageRes.TopAdmin
topUpper = pageRes.TopUpper
total = pageRes.Total
}
if config, _ := rpSvr.GetReplyLogConfig(c, sub, 1); config != nil {
showEntry = int(config.ShowEntry)
showAdmin = int(config.ShowAdmin)
}
rpSvr.EmojiReplace(int8(plat), build, hots...)
rpSvr.EmojiReplace(int8(plat), build, rs...)
rpSvr.EmojiReplace(int8(plat), build, topAdmin)
rpSvr.EmojiReplace(int8(plat), build, topUpper)
rpSvr.EmojiReplaceI(appStr, build, hots...)
rpSvr.EmojiReplaceI(appStr, build, rs...)
rpSvr.EmojiReplaceI(appStr, build, topAdmin)
rpSvr.EmojiReplaceI(appStr, build, topUpper)
data := make(map[string]interface{}, 2)
page := map[string]int{
"num": pn,
"size": ps,
"count": total,
"acount": sub.ACount,
"rt_num": rtpn,
}
configValue := map[string]int{
"showentry": showEntry,
"showadmin": showAdmin,
}
upper := map[string]interface{}{
"mid": sub.Mid,
"top": topUpper,
}
data["config"] = configValue
data["upper"] = upper
data["page"] = page
data["replies"] = rs
data["hots"] = hots
data["top"] = topAdmin
if notice := rpSvr.RplyNotice(c, int8(plat), build, appStr, buvid); notice != nil {
data["notice"] = notice
}
//NOTE donot need
// data["need_captcha"] = rpSvr.NeedCaptcha(c, mid)
c.JSON(data, nil)
}
// showReply show reply by upper.
func showReply(c *bm.Context) {
params := c.Request.Form
mid, _ := c.Get("mid")
oidsStr := params.Get("oid")
rpsStr := params.Get("rpid")
tpStr := params.Get("type")
ak := params.Get("access_key")
// check params
oids, err := xstr.SplitInts(oidsStr)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", oidsStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
rpIDs, err := xstr.SplitInts(rpsStr)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", rpsStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if len(oids) != len(rpIDs) {
log.Warn("oids(%v) not equal roids(%v)", oids, rpIDs)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
tp, err := strconv.ParseInt(tpStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", tpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if len(oids) != len(rpIDs) {
log.Warn("miss oid:%s rpid:%s", oidsStr, rpsStr)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
for i := 0; i < len(oids); i++ {
if oids[i] <= 0 {
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if err = rpSvr.Show(c, oids[i], mid.(int64), rpIDs[i], int8(tp), ak, c.Request.Header.Get("Cookie")); err != nil {
c.JSON(nil, err)
return
}
}
c.JSON(nil, nil)
}
// hideReplys hide reply by upper.
func hideReply(c *bm.Context) {
params := c.Request.Form
mid, _ := c.Get("mid")
oidsStr := params.Get("oid")
rpsStr := params.Get("rpid")
tpStr := params.Get("type")
ak := params.Get("access_key")
// check params
oids, err := xstr.SplitInts(oidsStr)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", oidsStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
rpIDs, err := xstr.SplitInts(rpsStr)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", rpsStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if len(oids) != len(rpIDs) {
log.Warn("oids(%v) not equal roids(%v)", oids, rpIDs)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
tp, err := strconv.ParseInt(tpStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", tpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if len(oids) != len(rpIDs) {
log.Warn("miss oid:%s rpid:%s", oidsStr, rpsStr)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
for i := 0; i < len(oids); i++ {
if oids[i] <= 0 {
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if err = rpSvr.Hide(c, oids[i], mid.(int64), rpIDs[i], int8(tp), ak, c.Request.Header.Get("Cookie")); err != nil {
c.JSON(nil, err)
return
}
}
c.JSON(nil, nil)
}
func replyCounts(c *bm.Context) {
params := c.Request.Form
oids, err := xstr.SplitInts(params.Get("oid"))
if err != nil {
log.Warn("sxtr.PlintInts(%v) err(%v)", params.Get("oid"), err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if len(oids) == 0 {
err = ecode.RequestErr
c.JSON(nil, err)
return
}
for i := 0; i < len(oids); i++ {
if oids[i] <= 0 {
err = ecode.RequestErr
c.JSON(nil, err)
return
}
}
otyp, err := strconv.ParseInt(params.Get("type"), 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%v) err(%v)", params.Get("type"), err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if !model.LegalSubjectType(int8(otyp)) {
err = ecode.ReplyIllegalSubType
c.JSON(nil, err)
return
}
counts, err := rpSvr.GetReplyCounts(c, oids, int8(otyp))
if err != nil {
log.Warn("rcSvr.GetReplyCount err(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(counts, nil)
}
// replyCount get replies count.
func replyMultiCount(c *bm.Context) {
params := c.Request.Form
oidsStr := params.Get("oid")
tpStr := params.Get("type")
oids, err := xstr.SplitInts(oidsStr)
if err != nil {
log.Warn("sxtr.PlintInts(%v) err(%v)", oidsStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
tp, err := strconv.ParseInt(tpStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%v) err(%v)", tpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if len(oids) == 0 {
err = ecode.RequestErr
c.JSON(nil, err)
return
}
for i := 0; i < len(oids); i++ {
if oids[i] <= 0 {
err = ecode.RequestErr
c.JSON(nil, err)
return
}
}
counts, err := rpSvr.ReplyCounts(c, oids, int8(tp))
if err != nil {
log.Warn("rcSvr.ReplyCount err(%v)", err)
c.JSON(nil, err)
return
}
c.JSON(counts, nil)
}
// replyAdminLog fetch pages of replies deleted by upper, reply user or administrators
func replyAdminLog(c *bm.Context) {
params := c.Request.Form
oidStr := params.Get("oid")
tpStr := params.Get("type")
curPageStr := params.Get("pn")
perPageStr := params.Get("ps")
// check params
oid, err := strconv.ParseInt(oidStr, 10, 64)
if err != nil || oid <= 0 {
log.Warn("strconv.ParseInt(%s) error(%v)", oidStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
tp, err := strconv.ParseInt(tpStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", tpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
curPage, err := strconv.Atoi(curPageStr)
if err != nil || curPage < 1 {
curPage = 1
}
perPage, err := strconv.Atoi(perPageStr)
if err != nil || perPage > conf.Conf.Reply.MaxPageSize || perPage <= 0 {
perPage = conf.Conf.Reply.MaxPageSize
}
if rpSvr.IsBnj(oid, int8(tp)) {
data := map[string]interface{}{
"page": map[string]int{
"num": curPage,
"size": perPage,
"pages": 0,
"total": 0,
},
"logs": make([]*adminlog.AdminLog, 0),
"reply_count": 0,
"report_count": 0,
}
c.JSON(data, nil)
return
}
logs, replyCount, reportCount, pageCount, total, err := rpSvr.PaginateUpperDeletedLogs(c, oid, int(tp), curPage, perPage)
if err != nil {
log.Warn("rpSvr.PaginateUpperDeletedLogs(%d, %d) error(%s)", oid, tp, err)
c.JSON(nil, err)
return
}
if replyCount > reportCount {
reportCount += replyCount
}
data := map[string]interface{}{
"page": map[string]int{
"num": curPage,
"size": perPage,
"pages": int(pageCount),
"total": int(total),
},
"logs": logs,
"reply_count": replyCount,
"report_count": reportCount,
}
c.JSON(data, nil)
}
// replyCount get replies count.
func replyCount(c *bm.Context) {
params := c.Request.Form
oidStr := params.Get("oid")
tpStr := params.Get("type")
// check params
oid, err := strconv.ParseInt(oidStr, 10, 64)
if err != nil || oid <= 0 {
log.Warn("strconv.ParseInt(%s) error(%v)", oidStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
tp, err := strconv.ParseInt(tpStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", tpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
count, err := rpSvr.ReplyCount(c, oid, int8(tp))
if err != nil {
c.JSON(nil, err)
return
}
data := map[string]int{"count": count}
c.JSON(data, nil)
}
// delReply delete reply by upper or self.
func delReply(c *bm.Context) {
params := c.Request.Form
mid, _ := c.Get("mid")
oidsStr := params.Get("oid")
tpStr := params.Get("type")
rpIDsStr := params.Get("rpid")
ak := params.Get("access_key")
platform := params.Get("platform")
buildStr := params.Get("build")
buvid := c.Request.Header.Get("buvid")
var build int64
var err error
// check params
if buildStr != "" {
build, err = strconv.ParseInt(buildStr, 10, 64)
if err != nil {
log.Warn("strconv.ParseInt(build %s) err(%v)", buildStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
}
oids, err := xstr.SplitInts(oidsStr)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", oidsStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
rpIDs, err := xstr.SplitInts(rpIDsStr)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", rpIDsStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
tp, err := strconv.ParseInt(tpStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", tpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if len(oids) != len(rpIDs) {
log.Warn("miss oid:%s rpid:%s", oidsStr, rpIDsStr)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
for i := 0; i < len(oids); i++ {
if oids[i] <= 0 {
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if err = rpSvr.Delete(c, mid.(int64), oids[i], rpIDs[i], int8(tp), ak, c.Request.Header.Get("Cookie"), platform, build, buvid); err != nil {
c.JSON(nil, err)
return
}
}
c.JSON(nil, nil)
}
// AddTopReply add top reply by upper
func AddTopReply(c *bm.Context) {
params := c.Request.Form
oidStr := params.Get("oid")
tpStr := params.Get("type")
rpIDStr := params.Get("rpid")
actStr := params.Get("action")
platform := params.Get("platform")
buildStr := params.Get("build")
buvid := c.Request.Header.Get("buvid")
var build int64
var err error
if buildStr != "" {
build, err = strconv.ParseInt(buildStr, 10, 64)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", buildStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
}
mid, _ := c.Get("mid")
// check params
oid, err := strconv.ParseInt(oidStr, 10, 64)
if err != nil || oid <= 0 {
log.Warn("strconv.ParseInt(%s) error(%v)", oidStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
rpID, err := strconv.ParseInt(rpIDStr, 10, 64)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", rpIDStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
tp, err := strconv.ParseInt(tpStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(%s) error(%v)", tpStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
act, err := strconv.ParseInt(actStr, 10, 8)
if err != nil {
log.Warn("strconv.ParseInt(actStr :%s) err(%v)", actStr, err)
act = 1
}
err = rpSvr.UpperAddTop(c, mid.(int64), oid, rpID, int8(tp), int8(act), platform, build, buvid)
c.JSON(nil, err)
}
// emojis
func emojis(c *bm.Context) {
params := c.Request.Form
appStr := params.Get("mobi_app")
buildStr := params.Get("build")
if buildStr != "" {
build, err := strconv.ParseInt(buildStr, 10, 64)
if err != nil {
log.Warn("strconv.ParseInt(build %s) err(%v)", buildStr, err)
err = ecode.RequestErr
c.JSON(nil, err)
return
}
if appStr == "android_i" && build > 1125000 && build < 2005000 {
c.JSON(nil, nil)
return
}
}
c.JSON(rpSvr.Emojis(c), nil)
}
func replyHots(c *bm.Context) {
params := c.Request.Form
oidStr := params.Get("oid")
typStr := params.Get("type")
pnStr := params.Get("pn")
psStr := params.Get("ps")
oid, err := strconv.ParseInt(oidStr, 10, 64)
if err != nil || oid <= 0 {
err = ecode.RequestErr
c.JSON(nil, err)
return
}
typ, err := strconv.ParseInt(typStr, 10, 8)
if err != nil {
err = ecode.RequestErr
c.JSON(nil, err)
return
}
pn, _ := strconv.Atoi(pnStr)
if pn <= 0 {
pn = 1
}
ps, _ := strconv.Atoi(psStr)
if ps > conf.Conf.Reply.MaxPageSize || ps <= 0 {
ps = 3
}
sub, rps, err := rpSvr.ReplyHots(c, oid, int8(typ), pn, ps)
if err != nil {
c.JSON(nil, err)
return
}
rps = rpSvr.FilDelReply(rps)
data := map[string]interface{}{
"page": map[string]int{
"num": pn,
"size": ps,
"count": sub.RCount,
"acount": sub.ACount,
},
"replies": rps,
}
c.JSON(data, nil)
}
func dialog(c *bm.Context) {
var (
err error
mid int64
escape = true
)
v := new(struct {
Oid int64 `form:"oid" validate:"required"`
Type int8 `form:"type" validate:"required"`
Dialog int64 `form:"dialog" validate:"required"`
Root int64 `form:"root" validate:"required"`
Pn int `form:"pn" validate:"min=1"`
Ps int `form:"ps" validate:"min=1"`
Plat string `form:"plat"`
Build string `form:"build"`
MobiApp string `form:"mobi_app"`
})
if err = c.Bind(v); err != nil {
return
}
if v.Ps > conf.Conf.Reply.MaxPageSize {
v.Ps = conf.Conf.Reply.MaxPageSize
}
midS, ok := c.Get("mid")
if !ok {
log.Warn("user no login")
} else {
mid = midS.(int64)
}
rps, err := rpSvr.Dialog(c, mid, v.Oid, v.Type, v.Root, v.Dialog, v.Pn, v.Ps, escape)
if err != nil {
c.JSON(nil, err)
return
}
data := map[string]interface{}{
"page": map[string]int{
"num": v.Pn,
"size": v.Ps,
"total": len(rps),
},
// "dialog":,
"replies": rps,
}
c.JSON(data, nil)
}
func isHotReply(c *bm.Context) {
v := new(struct {
Type int8 `form:"type" validate:"required"`
Oid int64 `form:"oid" validate:"required"`
RpID int64 `form:"rpid" validate:"required"`
})
var (
isHot bool
err error
)
if err = c.Bind(v); err != nil {
return
}
if isHot, err = rpSvr.IsHotReply(c, v.Type, v.Oid, v.RpID); err != nil {
c.JSON(nil, err)
return
}
data := map[string]bool{
"isHot": isHot,
}
c.JSON(data, nil)
}
func hotsBatch(c *bm.Context) {
v := new(struct {
Type int8 `form:"type" validate:"required"`
Oids []int64 `form:"oids,split" validate:"required"`
Size int8 `form:"size" default:"1" validate:"min=1"`
Mid int64 `form:"mid"`
})
var (
err error
)
if err = c.Bind(v); err != nil {
return
}
c.JSON(rpSvr.HotsBatch(c, v.Type, v.Size, v.Oids, v.Mid))
}