diff --git a/pkg/internal/grpc/feed.go b/pkg/internal/grpc/feed.go new file mode 100644 index 0000000..35c0a1c --- /dev/null +++ b/pkg/internal/grpc/feed.go @@ -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 +} diff --git a/pkg/internal/grpc/server.go b/pkg/internal/grpc/server.go index 3f23e3a..8f2f9d5 100644 --- a/pkg/internal/grpc/server.go +++ b/pkg/internal/grpc/server.go @@ -3,6 +3,7 @@ package grpc import ( "net" + iproto "git.solsynth.dev/hypernet/interactive/pkg/proto" "git.solsynth.dev/hypernet/nexus/pkg/proto" "github.com/spf13/viper" "google.golang.org/grpc" @@ -12,6 +13,7 @@ import ( type Server struct { proto.UnimplementedDirectoryServiceServer + iproto.UnimplementedFeedServiceServer health.UnimplementedHealthServer srv *grpc.Server @@ -23,6 +25,7 @@ func NewGrpc() *Server { } proto.RegisterDirectoryServiceServer(server.srv, server) + iproto.RegisterFeedServiceServer(server.srv, server) health.RegisterHealthServer(server.srv, server) reflection.Register(server.srv) diff --git a/pkg/internal/server/api/admin_api.go b/pkg/internal/server/api/admin_api.go index 1667b84..2962cb7 100644 --- a/pkg/internal/server/api/admin_api.go +++ b/pkg/internal/server/api/admin_api.go @@ -28,7 +28,7 @@ func adminTriggerScanTask(c *fiber.Ctx) error { go func() { count := 0 - for _, src := range services.NewsSources { + for _, src := range services.GetNewsSources() { if !src.Enabled { continue } diff --git a/pkg/internal/server/api/news_api.go b/pkg/internal/server/api/news_api.go index 6767185..dd587d2 100644 --- a/pkg/internal/server/api/news_api.go +++ b/pkg/internal/server/api/news_api.go @@ -56,7 +56,7 @@ func listNewsArticles(c *fiber.Ctx) error { } var sources []string - for _, srv := range services.NewsSources { + for _, srv := range services.GetNewsSources() { if !isAdvanced && srv.Advanced { continue } diff --git a/pkg/internal/server/api/well_known_api.go b/pkg/internal/server/api/well_known_api.go index ae83aad..ede7499 100644 --- a/pkg/internal/server/api/well_known_api.go +++ b/pkg/internal/server/api/well_known_api.go @@ -14,7 +14,7 @@ func getNewsSources(c *fiber.Ctx) error { 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 { return false } diff --git a/pkg/internal/services/feed.go b/pkg/internal/services/feed.go new file mode 100644 index 0000000..cbec719 --- /dev/null +++ b/pkg/internal/services/feed.go @@ -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 +} diff --git a/pkg/internal/services/reader.go b/pkg/internal/services/news.go similarity index 94% rename from pkg/internal/services/reader.go rename to pkg/internal/services/news.go index 834bbfd..6d64e3c 100644 --- a/pkg/internal/services/reader.go +++ b/pkg/internal/services/news.go @@ -17,13 +17,17 @@ import ( "gorm.io/gorm/clause" ) -var NewsSources []models.NewsSource +var newsSources []models.NewsSource + +func GetNewsSources() []models.NewsSource { + return newsSources +} func LoadNewsSources() error { - if err := viper.UnmarshalKey("sources", &NewsSources); err != nil { + if err := viper.UnmarshalKey("sources", &newsSources); err != nil { 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 } @@ -33,7 +37,7 @@ func ScanNewsSourcesNoEager() { func ScanNewsSources(eager ...bool) { count := 0 - for _, src := range NewsSources { + for _, src := range newsSources { if !src.Enabled { continue }