From 01f9a9f5d71450a0c80195058245fdebe88796bd Mon Sep 17 00:00:00 2001 From: GrailFinder Date: Wed, 5 Jun 2024 08:22:36 +0300 Subject: Feat: recommendations for anon and user --- components/index.html | 4 +++- components/recommendation.html | 15 +++++++++------ internal/database/repos/action.go | 8 ++++---- internal/handlers/elements.go | 10 ++-------- internal/handlers/helpers.go | 36 ++++++++++++++++++++++++++++++++++++ internal/handlers/main.go | 18 +++++++++++++++--- internal/models/models.go | 15 ++++++++------- 7 files changed, 77 insertions(+), 29 deletions(-) create mode 100644 internal/handlers/helpers.go diff --git a/components/index.html b/components/index.html index 3693a56..a1d9293 100644 --- a/components/index.html +++ b/components/index.html @@ -10,9 +10,10 @@
- {{ if not . }} + {{ if not .Username }}
{{ template "auth" }} + {{ template "recommendation" .Recommendations}}
{{ else }}
@@ -20,6 +21,7 @@
{{ template "showformbtn" }} + {{ template "recommendation" .Recommendations}}
{{ end }}
diff --git a/components/recommendation.html b/components/recommendation.html index 5036088..17e622a 100644 --- a/components/recommendation.html +++ b/components/recommendation.html @@ -1,4 +1,7 @@ -{{define "recommentdation"}} +{{define "recommendation"}} +
+

Recommendations

+

Some actions used by other users for inspiration.

ActionTypePlus

