Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/interface/main/web-feed/cmd:all-srcs",
"//app/interface/main/web-feed/conf:all-srcs",
"//app/interface/main/web-feed/dao:all-srcs",
"//app/interface/main/web-feed/http:all-srcs",
"//app/interface/main/web-feed/model:all-srcs",
"//app/interface/main/web-feed/service:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,70 @@
# web-feed
##### Version 1.3.10
> 1. 去掉remote ip
##### Version 1.3.9
> 1. 使用aqm change title
##### Version 1.3.8
> 1. 使用aqm bugfix
##### Version 1.3.5
> 1. 使用aqm
##### Version 1.3.4
> 1.切换bm
##### Version 1.3.3
> 1.修改account-service v7
##### Version 1.3.2
> 1.重新请求up主信息
##### Version 1.3.1
> 1.修复cache.Save()用了外部变量
##### Version 1.3.0
> 1.接入article
##### Version 1.2.1
> 1.优化prom error
##### Version 1.2.0
> 1.接入大仓库
##### Version 1.1.12
> 1.go-business中的services加上prometheus统计
##### Version 1.1.8
> 1.fix 只对首页请求降级
##### Version 1.1.7
> 1.优化prometheus统计方式
##### Version 1.1.6
> 1.加prometheus统计
##### Version 1.1.5
> 1.支持远程灾备缓存
##### Version 1.1.4
> 1.更新vendor支持新的proms接口
##### Version 1.1.0
> 1.更新vendor支持proms
##### Version 1.0.11
> 1.更新 vendor/go-business 加入 bangumi 封面
##### Version 1.0.10
> 1.完善配置中心
##### Version 1.0.9
> 1.启用新的配置中心
##### Version 1.0.8
> 1.添加up主认证信息
##### Version 1.0.0
> 1.项目初始化

View File

@@ -0,0 +1,10 @@
# Owner
zhapuyu
liweijia
renwei
# Author
wangjian
# Reviewer
zhapuyu

View File

@@ -0,0 +1,16 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- liweijia
- renwei
- wangjian
- zhapuyu
labels:
- interface
- interface/main/web-feed
- main
options:
no_parent_owners: true
reviewers:
- wangjian
- zhapuyu

View File

@@ -0,0 +1,13 @@
# web-feed
##### 项目简介
> 1.给web端提供feed接口
##### 编译环境
> 请使用golang v1.7.x以上版本编译执行。
##### 依赖包
> 1.公共包go-common
##### 特别说明
> http接口文档可参考 http://info.bilibili.co/pages/viewpage.action?pageId=1742739

View File

@@ -0,0 +1,42 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "cmd",
embed = [":go_default_library"],
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["main.go"],
data = ["web-feed-test.toml"],
importpath = "go-common/app/interface/main/web-feed/cmd",
tags = ["automanaged"],
deps = [
"//app/interface/main/web-feed/conf:go_default_library",
"//app/interface/main/web-feed/http:go_default_library",
"//app/interface/main/web-feed/service:go_default_library",
"//library/log:go_default_library",
"//library/net/trace:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,51 @@
package main
import (
"flag"
"os"
"os/signal"
"syscall"
"time"
"go-common/app/interface/main/web-feed/conf"
"go-common/app/interface/main/web-feed/http"
"go-common/app/interface/main/web-feed/service"
"go-common/library/log"
"go-common/library/net/trace"
)
func main() {
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
// init log
log.Init(conf.Conf.Xlog)
defer log.Close()
log.Info("web-feed start")
// init trace
trace.Init(conf.Conf.Tracer)
defer trace.Close()
// service init
srv := service.New(conf.Conf)
http.Init(conf.Conf, srv)
// init pprof conf.Conf.Perf
// init signal
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
s := <-c
log.Info("web-feed get a signal %s", s.String())
switch s {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
log.Info("web-feed exit")
srv.Close()
time.Sleep(time.Second * 2)
return
case syscall.SIGHUP:
// TODO reload
default:
return
}
}
}

View File

