diff options
author | GrailFinder <wohilas@gmail.com> | 2024-06-05 08:22:36 +0300 |
---|---|---|
committer | GrailFinder <wohilas@gmail.com> | 2024-06-05 08:22:36 +0300 |
commit | 01f9a9f5d71450a0c80195058245fdebe88796bd (patch) | |
tree | fd50f3fdd0585fd1ff6cf431af613fa01b86e439 | |
parent | 60fc1773241195f4988ed8066e019bbc42267085 (diff) |
Feat: recommendations for anon and user
-rw-r--r-- | components/index.html | 4 | ||||
-rw-r--r-- | components/recommendation.html | 15 | ||||
-rw-r--r-- | internal/database/repos/action.go | 8 | ||||
-rw-r--r-- | internal/handlers/elements.go | 10 | ||||
-rw-r--r-- | internal/handlers/helpers.go | 36 | ||||
-rw-r--r-- | internal/handlers/main.go | 18 | ||||
-rw-r--r-- | internal/models/models.go | 15 |
7 files changed, 77 insertions, 29 deletions
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 @@ </head> <body> <div id="ancestor"> - {{ if not . }} + {{ if not .Username }} <div> {{ template "auth" }} + {{ template "recommendation" .Recommendations}} </div> {{ else }} <div> @@ -20,6 +21,7 @@ </div> <div> {{ template "showformbtn" }} + {{ template "recommendation" .Recommendations}} </div> {{ end }} </div> 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"}} +<hr> +<h4>Recommendations</h4> +<p>Some actions used by other users for inspiration.</p> <div class="actiontable"> <p>ActionTypePlus</p> <table> @@ -6,10 +9,10 @@ <th>Name</th> <th>Magnitude</th> <th>Repeatable</th> - <th>Commit</th> + <th>Copy</th> </tr> - {{range $action := .Actions}} - {{if and (eq $action.Type "ActionTypePlus") (or (not $action.Done) ($action.Repeatable))}} + {{range $action := .}} + {{if (eq $action.Type "ActionTypePlus")}} <form hx-post="/done" hx-target="#ancestor" hx-swap="outerHTML"> <tr> <td><input class="action_name" name="name" value={{$action.Name}} type="hidden" readonly />{{$action.Name}}</td> @@ -29,9 +32,9 @@ <th>Name</th> <th>Magnitude</th> <th>Repeatable</th> - <th>Commit</th> + <th>Copy</th> </tr> - {{range $action := .Actions}} + {{range $action := .}} {{if eq $action.Type "ActionTypeMinus"}} <form hx-post="/done" hx-target="#ancestor" hx-swap="outerHTML"> <tr> 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"` |