✨ Language's post
This commit is contained in:
parent
ad3257dabf
commit
c67a38f4bb
4
go.mod
4
go.mod
@ -64,11 +64,13 @@ require (
|
|||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
|
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
|
||||||
|
github.com/pemistahl/lingua-go v1.4.0 // indirect
|
||||||
github.com/philhofer/fwd v1.1.2 // indirect
|
github.com/philhofer/fwd v1.1.2 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/rivo/uniseg v0.4.7 // indirect
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||||
|
github.com/shopspring/decimal v1.4.0 // indirect
|
||||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||||
github.com/spf13/afero v1.11.0 // indirect
|
github.com/spf13/afero v1.11.0 // indirect
|
||||||
github.com/spf13/cast v1.6.0 // indirect
|
github.com/spf13/cast v1.6.0 // indirect
|
||||||
@ -79,7 +81,7 @@ require (
|
|||||||
github.com/valyala/fasthttp v1.52.0 // indirect
|
github.com/valyala/fasthttp v1.52.0 // indirect
|
||||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
|
golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect
|
||||||
golang.org/x/net v0.26.0 // indirect
|
golang.org/x/net v0.26.0 // indirect
|
||||||
golang.org/x/sync v0.7.0 // indirect
|
golang.org/x/sync v0.7.0 // indirect
|
||||||
golang.org/x/sys v0.21.0 // indirect
|
golang.org/x/sys v0.21.0 // indirect
|
||||||
|
6
go.sum
6
go.sum
@ -218,6 +218,8 @@ github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0Mw
|
|||||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
|
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
|
||||||
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||||
|
github.com/pemistahl/lingua-go v1.4.0 h1:ifYhthrlW7iO4icdubwlduYnmwU37V1sbNrwhKBR4rM=
|
||||||
|
github.com/pemistahl/lingua-go v1.4.0/go.mod h1:ECuM1Hp/3hvyh7k8aWSqNCPlTxLemFZsRjocUf3KgME=
|
||||||
github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw=
|
github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw=
|
||||||
github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0=
|
github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
@ -259,6 +261,8 @@ github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA=
|
|||||||
github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
|
github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
|
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
||||||
|
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||||
@ -308,6 +312,8 @@ golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
|||||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
|
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
|
||||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
|
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
|
||||||
|
golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w=
|
||||||
|
golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
@ -13,6 +13,7 @@ type Article struct {
|
|||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
|
Language string `json:"language"`
|
||||||
Tags []Tag `json:"tags" gorm:"many2many:article_tags"`
|
Tags []Tag `json:"tags" gorm:"many2many:article_tags"`
|
||||||
Categories []Category `json:"categories" gorm:"many2many:article_categories"`
|
Categories []Category `json:"categories" gorm:"many2many:article_categories"`
|
||||||
Reactions []Reaction `json:"reactions"`
|
Reactions []Reaction `json:"reactions"`
|
||||||
@ -26,7 +27,5 @@ type Article struct {
|
|||||||
AuthorID uint `json:"author_id"`
|
AuthorID uint `json:"author_id"`
|
||||||
Author Account `json:"author"`
|
Author Account `json:"author"`
|
||||||
|
|
||||||
// Dynamic Calculated Values
|
Metric PostMetric `json:"metric" gorm:"-"`
|
||||||
ReactionCount int64 `json:"reaction_count"`
|
|
||||||
ReactionList map[string]int64 `json:"reaction_list" gorm:"-"`
|
|
||||||
}
|
}
|
||||||
|
7
pkg/internal/models/metrics.go
Normal file
7
pkg/internal/models/metrics.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
type PostMetric struct {
|
||||||
|
ReplyCount int64 `json:"reply_count,omitempty"`
|
||||||
|
ReactionCount int64 `json:"reaction_count,omitempty"`
|
||||||
|
ReactionList map[string]int64 `json:"reaction_list,omitempty"`
|
||||||
|
}
|
@ -10,7 +10,8 @@ type Post struct {
|
|||||||
BaseModel
|
BaseModel
|
||||||
|
|
||||||
Alias string `json:"alias" gorm:"uniqueIndex"`
|
Alias string `json:"alias" gorm:"uniqueIndex"`
|
||||||
Content string `json:"content"`
|
Content *string `json:"content"`
|
||||||
|
Language string `json:"language"`
|
||||||
Tags []Tag `json:"tags" gorm:"many2many:post_tags"`
|
Tags []Tag `json:"tags" gorm:"many2many:post_tags"`
|
||||||
Categories []Category `json:"categories" gorm:"many2many:post_categories"`
|
Categories []Category `json:"categories" gorm:"many2many:post_categories"`
|
||||||
Reactions []Reaction `json:"reactions"`
|
Reactions []Reaction `json:"reactions"`
|
||||||
@ -29,8 +30,5 @@ type Post struct {
|
|||||||
AuthorID uint `json:"author_id"`
|
AuthorID uint `json:"author_id"`
|
||||||
Author Account `json:"author"`
|
Author Account `json:"author"`
|
||||||
|
|
||||||
// Dynamic Calculated Values
|
Metric PostMetric `json:"metric" gorm:"-"`
|
||||||
ReplyCount int64 `json:"reply_count"`
|
|
||||||
ReactionCount int64 `json:"reaction_count"`
|
|
||||||
ReactionList map[string]int64 `json:"reaction_list" gorm:"-"`
|
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,8 @@ func getArticle(c *fiber.Ctx) error {
|
|||||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
item.ReactionCount = services.CountArticleReactions(item.ID)
|
item.Metric.ReactionCount = services.CountArticleReactions(item.ID)
|
||||||
item.ReactionList, err = services.ListResourceReactions(database.C.Where("article_id = ?", item.ID))
|
item.Metric.ReactionList, err = services.ListResourceReactions(database.C.Where("article_id = ?", item.ID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,11 @@ func getPost(c *fiber.Ctx) error {
|
|||||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
item.ReplyCount = services.CountPostReply(item.ID)
|
item.Metric = models.PostMetric{
|
||||||
item.ReactionCount = services.CountPostReactions(item.ID)
|
ReplyCount: services.CountPostReply(item.ID),
|
||||||
item.ReactionList, err = services.ListResourceReactions(database.C.Where("post_id = ?", item.ID))
|
ReactionCount: services.CountPostReactions(item.ID),
|
||||||
|
}
|
||||||
|
item.Metric.ReactionList, err = services.ListResourceReactions(database.C.Where("post_id = ?", item.ID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||||
}
|
}
|
||||||
@ -139,7 +141,7 @@ func createPost(c *fiber.Ctx) error {
|
|||||||
|
|
||||||
item := models.Post{
|
item := models.Post{
|
||||||
Alias: data.Alias,
|
Alias: data.Alias,
|
||||||
Content: data.Content,
|
Content: &data.Content,
|
||||||
Tags: data.Tags,
|
Tags: data.Tags,
|
||||||
Categories: data.Categories,
|
Categories: data.Categories,
|
||||||
Attachments: data.Attachments,
|
Attachments: data.Attachments,
|
||||||
@ -218,8 +220,8 @@ func editPost(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item.Content = &data.Content
|
||||||
item.Alias = data.Alias
|
item.Alias = data.Alias
|
||||||
item.Content = data.Content
|
|
||||||
item.IsDraft = data.IsDraft
|
item.IsDraft = data.IsDraft
|
||||||
item.PublishedAt = data.PublishedAt
|
item.PublishedAt = data.PublishedAt
|
||||||
item.Tags = data.Tags
|
item.Tags = data.Tags
|
||||||
|
@ -138,7 +138,7 @@ func ListArticle(tx *gorm.DB, take int, offset int, noReact ...bool) ([]*models.
|
|||||||
|
|
||||||
for k, v := range mapping {
|
for k, v := range mapping {
|
||||||
if post, ok := itemMap[k]; ok {
|
if post, ok := itemMap[k]; ok {
|
||||||
post.ReactionList = v
|
post.Metric.ReactionList = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,6 +165,8 @@ func EnsureArticleCategoriesAndTags(item models.Article) (models.Article, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewArticle(user models.Account, item models.Article) (models.Article, error) {
|
func NewArticle(user models.Account, item models.Article) (models.Article, error) {
|
||||||
|
item.Language = DetectLanguage(&item.Content)
|
||||||
|
|
||||||
item, err := EnsureArticleCategoriesAndTags(item)
|
item, err := EnsureArticleCategoriesAndTags(item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return item, err
|
return item, err
|
||||||
@ -185,6 +187,7 @@ func NewArticle(user models.Account, item models.Article) (models.Article, error
|
|||||||
}
|
}
|
||||||
|
|
||||||
func EditArticle(item models.Article) (models.Article, error) {
|
func EditArticle(item models.Article) (models.Article, error) {
|
||||||
|
item.Language = DetectLanguage(&item.Content)
|
||||||
item, err := EnsureArticleCategoriesAndTags(item)
|
item, err := EnsureArticleCategoriesAndTags(item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return item, err
|
return item, err
|
||||||
|
18
pkg/internal/services/languages.go
Normal file
18
pkg/internal/services/languages.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pemistahl/lingua-go"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DetectLanguage(content *string) string {
|
||||||
|
if content != nil {
|
||||||
|
detector := lingua.NewLanguageDetectorBuilder().
|
||||||
|
FromLanguages(lingua.AllLanguages()...).
|
||||||
|
Build()
|
||||||
|
if lang, ok := detector.DetectLanguageOf(*content); ok {
|
||||||
|
return strings.ToLower(lang.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "unknown"
|
||||||
|
}
|
@ -167,6 +167,7 @@ func ListPost(tx *gorm.DB, take int, offset int, noReact ...bool) ([]*models.Pos
|
|||||||
}
|
}
|
||||||
|
|
||||||
idx := lo.Map(items, func(item *models.Post, index int) uint {
|
idx := lo.Map(items, func(item *models.Post, index int) uint {
|
||||||
|
item.Metric = models.PostMetric{}
|
||||||
return item.ID
|
return item.ID
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -181,7 +182,7 @@ func ListPost(tx *gorm.DB, take int, offset int, noReact ...bool) ([]*models.Pos
|
|||||||
|
|
||||||
for k, v := range mapping {
|
for k, v := range mapping {
|
||||||
if post, ok := itemMap[k]; ok {
|
if post, ok := itemMap[k]; ok {
|
||||||
post.ReactionList = v
|
post.Metric.ReactionList = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,7 +214,7 @@ func ListPost(tx *gorm.DB, take int, offset int, noReact ...bool) ([]*models.Pos
|
|||||||
|
|
||||||
for k, v := range list {
|
for k, v := range list {
|
||||||
if post, ok := itemMap[k]; ok {
|
if post, ok := itemMap[k]; ok {
|
||||||
post.ReplyCount = v
|
post.Metric.ReplyCount = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -239,6 +240,8 @@ func EnsurePostCategoriesAndTags(item models.Post) (models.Post, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewPost(user models.Account, item models.Post) (models.Post, error) {
|
func NewPost(user models.Account, item models.Post) (models.Post, error) {
|
||||||
|
item.Language = DetectLanguage(item.Content)
|
||||||
|
|
||||||
item, err := EnsurePostCategoriesAndTags(item)
|
item, err := EnsurePostCategoriesAndTags(item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return item, err
|
return item, err
|
||||||
@ -281,6 +284,7 @@ func NewPost(user models.Account, item models.Post) (models.Post, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func EditPost(item models.Post) (models.Post, error) {
|
func EditPost(item models.Post) (models.Post, error) {
|
||||||
|
item.Language = DetectLanguage(item.Content)
|
||||||
item, err := EnsurePostCategoriesAndTags(item)
|
item, err := EnsurePostCategoriesAndTags(item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return item, err
|
return item, err
|
||||||
|
Loading…
Reference in New Issue
Block a user