@@ -0,0 +1,32 @@
version = "1.0.0"
user = "nobody"
pid = "/tmp/web-feed.pid"
dir = "./"
perf = "0.0.0.0:6380"
family = "web-feed"
trace = false
debug = false
[xlog]
dir = "/data/log/web-feed/"
[memcache]
name = "web-feed"
proto = "tcp"
addr = "172.16.33.54:11211"
idle = 100
active = 1000
dialTimeout = "200ms"
readTimeout = "200ms"
writeTimeout = "200ms"
idleTimeout = "80s"
feedExpire = "24h"
[bm]
addr = "0.0.0.0:6381"
maxListen = 1000
timeout = "1000ms"
[feed]
defaultSize = 20
maxSize = 200

View File

@@ -0,0 +1,38 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importpath = "go-common/app/interface/main/web-feed/conf",
tags = ["automanaged"],
deps = [
"//library/cache/memcache:go_default_library",
"//library/conf:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/middleware/auth:go_default_library",
"//library/net/rpc:go_default_library",
"//library/net/trace:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/BurntSushi/toml:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,108 @@
package conf
import (
"errors"
"flag"
"go-common/library/cache/memcache"
"go-common/library/conf"
xlog "go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/auth"
"go-common/library/net/rpc"
"go-common/library/net/trace"
xtime "go-common/library/time"
"github.com/BurntSushi/toml"
)
// Config .
type Config struct {
// Env
Env string
// App
App *bm.App
// Xlog is go-common log.
Xlog *xlog.Config
// rpc
FeedRPC *rpc.ClientConfig
AccountRPC *rpc.ClientConfig
// multihttp
BM *bm.ServerConfig
Auth *auth.Config
// tracer
Tracer *trace.Config
// feed
Feed *feed
// memcache
Memcache *mc
}
// Feed feed controls
type feed struct {
DefaultSize int
MaxSize int
}
type mc struct {
*memcache.Config
FeedExpire xtime.Duration
}
var (
confPath string
client *conf.Client
// Conf config
Conf = &Config{}
)
func init() {
flag.StringVar(&confPath, "conf", "", "config path")
}
// Init .
func Init() (err error) {
if confPath != "" {
return local()
}
return remote()
}
func local() (err error) {
_, err = toml.DecodeFile(confPath, &Conf)
return
}
func remote() (err error) {
if client, err = conf.New(); err != nil {
return
}
if err = load(); err != nil {
return
}
go func() {
for range client.Event() {
xlog.Info("config reload")
if load() != nil {
xlog.Error("config reload err")
}
}
}()
return
}
func load() (err error) {
var (
s string
ok bool
tmpConf *Config
)
if s, ok = client.Toml2(); !ok {
return errors.New("load config center error")
}
if _, err = toml.Decode(s, &tmpConf); err != nil {
return errors.New("could not decode config")
}
*Conf = *tmpConf
return
}

View File

@@ -0,0 +1,47 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["dao_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = ["//vendor/github.com/smartystreets/goconvey/convey:go_default_library"],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"memcache.go",
],
importpath = "go-common/app/interface/main/web-feed/dao",
tags = ["automanaged"],
deps = [
"//app/interface/main/web-feed/conf:go_default_library",
"//app/interface/main/web-feed/model:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/log:go_default_library",
"//library/stat/prom:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,54 @@
package dao
import (
"context"
"time"
"go-common/app/interface/main/web-feed/conf"
"go-common/library/cache/memcache"
"go-common/library/stat/prom"
)
// Dao .
type Dao struct {
c *conf.Config
mc *memcache.Pool
mcFeedExpire int32
}
var (
errorsCount = prom.BusinessErrCount
infosCount = prom.BusinessInfoCount
)
// PromError prom error
func PromError(name string) {
errorsCount.Incr(name)
}
// PromInfo add prom info
func PromInfo(name string) {
infosCount.Incr(name)
}
// New add a feed job dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
mc: memcache.NewPool(c.Memcache.Config),
mcFeedExpire: int32(time.Duration(c.Memcache.FeedExpire) / time.Second),
}
return
}
// Ping checks health of redis and mc.
func (d *Dao) Ping(c context.Context) (err error) {
return d.pingMC(c)
}
// Close closes connections of redis or mc etc.
func (d *Dao) Close() {
if d.mc != nil {
d.mc.Close()
}
}

