✨ Interactive feed provider
This commit is contained in:
parent
ee4e7a58fe
commit
17c280ddf7
31
pkg/internal/grpc/feed.go
Normal file
31
pkg/internal/grpc/feed.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package grpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
iproto "git.solsynth.dev/hypernet/interactive/pkg/proto"
|
||||||
|
"git.solsynth.dev/hypernet/nexus/pkg/nex"
|
||||||
|
"git.solsynth.dev/hypernet/reader/pkg/internal/models"
|
||||||
|
"git.solsynth.dev/hypernet/reader/pkg/internal/services"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (v *Server) GetFeed(_ context.Context, in *iproto.GetFeedRequest) (*iproto.GetFeedResponse, error) {
|
||||||
|
limit := int(in.GetLimit())
|
||||||
|
articles, err := services.GetTodayNewsRandomly(limit, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return &iproto.GetFeedResponse{
|
||||||
|
Items: lo.Map(articles, func(item models.NewsArticle, _ int) *iproto.FeedItem {
|
||||||
|
return &iproto.FeedItem{
|
||||||
|
Type: "reader.news",
|
||||||
|
Content: nex.EncodeMap(item),
|
||||||
|
CreatedAt: uint64(item.CreatedAt.Unix()),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
}, nil
|
||||||
|
}
|
@ -3,6 +3,7 @@ package grpc
|
|||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
iproto "git.solsynth.dev/hypernet/interactive/pkg/proto"
|
||||||
"git.solsynth.dev/hypernet/nexus/pkg/proto"
|
"git.solsynth.dev/hypernet/nexus/pkg/proto"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
@ -12,6 +13,7 @@ import (
|
|||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
proto.UnimplementedDirectoryServiceServer
|
proto.UnimplementedDirectoryServiceServer
|
||||||
|
iproto.UnimplementedFeedServiceServer
|
||||||
health.UnimplementedHealthServer
|
health.UnimplementedHealthServer
|
||||||
|
|
||||||
srv *grpc.Server
|
srv *grpc.Server
|
||||||
@ -23,6 +25,7 @@ func NewGrpc() *Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proto.RegisterDirectoryServiceServer(server.srv, server)
|
proto.RegisterDirectoryServiceServer(server.srv, server)
|
||||||
|
iproto.RegisterFeedServiceServer(server.srv, server)
|
||||||
health.RegisterHealthServer(server.srv, server)
|
health.RegisterHealthServer(server.srv, server)
|
||||||
|
|
||||||
reflection.Register(server.srv)
|
reflection.Register(server.srv)
|
||||||
|
@ -28,7 +28,7 @@ func adminTriggerScanTask(c *fiber.Ctx) error {
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
count := 0
|
count := 0
|
||||||
for _, src := range services.NewsSources {
|
for _, src := range services.GetNewsSources() {
|
||||||
if !src.Enabled {
|
if !src.Enabled {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ func listNewsArticles(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var sources []string
|
var sources []string
|
||||||
for _, srv := range services.NewsSources {
|
for _, srv := range services.GetNewsSources() {
|
||||||
if !isAdvanced && srv.Advanced {
|
if !isAdvanced && srv.Advanced {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ func getNewsSources(c *fiber.Ctx) error {
|
|||||||
isAdvanced = true
|
isAdvanced = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(lo.Filter(services.NewsSources, func(item models.NewsSource, index int) bool {
|
return c.JSON(lo.Filter(services.GetNewsSources(), func(item models.NewsSource, index int) bool {
|
||||||
if !isAdvanced && item.Advanced {
|
if !isAdvanced && item.Advanced {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
26
pkg/internal/services/feed.go
Normal file
26
pkg/internal/services/feed.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.solsynth.dev/hypernet/reader/pkg/internal/database"
|
||||||
|
"git.solsynth.dev/hypernet/reader/pkg/internal/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetTodayNewsRandomly(limit int, isAdvanced bool) ([]models.NewsArticle, error) {
|
||||||
|
var sources []string
|
||||||
|
for _, srv := range GetNewsSources() {
|
||||||
|
if !isAdvanced && srv.Advanced {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sources = append(sources, srv.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
var articles []models.NewsArticle
|
||||||
|
if err := database.C.Limit(limit).
|
||||||
|
Where("source IN ?", sources).
|
||||||
|
Where("DATE(created_at) = CURRENT_DATE"). // Created in today
|
||||||
|
Order("RANDOM()").
|
||||||
|
Find(&articles).Error; err != nil {
|
||||||
|
return articles, err
|
||||||
|
}
|
||||||
|
return articles, nil
|
||||||
|
}
|
@ -17,13 +17,17 @@ import (
|
|||||||
"gorm.io/gorm/clause"
|
"gorm.io/gorm/clause"
|
||||||
)
|
)
|
||||||
|
|
||||||
var NewsSources []models.NewsSource
|
var newsSources []models.NewsSource
|
||||||
|
|
||||||
|
func GetNewsSources() []models.NewsSource {
|
||||||
|
return newsSources
|
||||||
|
}
|
||||||
|
|
||||||
func LoadNewsSources() error {
|
func LoadNewsSources() error {
|
||||||
if err := viper.UnmarshalKey("sources", &NewsSources); err != nil {
|
if err := viper.UnmarshalKey("sources", &newsSources); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Info().Int("count", len(NewsSources)).Msg("Loaded news sources configuration.")
|
log.Info().Int("count", len(newsSources)).Msg("Loaded news sources configuration.")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +37,7 @@ func ScanNewsSourcesNoEager() {
|
|||||||
|
|
||||||
func ScanNewsSources(eager ...bool) {
|
func ScanNewsSources(eager ...bool) {
|
||||||
count := 0
|
count := 0
|
||||||
for _, src := range NewsSources {
|
for _, src := range newsSources {
|
||||||
if !src.Enabled {
|
if !src.Enabled {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user