@@ -6,10 +9,10 @@ - + - {{range $action := .Actions}} - {{if and (eq $action.Type "ActionTypePlus") (or (not $action.Done) ($action.Repeatable))}} + {{range $action := .}} + {{if (eq $action.Type "ActionTypePlus")}} @@ -29,9 +32,9 @@ - + - {{range $action := .Actions}} + {{range $action := .}} {{if eq $action.Type "ActionTypeMinus"}} diff --git a/internal/database/repos/action.go b/internal/database/repos/action.go index ab1f559..38253bc 100644 --- a/internal/database/repos/action.go +++ b/internal/database/repos/action.go @@ -8,15 +8,15 @@ type ActionRepo interface { DBActionGetByName(name string) (*models.Action, error) DBActionDone(name string) error DBActionsToReset() error - DBActionRecommend(username string, at models.ActionType) ([]models.Action, error) + DBActionRecommend(username string) ([]models.Action, error) } func (p *Provider) DBActionRecommend( - username string, at models.ActionType, + username string, ) ([]models.Action, error) { resp := []models.Action{} - query := `SELECT * FROM action WHERE username!=$1 AND type=$2 GROUP BY name LIMIT 5;` - if err := p.db.Select(&resp, query, username, at); err != nil { + query := `SELECT * FROM action WHERE name NOT IN (select name from action where username == $1) GROUP BY name LIMIT 100;` + if err := p.db.Select(&resp, query, username); err != nil { return nil, err } return resp, nil diff --git a/internal/handlers/elements.go b/internal/handlers/elements.go index 7fcd9ce..65a1c2d 100644 --- a/internal/handlers/elements.go +++ b/internal/handlers/elements.go @@ -1,7 +1,6 @@ package handlers import ( - "apjournal/internal/models" "html/template" "net/http" ) @@ -28,17 +27,12 @@ func (h *Handlers) ShowRecommended(w http.ResponseWriter, r *http.Request) { var username string // TODO: getusername // TODO: get recommendations for user - plusA, err := h.repo.DBActionRecommend(username, models.ActionTypePlus) + acts, err := h.fetchRecommendations(username, 5) if err != nil { abortWithError(w, err.Error()) return } - minusA, err := h.repo.DBActionRecommend(username, models.ActionTypeMinus) - if err != nil { - abortWithError(w, err.Error()) - return - } - h.log.Debug("got actions", "plus#", len(plusA), "minus#", len(minusA)) + h.log.Debug("got actions", "acts#", len(acts)) tmpl, err := template.ParseGlob("components/*.html") if err != nil { abortWithError(w, err.Error()) diff --git a/internal/handlers/helpers.go b/internal/handlers/helpers.go new file mode 100644 index 0000000..bc705af --- /dev/null +++ b/internal/handlers/helpers.go @@ -0,0 +1,36 @@ +package handlers + +import "apjournal/internal/models" + +func (h *Handlers) fetchRecommendations( + username string, limit int, +) ([]models.Action, error) { + actionsRes := []models.Action{} + acts, err := h.repo.DBActionRecommend(username) + if err != nil { + return nil, err + } + plusCounter := 0 + minusCounter := 0 + for _, act := range acts { + if act.Type == models.ActionTypePlus { + if plusCounter >= limit { + continue + } + actionsRes = append(actionsRes, act) + plusCounter++ + continue + } + if minusCounter >= limit { + continue + } + actionsRes = append(actionsRes, act) + minusCounter++ + if len(actionsRes) > limit*2 { + break + } + } + h.log.Debug("actions rec debug", "db_acts#", len(acts), + "res_acts#", len(actionsRes)) + return actionsRes, nil +} diff --git a/internal/handlers/main.go b/internal/handlers/main.go index e470b49..3bb194c 100644 --- a/internal/handlers/main.go +++ b/internal/handlers/main.go @@ -15,6 +15,8 @@ import ( "github.com/jmoiron/sqlx" ) +var defUS = models.UserScore{} + // Handlers structure type Handlers struct { cfg config.Config @@ -50,21 +52,26 @@ func (h *Handlers) MainPage(w http.ResponseWriter, r *http.Request) { abortWithError(w, err.Error()) return } + // get recommendations + defUS.Recommendations, err = h.fetchRecommendations("", 5) + if err != nil { + panic(err) + } usernameRaw := r.Context().Value("username") h.log.Info("got mainpage request", "username", usernameRaw) if usernameRaw == nil { - tmpl.ExecuteTemplate(w, "main", nil) + tmpl.ExecuteTemplate(w, "main", defUS) return } username := usernameRaw.(string) if username == "" { - tmpl.ExecuteTemplate(w, "main", nil) + tmpl.ExecuteTemplate(w, "main", defUS) return } userScore, err := h.repo.DBUserScoreGet(username) if err != nil { h.log.Warn("got db err", "err", err) - tmpl.ExecuteTemplate(w, "main", nil) + tmpl.ExecuteTemplate(w, "main", defUS) return } userScore.Actions, err = h.repo.DBActionList(username) @@ -72,6 +79,11 @@ func (h *Handlers) MainPage(w http.ResponseWriter, r *http.Request) { abortWithError(w, err.Error()) return } + userScore.Recommendations, err = h.fetchRecommendations(username, 5) + if err != nil { + abortWithError(w, err.Error()) + return + } tmpl.ExecuteTemplate(w, "main", userScore) } diff --git a/internal/models/models.go b/internal/models/models.go index 71fb358..5bc120b 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -11,13 +11,14 @@ const ( type ( UserScore struct { - ID uint32 `db:"id"` - Username string `db:"username"` - Password string `db:"password"` - Actions []Action - BurnTime time.Time `db:"burn_time"` - Score int8 `db:"score"` - CreatedAt time.Time `db:"created_at"` + ID uint32 `db:"id"` + Username string `db:"username"` + Password string `db:"password"` + Actions []Action + Recommendations []Action + BurnTime time.Time `db:"burn_time"` + Score int8 `db:"score"` + CreatedAt time.Time `db:"created_at"` } Action struct { ID uint32 `db:"id"` -- cgit v1.2.3
Name Magnitude RepeatableCommitCopy
{{$action.Name}}Name Magnitude RepeatableCommitCopy