Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support search private tweet #141

Merged
merged 1 commit into from
Jun 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ release/paopao-ce --no-default-features --features sqlite3,localoss,loggerfile,r
`LocalOSS` 提供使用本地目录文件作为对象存储的功能,仅用于开发调试环境;
* 缓存: Redis/SimpleCacheIndex/BigCacheIndex
`SimpleCacheIndex` 提供简单的 广场推文列表 的缓存功能;
`BigCacheIndex` 使用[BigCache](https://github.com/allegro/bigcache)缓存 广场推文列表,缓存每个用户每一页,简单做到千人千面;
`BigCacheIndex` 使用[BigCache](https://github.com/allegro/bigcache)缓存 广场推文列表,缓存每个用户每一页,简单做到千人千面(推荐使用)
* 搜索: Zinc/Meili
`Zinc` 基于[Zinc](https://github.com/zinclabs/zinc)搜索引擎提供推文搜索服务(目前状态: 稳定,推荐使用);
`Meili` 基于[Meilisearch](https://github.com/meilisearch/meilisearch)搜索引擎提供推文搜索服务(目前状态: 内测阶段);
Expand Down
117 changes: 117 additions & 0 deletions internal/core/authority.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package core

import (
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/types"
)

const (
ActRegisterUser act = iota
ActCreatePublicTweet
ActCreatePublicAttachment
ActCreatePublicPicture
ActCreatePublicVideo
ActCreatePrivateTweet
ActCreatePrivateAttachment
ActCreatePrivatePicture
ActCreatePrivateVideo
ActCreateFriendTweet
ActCreateFriendAttachment
ActCreateFriendPicture
ActCreateFriendVideo
ActCreatePublicComment
ActCreatePublicPicureComment
ActCreateFriendComment
ActCreateFriendPicureComment
ActCreatePrivateComment
ActCreatePrivatePicureComment
ActStickTweet
ActTopTweet
ActLockTweet
ActVisibleTweet
ActDeleteTweet
ActCreateActivationCode
)

type act uint8

type FriendFilter map[int64]types.Empty

type Action struct {
Act act
UserId int64
}

type AuthorizationManageService interface {
IsAllow(user *model.User, action *Action) bool
GetFriendFilter(userId int64) FriendFilter
GetFriendIds(userId int64) []int64
}

func (f FriendFilter) IsFriend(userId int64) bool {
// _, yesno := f[userId]
// return yesno
// so, you are friend with all world now
return true
}

// IsAllow default true if user is admin
func (a act) IsAllow(user *model.User, userId int64, isFriend bool, isActivation bool) bool {
if user.IsAdmin {
return true
}
if user.ID == userId && isActivation {
switch a {
case ActCreatePublicTweet,
ActCreatePublicAttachment,
ActCreatePublicPicture,
ActCreatePublicVideo,
ActCreatePrivateTweet,
ActCreatePrivateAttachment,
ActCreatePrivatePicture,
ActCreatePrivateVideo,
ActCreateFriendTweet,
ActCreateFriendAttachment,
ActCreateFriendPicture,
ActCreateFriendVideo,
ActCreatePrivateComment,
ActCreatePrivatePicureComment,
ActStickTweet,
ActLockTweet,
ActVisibleTweet,
ActDeleteTweet:
return true
}
}

if user.ID == userId && !isActivation {
switch a {
case ActCreatePrivateTweet,
ActCreatePrivateComment,
ActStickTweet,
ActLockTweet,
ActDeleteTweet:
return true
}
}

if isFriend && isActivation {
switch a {
case ActCreatePublicComment,
ActCreatePublicPicureComment,
ActCreateFriendComment,
ActCreateFriendPicureComment:
return true
}
}

if !isFriend && isActivation {
switch a {
case ActCreatePublicComment,
ActCreatePublicPicureComment:
return true
}
}

return false
}
2 changes: 1 addition & 1 deletion internal/core/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ import (
)

type IndexPostsService interface {
IndexPosts(userId int64, offset int, limit int) ([]*model.PostFormated, error)
IndexPosts(user *model.User, offset int, limit int) ([]*model.PostFormated, error)
}
2 changes: 1 addition & 1 deletion internal/core/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@ type TweetSearchService interface {
IndexName() string
AddDocuments(documents DocItems, primaryKey ...string) (bool, error)
DeleteDocuments(identifiers []string) error
Search(q *QueryReq, offset, limit int) (*QueryResp, error)
Search(user *model.User, q *QueryReq, offset, limit int) (*QueryResp, error)
}
37 changes: 37 additions & 0 deletions internal/dao/authority.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package dao

import (
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
)

func newSimpleAuthorizationManageService() *simpleAuthorizationManageService {
return &simpleAuthorizationManageService{
db: conf.DBEngine,
}
}

func (s *simpleAuthorizationManageService) IsAllow(user *model.User, action *core.Action) bool {
// user is activation if had bind phone
isActivation := (len(user.Phone) != 0)
isFriend := s.isFriend(action.UserId)
// TODO: just use defaut act authorization chek rule now
return action.Act.IsAllow(user, action.UserId, isFriend, isActivation)
}

// GetFriendFilter _userId保留未来使用
func (s *simpleAuthorizationManageService) GetFriendFilter(_userId int64) core.FriendFilter {
// TODO: just return an empty friend fileter now
return core.FriendFilter{}
}

func (s *simpleAuthorizationManageService) GetFriendIds(_userId int64) []int64 {
// TODO: just retrun empty now
return nil
}

func (s *simpleAuthorizationManageService) isFriend(_userId int64) bool {
// friend with all world now
return true
}
2 changes: 1 addition & 1 deletion internal/dao/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type postsEntry struct {
posts []*model.PostFormated
}

type indexPostsFunc func(int64, int, int) ([]*model.PostFormated, error)
type indexPostsFunc func(*model.User, int, int) ([]*model.PostFormated, error)

type bigCacheIndexServant struct {
getIndexPosts indexPostsFunc
Expand Down
34 changes: 19 additions & 15 deletions internal/dao/cache_index_big.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,33 +49,33 @@ func newBigCacheIndexServant(getIndexPosts indexPostsFunc) *bigCacheIndexServant
return cacheIndex
}

func (s *bigCacheIndexServant) IndexPosts(userId int64, offset int, limit int) ([]*model.PostFormated, error) {
key := s.keyFrom(userId, offset, limit)
func (s *bigCacheIndexServant) IndexPosts(user *model.User, offset int, limit int) ([]*model.PostFormated, error) {
key := s.keyFrom(user, offset, limit)
posts, err := s.getPosts(key)
if err == nil {
logrus.Debugf("get index posts from cache by key: %s userId: %d offset:%d limit:%d", key, userId, offset, limit)
logrus.Debugf("bigCacheIndexServant.IndexPosts get index posts from cache by key: %s", key)
return posts, nil
}

if posts, err = s.getIndexPosts(userId, offset, limit); err != nil {
if posts, err = s.getIndexPosts(user, offset, limit); err != nil {
return nil, err
}
logrus.Debugf("get index posts from database by userId: %d offset:%d limit:%d", userId, offset, limit)
logrus.Debugf("bigCacheIndexServant.IndexPosts get index posts from database by key: %s", key)
s.cachePosts(key, posts)
return posts, nil
}

func (s *bigCacheIndexServant) getPosts(key string) ([]*model.PostFormated, error) {
data, err := s.cache.Get(key)
if err != nil {
logrus.Debugf("get posts by key: %s from cache err: %v", key, err)
logrus.Debugf("bigCacheIndexServant.getPosts get posts by key: %s from cache err: %v", key, err)
return nil, err
}
buf := bytes.NewBuffer(data)
dec := gob.NewDecoder(buf)
var posts []*model.PostFormated
if err := dec.Decode(&posts); err != nil {
logrus.Debugf("get posts from cache in decode err: %v", err)
logrus.Debugf("bigCacheIndexServant.getPosts get posts from cache in decode err: %v", err)
return nil, err
}
return posts, nil
Expand All @@ -85,10 +85,10 @@ func (s *bigCacheIndexServant) cachePosts(key string, posts []*model.PostFormate
entry := &postsEntry{key: key, posts: posts}
select {
case s.cachePostsCh <- entry:
logrus.Debugf("cachePosts by chan of key: %s", key)
logrus.Debugf("bigCacheIndexServant.cachePosts cachePosts by chan of key: %s", key)
default:
go func(ch chan<- *postsEntry, entry *postsEntry) {
logrus.Debugf("cachePosts indexAction by goroutine of key: %s", key)
logrus.Debugf("bigCacheIndexServant.cachePosts cachePosts indexAction by goroutine of key: %s", key)
ch <- entry
}(s.cachePostsCh, entry)
}
Expand All @@ -98,26 +98,30 @@ func (s *bigCacheIndexServant) setPosts(entry *postsEntry) {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
if err := enc.Encode(entry.posts); err != nil {
logrus.Debugf("setPosts encode post entry err: %v", err)
logrus.Debugf("bigCacheIndexServant.setPosts setPosts encode post entry err: %v", err)
return
}
if err := s.cache.Set(entry.key, buf.Bytes()); err != nil {
logrus.Debugf("setPosts set cache err: %v", err)
logrus.Debugf("bigCacheIndexServant.setPosts setPosts set cache err: %v", err)
}
logrus.Debugf("setPosts set cache by key: %s", entry.key)
logrus.Debugf("bigCacheIndexServant.setPosts setPosts set cache by key: %s", entry.key)
}

func (s *bigCacheIndexServant) keyFrom(userId int64, offset int, limit int) string {
func (s *bigCacheIndexServant) keyFrom(user *model.User, offset int, limit int) string {
var userId int64 = -1
if user != nil {
userId = user.ID
}
return fmt.Sprintf("index:%d:%d:%d", userId, offset, limit)
}

func (s *bigCacheIndexServant) SendAction(act core.IndexActionT) {
select {
case s.indexActionCh <- act:
logrus.Debugf("send indexAction by chan: %s", act)
logrus.Debugf("bigCacheIndexServant.SendAction send indexAction by chan: %s", act)
default:
go func(ch chan<- core.IndexActionT, act core.IndexActionT) {
logrus.Debugf("send indexAction by goroutine: %s", act)
logrus.Debugf("bigCacheIndexServant.SendAction send indexAction by goroutine: %s", act)
ch <- act
}(s.indexActionCh, act)
}
Expand Down
4 changes: 2 additions & 2 deletions internal/dao/cache_index_simple.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func newSimpleCacheIndexServant(getIndexPosts indexPostsFunc) *simpleCacheIndexS
return cacheIndex
}

func (s *simpleCacheIndexServant) IndexPosts(_userId int64, offset int, limit int) ([]*model.PostFormated, error) {
func (s *simpleCacheIndexServant) IndexPosts(_user *model.User, offset int, limit int) ([]*model.PostFormated, error) {
posts := s.atomicIndex.Load().([]*model.PostFormated)
end := offset + limit
size := len(posts)
Expand Down Expand Up @@ -79,7 +79,7 @@ func (s *simpleCacheIndexServant) startIndexPosts() {
case <-s.checkTick.C:
if len(s.indexPosts) == 0 {
logrus.Debugf("index posts by checkTick")
if s.indexPosts, err = s.getIndexPosts(0, 0, s.maxIndexSize); err == nil {
if s.indexPosts, err = s.getIndexPosts(nil, 0, s.maxIndexSize); err == nil {
s.atomicIndex.Store(s.indexPosts)
} else {
logrus.Errorf("get index posts err: %v", err)
Expand Down
29 changes: 19 additions & 10 deletions internal/dao/dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,45 @@ package dao
import (
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/zinc"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
)

var (
_ core.DataService = (*dataServant)(nil)
_ core.AttachmentCheckService = (*attachmentCheckServant)(nil)
_ core.DataService = (*dataServant)(nil)
_ core.AttachmentCheckService = (*attachmentCheckServant)(nil)
_ core.AuthorizationManageService = (*simpleAuthorizationManageService)(nil)
)

type dataServant struct {
useCacheIndex bool
cacheIndex core.CacheIndexService
useCacheIndex bool
cacheIndex core.CacheIndexService
ams core.AuthorizationManageService
engine *gorm.DB
getIndexPostsFunc indexPostsFunc
}

engine *gorm.DB
zinc *zinc.ZincClient
type simpleAuthorizationManageService struct {
db *gorm.DB
}

type attachmentCheckServant struct {
domain string
}

func NewDataService() core.DataService {
client := zinc.NewClient(conf.ZincSetting)
ds := &dataServant{
engine: conf.DBEngine,
zinc: client,
ams: NewAuthorizationManageService(),
}

// initialize CacheIndex if needed
ds.useCacheIndex = true
if conf.CfgIf("SimpleCacheIndex") {
ds.cacheIndex = newSimpleCacheIndexServant(ds.getIndexPosts)
ds.getIndexPostsFunc = ds.simpleCacheIndexGetPosts
ds.cacheIndex = newSimpleCacheIndexServant(ds.simpleCacheIndexGetPosts)
} else if conf.CfgIf("BigCacheIndex") {
ds.getIndexPostsFunc = ds.getIndexPosts
ds.cacheIndex = newBigCacheIndexServant(ds.getIndexPosts)
} else {
ds.useCacheIndex = false
Expand All @@ -49,6 +54,10 @@ func NewDataService() core.DataService {
return ds
}

func NewAuthorizationManageService() core.AuthorizationManageService {
return newSimpleAuthorizationManageService()
}

func NewAttachmentCheckService() core.AttachmentCheckService {
return &attachmentCheckServant{
domain: getOssDomain(),
Expand Down
Loading