View File

@@ -0,0 +1,22 @@
package dao
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func Test_Dao(t *testing.T) {
c := context.TODO()
mid := int64(1)
var err error
d := New(nil)
Convey("set cache", t, func() {
PromError("")
PromInfo("")
err = d.SetFeedCache(c, mid, nil)
_, err = d.FeedCache(c, mid)
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,71 @@
package dao
import (
"context"
"encoding/json"
"strconv"
"go-common/app/interface/main/web-feed/model"
"go-common/library/cache/memcache"
"go-common/library/log"
)
const (
_prefixFeed = "f_"
)
func feedKey(mid int64) string {
return _prefixFeed + strconv.FormatInt(mid, 10)
}
// pingMc ping memcache
func (d *Dao) pingMC(c context.Context) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
item := memcache.Item{Key: "ping", Value: []byte{1}, Expiration: 0}
err = conn.Set(&item)
return
}
// FeedCache gets feed cache
func (d *Dao) FeedCache(c context.Context, mid int64) (feeds []*model.Feed, err error) {
PromInfo("backup-cache")
var (
reply *memcache.Item
conn = d.mc.Get(c)
key = feedKey(mid)
)
defer conn.Close()
if reply, err = conn.Get(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
} else {
PromError("mc:获取feed缓存")
log.Error("conn.Get(%s) error(%v)", key, err)
}
return
}
err = conn.Scan(reply, &feeds)
return
}
// SetFeedCache sets feed cache
func (d *Dao) SetFeedCache(c context.Context, mid int64, feeds []*model.Feed) (err error) {
var (
bs []byte
key = feedKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if bs, err = json.Marshal(feeds); err != nil {
PromError("mc:json feed缓存")
log.Error("json.Marshal(%v) error(%v)", feeds, err)
return
}
item := &memcache.Item{Key: key, Value: bs, Expiration: d.mcFeedExpire}
if err = conn.Set(item); err != nil {
PromError("mc:设置feed缓存")
log.Error("conn.Set(%+v) error(%v)", item, err)
}
return
}

View File

@@ -0,0 +1,40 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"feed.go",
"http.go",
],
importpath = "go-common/app/interface/main/web-feed/http",
tags = ["automanaged"],
deps = [
"//app/interface/main/web-feed/conf:go_default_library",
"//app/interface/main/web-feed/model:go_default_library",
"//app/interface/main/web-feed/service:go_default_library",
"//app/interface/openplatform/article/model:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/middleware/auth:go_default_library",
"//library/net/http/blademaster/middleware/limit/aqm:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,106 @@
package http
import (
"strconv"
"time"
"go-common/app/interface/main/web-feed/conf"
"go-common/app/interface/main/web-feed/model"
artmdl "go-common/app/interface/openplatform/article/model"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
func feed(c *bm.Context) {
var (
params = c.Request.Form
pn, ps int
mid int64
feeds []*model.Feed
err error
)
pnStr := params.Get("pn")
if pn, err = strconv.Atoi(pnStr); err != nil || pn < 1 {
pn = 1
}
psStr := params.Get("ps")
if ps, err = strconv.Atoi(psStr); err != nil || ps < 1 {
ps = conf.Conf.Feed.DefaultSize
} else if ps > conf.Conf.Feed.MaxSize {
ps = conf.Conf.Feed.MaxSize
}
if midInter, ok := c.Get("mid"); ok {
mid = midInter.(int64)
}
if feeds, err = feedSrv.Feed(c, mid, pn, ps); err != nil {
log.Error("feedSrv.Feed(%d,%d,%d) error(%v)", mid, pn, ps, err)
c.JSON(nil, err)
return
}
c.JSON(feeds, err)
}
func feedUnread(c *bm.Context) {
var (
mid int64
)
if midInter, ok := c.Get("mid"); ok {
mid = midInter.(int64)
}
count, err := feedSrv.UnreadCount(c, mid)
if err != nil {
log.Error("feedSrv.UnreadCount(%d,%v) error(%v)", mid, time.Now(), err)
c.JSON(nil, err)
return
}
c.JSON(struct {
Count int `json:"count"`
}{Count: count}, nil)
}
func articleFeedUnread(c *bm.Context) {
var (
mid int64
)
if midInter, ok := c.Get("mid"); ok {
mid = midInter.(int64)
}
count, err := feedSrv.ArticleUnreadCount(c, mid)
if err != nil {
log.Error("feedSrv.ArticleUnreadCount(%d,%v) error(%v)", mid, time.Now(), err)
c.JSON(nil, err)
return
}
c.JSON(struct {
Count int `json:"count"`
}{Count: count}, nil)
}
func articleFeed(c *bm.Context) {
var (
params = c.Request.Form
pn, ps int
feeds []*artmdl.Meta
mid int64
err error
)
pnStr := params.Get("pn")
if pn, err = strconv.Atoi(pnStr); err != nil || pn < 1 {
pn = 1
}
psStr := params.Get("ps")
if ps, err = strconv.Atoi(psStr); err != nil || ps < 1 {
ps = conf.Conf.Feed.DefaultSize
} else if ps > conf.Conf.Feed.MaxSize {
ps = conf.Conf.Feed.MaxSize
}
if midInter, ok := c.Get("mid"); ok {
mid = midInter.(int64)
}
if feeds, err = feedSrv.ArticleFeed(c, mid, pn, ps); err != nil {
log.Error("feedSrv.ArticleFeed(%d,%d,%d) error(%v)", mid, pn, ps, err)
c.JSON(nil, err)
return
}
c.JSON(feeds, nil)
}

View File

@@ -0,0 +1,51 @@
package http
import (
"net/http"
"go-common/app/interface/main/web-feed/conf"
"go-common/app/interface/main/web-feed/service"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/auth"
"go-common/library/net/http/blademaster/middleware/limit/aqm"
)
var (
feedSrv *service.Service
authSvr *auth.Auth
)
// Init init
func Init(c *conf.Config, srv *service.Service) {
authSvr = auth.New(c.Auth)
feedSrv = srv
engine := bm.DefaultServer(c.BM)
outerRouter(engine)
if err := engine.Start(); err != nil {
log.Error("engine.Start error(%v)", err)
panic(err)
}
}
func outerRouter(e *bm.Engine) {
e.Ping(ping)
group := e.Group("/x/web-feed", authSvr.User)
{
group.GET("/feed", aqm.New(nil).Limit(), feed)
group.GET("/feed/unread", aqm.New(nil).Limit(), feedUnread)
art := group.Group("/article")
{
art.GET("/feed", aqm.New(nil).Limit(), articleFeed)
art.GET("/unread", aqm.New(nil).Limit(), articleFeedUnread)
}
}
}
// Ping check server ok.
func ping(c *bm.Context) {
if err := feedSrv.Ping(c); err != nil {
log.Error("web-feed ping error(%v)", err)
c.AbortWithStatus(http.StatusServiceUnavailable)
}
}

View File

@@ -0,0 +1,31 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["model.go"],
importpath = "go-common/app/interface/main/web-feed/model",
tags = ["automanaged"],
deps = [
"//app/service/main/account/api:go_default_library",
"//app/service/main/feed/model:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,12 @@
package model
import (
accv1 "go-common/app/service/main/account/api"
feedmdl "go-common/app/service/main/feed/model"
)
// Feed feed
type Feed struct {
*feedmdl.Feed
OfficialVerify *accv1.OfficialInfo `json:"official_verify,omitempty"`
}

View File

@@ -0,0 +1,57 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["feed_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/web-feed/conf:go_default_library",
"//app/interface/main/web-feed/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"feed.go",
"service.go",
],
importpath = "go-common/app/interface/main/web-feed/service",
tags = ["automanaged"],
deps = [
"//app/interface/main/web-feed/conf:go_default_library",
"//app/interface/main/web-feed/dao:go_default_library",
"//app/interface/main/web-feed/model:go_default_library",
"//app/interface/openplatform/article/model:go_default_library",
"//app/service/main/account/model:go_default_library",
"//app/service/main/account/rpc/client:go_default_library",
"//app/service/main/feed/model:go_default_library",
"//app/service/main/feed/rpc/client:go_default_library",
"//library/cache:go_default_library",
"//library/log:go_default_library",
"//library/net/metadata:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,171 @@
package service
import (
"context"
"go-common/app/interface/main/web-feed/dao"
"go-common/app/interface/main/web-feed/model"
artmdl "go-common/app/interface/openplatform/article/model"
account "go-common/app/service/main/account/model"
feedmdl "go-common/app/service/main/feed/model"
"go-common/library/log"
"go-common/library/net/metadata"
)
// Feed get feed of ups and bangumi.
func (s *Service) Feed(c context.Context, mid int64, pn, ps int) (res []*model.Feed, err error) {
var (
feeds, newFeeds []*feedmdl.Feed
upAids []int64
accRes map[int64]*account.Card
)
arg := &feedmdl.ArgFeed{
Mid: mid,
Pn: pn,
Ps: ps,
RealIP: metadata.String(c, metadata.RemoteIP),
}
if feeds, err = s.feedRPC.WebFeed(c, arg); err != nil || len(feeds) == 0 {
log.Error("s.feedRPC.WebFeed(%v) error(%v)", arg, err)
if pn == 1 {
res, err = s.dao.FeedCache(c, mid)
log.Info("s.dao.FeedCache(%d) len(%d) error(%v)", mid, len(res), err)
}
return
}
for _, item := range feeds {
if (item.Type == feedmdl.BangumiType) && (item.Bangumi == nil) {
dao.PromError("bangumi为空")
log.Error("s.feedRPC.WebFeed(%v) error(%v)", arg, err)
continue
}
if (item.Type == feedmdl.ArchiveType) && (item.Archive == nil) {
dao.PromError("archive为空")
log.Error("s.feedRPC.WebFeed(%v) error(%v)", arg, err)
continue
}
newFeeds = append(newFeeds, item)
}
feeds = newFeeds
for _, item := range feeds {
if item.Type != feedmdl.ArchiveType {
continue
}
if item.Archive != nil {
upAids = append(upAids, item.Archive.Author.Mid)
}
}
accArg := &account.ArgMids{Mids: upAids}
if accRes, err = s.accRPC.Cards3(c, accArg); err != nil {
dao.PromError("rpc:accRPC.Infos2")
log.Error("Feed s.accRPC.info(%v) error(%v)", arg, err)
err = nil
}
for _, item := range feeds {
tmp := model.Feed{Feed: item}
if tmp.Type == feedmdl.ArchiveType && accRes != nil {
if ai, ok := accRes[item.Archive.Author.Mid]; ok {
tmp.OfficialVerify = &ai.Official
}
}
res = append(res, &tmp)
}
if pn == 1 {
s.cache.Save(func() {
s.dao.SetFeedCache(context.TODO(), mid, res)
})
}
return
}
// UnreadCount get unread count of feed
func (s *Service) UnreadCount(c context.Context, mid int64) (count int, err error) {
arg := &feedmdl.ArgMid{
Mid: mid,
RealIP: metadata.String(c, metadata.RemoteIP),
}
if count, err = s.feedRPC.WebUnreadCount(c, arg); err != nil {
dao.PromError("rpc:feedRPC.WebUnreadCount")
log.Error("s.feedRPC.UnreadCount(%v) error(%v)", arg, err)
}
return
}
// ArticleUnreadCount get unread count of feed
func (s *Service) ArticleUnreadCount(c context.Context, mid int64) (count int, err error) {
arg := &feedmdl.ArgMid{
Mid: mid,
RealIP: metadata.String(c, metadata.RemoteIP),
}
if count, err = s.feedRPC.ArticleUnreadCount(c, arg); err != nil {
dao.PromError("feed:ArticleUnreadCount")
log.Error("s.feedRPC.ArticleUnreadCount(%v) error(%v)", arg, err)
}
return
}
// ArticleFeed get feed of ups and bangumi.
func (s *Service) ArticleFeed(c context.Context, mid int64, pn, ps int) (res []*artmdl.Meta, err error) {
arg := &feedmdl.ArgFeed{
Mid: mid,
Pn: pn,
Ps: ps,
RealIP: metadata.String(c, metadata.RemoteIP),
}
if res, err = s.feedRPC.ArticleFeed(c, arg); err != nil {
log.Error("s.feedRPC.ArticleFeed(%v) error(%v)", arg, err)
return
}
var mids []int64
var accRes map[int64]*account.Card
for _, meta := range res {
if meta.Author != nil {
mids = append(mids, meta.Author.Mid)
}
}
accArg := &account.ArgMids{
Mids: mids,
}
if accRes, err = s.accRPC.Cards3(c, accArg); err != nil {
dao.PromError("rpc:accRPC.Infos2")
log.Error("Feed s.accRPC.info(%v) error(%v)", arg, err)
err = nil
return
}
for _, item := range res {
if (item.Author == nil) || (accRes[item.Author.Mid] == nil) {
continue
}
info := accRes[item.Author.Mid]
item.Author = &artmdl.Author{
Mid: item.Author.Mid,
Name: info.Name,
Face: info.Face,
Pendant: artmdl.Pendant{
Pid: int32(info.Pendant.Pid),
Name: info.Pendant.Name,
Image: info.Pendant.Image,
Expire: int32(info.Pendant.Expire),
},
Nameplate: artmdl.Nameplate{
Nid: info.Nameplate.Nid,
Name: info.Nameplate.Name,
Image: info.Nameplate.Image,
ImageSmall: info.Nameplate.ImageSmall,
Level: info.Nameplate.Level,
Condition: info.Nameplate.Condition,
},
}
if info.Official.Role == 0 {
item.Author.OfficialVerify.Type = -1
} else {
if info.Official.Role <= 2 {
item.Author.OfficialVerify.Type = 0
} else {
item.Author.OfficialVerify.Type = 1
}
item.Author.OfficialVerify.Desc = info.Official.Title
}
}
return
}

View File

@@ -0,0 +1,52 @@
package service
import (
"context"
"testing"
"go-common/app/interface/main/web-feed/conf"
"go-common/app/interface/main/web-feed/model"
. "github.com/smartystreets/goconvey/convey"
)
func initConf(t *testing.T) {
if err := conf.Init(); err != nil {
t.Errorf("conf.Init() error(%v)", err)
t.FailNow()
}
}
func TestFeed(t *testing.T) {
Convey("feed", t, func() {
var (
mid int64 = 27515256
pn = 1
ps = 20
c = context.TODO()
res []*model.Feed
err error
)
initConf(t)
svr := New(conf.Conf)
if res, err = svr.Feed(c, mid, pn, ps); err != nil {
t.Error(err)
}
t.Logf("result length:%d", len(res))
})
}
func TestUnreadCount(t *testing.T) {
var (
mid int64 = 27515256
c = context.TODO()
count int
err error
)
initConf(t)
svr := New(conf.Conf)
if count, err = svr.UnreadCount(c, mid); err != nil {
t.Error(err)
}
t.Logf("count:%d", count)
}

View File

@@ -0,0 +1,42 @@
package service
import (
"context"
"go-common/app/interface/main/web-feed/conf"
"go-common/app/interface/main/web-feed/dao"
accrpc "go-common/app/service/main/account/rpc/client"
feedrpc "go-common/app/service/main/feed/rpc/client"
"go-common/library/cache"
)
// Service service struct info
type Service struct {
c *conf.Config
dao *dao.Dao
feedRPC *feedrpc.Service
accRPC *accrpc.Service3
cache *cache.Cache
}
// New .
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
dao: dao.New(c),
feedRPC: feedrpc.New(c.FeedRPC),
accRPC: accrpc.New3(c.AccountRPC),
cache: cache.New(1, 1024),
}
return s
}
// Close closes dao.
func (s *Service) Close() {
s.dao.Close()
}
// Ping is check server ping.
func (s *Service) Ping(c context.Context) (err error) {
return s.dao.Ping(c)
}