Skip to content

Commit

Permalink
Converted log list to use cookies for most part. Global search is not…
Browse files Browse the repository at this point in the history
… global though for some reason
  • Loading branch information
fingon committed Apr 26, 2024
1 parent 25b90c8 commit 41adace
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 93 deletions.
35 changes: 26 additions & 9 deletions cm/cm.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
* Copyright (c) 2024 Markus Stenberg
*
* Created: Fri Apr 26 10:35:46 2024 mstenber
* Last modified: Fri Apr 26 14:38:05 2024 mstenber
* Edit time: 93 min
* Last modified: Fri Apr 26 21:13:04 2024 mstenber
* Edit time: 102 min
*
*/

package cm

import (
"errors"
"fmt"
"net/http"
"reflect"
Expand All @@ -22,8 +21,6 @@ type CookieSource interface {
Cookie(string) (*http.Cookie, error)
}

var ErrNoSource = errors.New("specified cookie source is nil")

func cookieName(state any) (string, error) {
v := reflect.ValueOf(state)
if v.Kind() != reflect.Pointer {
Expand All @@ -37,19 +34,39 @@ func cookieName(state any) (string, error) {
return fmt.Sprintf("cm-%s", s.Type()), nil
}

func Run(r *http.Request, w http.ResponseWriter, state any) error {
func GetWrapper(r *http.Request) (*URLWrapper, error) {
if r == nil {
return nil, nil
}
err := r.ParseForm()
if err != nil {
return err
return nil, err
}
w := URLWrapper(r.Form)
return &w, nil
}

changed, err := Parse(r, URLWrapper(r.Form), state)
func RunWrapper(s CookieSource, r *URLWrapper, w http.ResponseWriter, state any) error {
if r == nil {
return nil
}
changed, err := Parse(s, r, state)
if err != nil {
return err
}
if changed {
fmt.Printf("XXX changed\n")
return Write(w, state)
}
return nil
}

func Run(r *http.Request, w http.ResponseWriter, state any) error {
if r == nil {
return nil
}
wr, err := GetWrapper(r)
if err != nil {
return err
}
return RunWrapper(r, wr, w, state)
}
25 changes: 13 additions & 12 deletions cm/cm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
* Copyright (c) 2024 Markus Stenberg
*
* Created: Fri Apr 26 10:44:18 2024 mstenber
* Last modified: Fri Apr 26 14:39:52 2024 mstenber
* Edit time: 40 min
* Last modified: Fri Apr 26 21:16:03 2024 mstenber
* Edit time: 42 min
*
*/

Expand Down Expand Up @@ -55,23 +55,24 @@ func TestParse(t *testing.T) {
// first off, ensure the type checking is correct. anything
// else than pointer (to a struct) shouldn't work
_, err := Parse(nil, nil, nil)
assert.Assert(t, err != nil)
assert.Assert(t, err, nil)

es := empty{}
_, err = Parse(nil, nil, es)
assert.Assert(t, err != nil)
assert.Assert(t, err, nil)

sc0 := staticCookie{name: "cm-cm.empty"}

i := 42
_, err = Parse(nil, nil, &i)
_, err = Parse(&sc0, &sc0.URLWrapper, &i)
assert.Assert(t, err != nil)

// nil pointer is still error
_, err = Parse(nil, nil, &es)
assert.Equal(t, err, ErrNoSource)
_, err = Parse(&sc0, &sc0.URLWrapper, &es)
assert.Equal(t, err, nil)

// empty is fine but doesn't do anything yet
sc1 := staticCookie{name: "cm-cm.empty"}
changed, err := Parse(&sc1, sc1.URLWrapper, &es)
changed, err := Parse(&sc1, &sc1.URLWrapper, &es)
assert.Equal(t, err, nil)
assert.Equal(t, changed, false)

Expand All @@ -81,7 +82,7 @@ func TestParse(t *testing.T) {

ts := tt{}
sc2 := staticCookie{name: "cm-cm.tt"}
changed, err = Parse(&sc2, sc2.URLWrapper, &ts)
changed, err = Parse(&sc2, &sc2.URLWrapper, &ts)
assert.Equal(t, err, nil)
assert.Equal(t, changed, false)

Expand All @@ -93,7 +94,7 @@ func TestParse(t *testing.T) {
"uf": []string{"42"},
})}
assert.Equal(t, sc3.FormValue("bf"), "true")
changed, err = Parse(&sc3, sc3.URLWrapper, &ts)
changed, err = Parse(&sc3, &sc3.URLWrapper, &ts)
assert.Equal(t, err, nil)
assert.Equal(t, changed, true)
assert.Equal(t, ts.B, true)
Expand All @@ -113,7 +114,7 @@ func TestParse(t *testing.T) {
sc4 := staticCookie{name: "cm-cm.tt", cookie: cookie, err: nil}
ts4 := tt{}
fmt.Printf("!!!\n")
changed, err = Parse(&sc4, sc4.URLWrapper, &ts4)
changed, err = Parse(&sc4, &sc4.URLWrapper, &ts4)
assert.Equal(t, changed, false)
assert.Equal(t, err, nil)

Expand Down
7 changes: 3 additions & 4 deletions cm/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
* Copyright (c) 2024 Markus Stenberg
*
* Created: Fri Apr 26 14:09:03 2024 mstenber
* Last modified: Fri Apr 26 14:40:37 2024 mstenber
* Edit time: 5 min
* Last modified: Fri Apr 26 21:12:46 2024 mstenber
* Edit time: 6 min
*
*/

Expand All @@ -19,9 +19,8 @@ import (
"reflect"
)

func Parse(r CookieSource, u URLWrapper, state any) (changed bool, err error) {
func Parse(r CookieSource, u *URLWrapper, state any) (changed bool, err error) {
if r == nil {
err = ErrNoSource
return
}
name, err := cookieName(state)
Expand Down
12 changes: 7 additions & 5 deletions log.templ
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package main

import "github.com/fingon/lixie/data"
import "fmt"
import "strconv"

templ LogListRuleLink(rule *data.LogRule) {
Expand Down Expand Up @@ -101,25 +102,25 @@ templ LogList(m LogListModel) {
@Row("refresh-and-count") {
@Col(3) {
if m.Config.AutoRefresh {
<a class="btn btn-sm btn-primary" href={m.Config.WithAutoRefresh(false).ToLink()}>Turn off autorefresh</a>
<a class="btn btn-sm btn-primary" href={m.Config.ToLink2("ar=false")}>Turn off autorefresh</a>
<div hx-get={m.Config.ToLinkString()}
hx-trigger="every 1s"
hx-target="#container"
hx-select="#container" />
} else {
<a class="btn btn-sm btn-primary" href={m.Config.WithAutoRefresh(true).ToLink()}>Turn on autorefresh</a>
<a class="btn btn-sm btn-primary" href={m.Config.ToLink2("ar=true")}>Turn on autorefresh</a>
<a class="btn btn-sm btn-primary" href={m.Config.ToLink()}>Refresh</a>
}
}
@Col(2) {
<form>
<input class="form-text" type="text" name="search"
<input class="form-text" type="text" name="gsearch"
hx-trigger="change, keyup delay:200ms changed"
hx-post={m.Config.ToLinkString()}
hx-select="#logs"
hx-swap="outerHTML"
hx-target="#logs"
value={m.Config.Search} placeholder="Search for text" />
value={m.Config.Global.Search} placeholder="Search for text" />
</form>
}
@Col(5) {
Expand All @@ -130,7 +131,8 @@ templ LogList(m LogListModel) {
<a class="nav-link active bg-success-subtle" href={m.Config.ToLink()}>
{data.LogVerdictToString(verdict)} filtered</a>
} else {
<a class="nav-link" href={m.Config.WithFilter(verdict).ToLink()}>
<a class="nav-link" href={m.Config.ToLink2(
fmt.Sprintf("f=%d", verdict))}>
No {data.LogVerdictToString(verdict)}</a>
}
</li>
Expand Down
90 changes: 51 additions & 39 deletions log_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,48 +19,49 @@ import (

// This struct represents external configuration - what we can get as query/form parameters
type LogListConfig struct {
AutoRefresh bool
BeforeHash uint64
Expand uint64
Filter int
Search string
// Global configuration (cookie)
Global GlobalConfig

// Local state (cookie)
AutoRefresh bool `json:"ar" cm:"ar"`
Filter int `json:"f" cm:"f"`

// These are only handled via links
BeforeHash uint64
Expand uint64
}

const autoRefreshKey = "ar"
const expandKey = "exp"
const beforeKey = "b"
const filterKey = "f"
const searchKey = "search"

func (self *LogListConfig) Init(r cm.FormValued) error {
self.AutoRefresh = r.FormValue(autoRefreshKey) != ""
_, err := cm.Uint64FromForm(r, expandKey, &self.Expand)
func (self *LogListConfig) Init(s cm.CookieSource, wr *cm.URLWrapper, w http.ResponseWriter) error {
// Global config
err := cm.RunWrapper(s, wr, w, &self.Global)
if err != nil {
return err
}

self.Filter = data.LogVerdictSpam
_, err = cm.IntFromForm(r, filterKey, &self.Filter)
// Local config
err = cm.RunWrapper(s, wr, w, self)
if err != nil {
return err
}

_, err = cm.Uint64FromForm(r, beforeKey, &self.BeforeHash)
// Link-based state
_, err = cm.Uint64FromForm(wr, expandKey, &self.Expand)
if err != nil {
return err
}

self.Search = r.FormValue(searchKey)
_, err = cm.Uint64FromForm(wr, beforeKey, &self.BeforeHash)
if err != nil {
return err
}

// before is omitted intentionally
return nil
}

func (self LogListConfig) WithAutoRefresh(v bool) LogListConfig {
self.AutoRefresh = v
return self
}

func (self LogListConfig) WithBeforeHash(v uint64) LogListConfig {
self.BeforeHash = v
return self
Expand All @@ -71,35 +72,40 @@ func (self LogListConfig) WithExpand(v uint64) LogListConfig {
return self
}

func (self LogListConfig) WithFilter(v int) LogListConfig {
self.Filter = v
return self
}

func (self LogListConfig) ToLinkString() string {
func (self LogListConfig) ToLinkString2(extra string) string {
base := topLevelLog.Path + "/"
v := url.Values{}
// TODO: Better diffs-from-default handling
if self.AutoRefresh {
v.Set(autoRefreshKey, "1")
}

// Cookie-based stuff is handled in Init

// Link-based things start here
if self.BeforeHash != 0 {
v.Set(beforeKey, strconv.FormatUint(self.BeforeHash, 10))
}
if self.Expand != 0 {
v.Set(expandKey, strconv.FormatUint(self.Expand, 10))
}
if self.Filter != data.LogVerdictSpam {
v.Set(filterKey, strconv.Itoa(self.Filter))
switch {
case len(v) > 0 && extra != "":
return base + "?" + extra + "&" + v.Encode()
case len(v) > 0:
return base + "?" + v.Encode()
case extra != "":
return base + extra
}
if len(v) == 0 {
return base
}
return base + "?" + v.Encode()
return base
}

func (self LogListConfig) ToLinkString() string {
return self.ToLinkString2("")
}

func (self LogListConfig) ToLink2(extra string) templ.SafeURL {
return templ.URL(self.ToLinkString2(extra))
}

func (self LogListConfig) ToLink() templ.SafeURL {
return templ.URL(self.ToLinkString())
return self.ToLink2("")
}

type LogListModel struct {
Expand Down Expand Up @@ -146,7 +152,7 @@ func (self *LogListModel) Filter() {
active := self.Config.BeforeHash == 0
count := 0
allLogs := self.DB.Logs()
allLogs = filterFTS(allLogs, self.Config.Search, len(allLogs))
allLogs = filterFTS(allLogs, self.Config.Global.Search, len(allLogs))
self.TotalCount = len(allLogs)
for _, log := range allLogs {
if !active {
Expand Down Expand Up @@ -175,7 +181,13 @@ func (self *LogListModel) Filter() {
func logListHandler(db *data.Database) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
config := LogListConfig{}
err := config.Init(r)
wr, err := cm.GetWrapper(r)
if err != nil {
http.Error(w, err.Error(), 400)
return
}

err = config.Init(r, wr, w)
if err != nil {
http.Error(w, err.Error(), 400)
return
Expand Down
5 changes: 3 additions & 2 deletions log_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ import (
)

func TestLogList(t *testing.T) {
conf := LogListConfig{Expand: uint64(42), AutoRefresh: true, Filter: 7, BeforeHash: 13}
conf := LogListConfig{Expand: uint64(42), BeforeHash: 13}
s := conf.ToLinkString()
u, err := url.Parse(s)
assert.Equal(t, err, nil)

conf1 := LogListConfig{}
err = conf1.Init(cm.URLWrapper(u.Query()))
wr := cm.URLWrapper(u.Query())
err = conf1.Init(nil, &wr, nil)
assert.Equal(t, err, nil)
assert.Equal(t, conf, conf1)
}
Loading

0 comments on commit 41adace

Please sign in to comment.