diff --git a/cmd/frontend/main.go b/cmd/frontend/main.go index 55c20de..bf6431f 100644 --- a/cmd/frontend/main.go +++ b/cmd/frontend/main.go @@ -7,13 +7,28 @@ import ( "fmt" "html/template" "net/http" + "strings" ) type articleDateOrder struct {} func (ord articleDateOrder) Weight(a *model.Article) int { - return int(a.PublishDate.Unix()) * -1 + return int(a.PublishDate.Unix()) } +type articleTermFrequency struct { + terms []string +} +func (ord articleTermFrequency) Weight(a *model.Article) int { + score := 0 + for _, term := range ord.terms { + term = strings.TrimSpace(term) + if term == "" { continue } + score += strings.Count(a.Content, term) + } + return score +} + + func index(w http.ResponseWriter, req *http.Request) { fds, _ := data.NewFileDatastore("./persistence/spiegel100.json") @@ -24,9 +39,29 @@ func index(w http.ResponseWriter, req *http.Request) { _ = t.ExecuteTemplate(w, "base", articles[:10]) } +func search(w http.ResponseWriter, req *http.Request) { + // Parse the form data + err := req.ParseForm() + if err != nil { + http.Error(w, "Unable to parse form", http.StatusBadRequest) + return + } + searchTerms := strings.Split(req.FormValue("search"), " ") + + + fds, _ := data.NewFileDatastore("./persistence/spiegel100.json") + + repo, _ := data.NewDefaultRepository[*model.Article](fds, "article") + articles, _ := repo.GetByCriteria(articleTermFrequency{ terms: searchTerms }) + + t := template.Must(template.ParseFiles("templates/article.html", "templates/layout.html")) + _ = t.ExecuteTemplate(w, "base", articles) +} + func main() { // routes http.HandleFunc("/", index) + http.HandleFunc("/search", search) // serve files from the "static" directory fs := http.FileServer(http.Dir("./static")) diff --git a/internal/data/DefaultRepository.go b/internal/data/DefaultRepository.go index ddc7d73..9766753 100644 --- a/internal/data/DefaultRepository.go +++ b/internal/data/DefaultRepository.go @@ -112,24 +112,23 @@ func (repo *DefaultRepository[T]) GetById(id string) (T, error) { return obj, nil } -// Returns a slice of all elememts in the repo sort by the given an -// ISearchCriteria. Throws an error when the elememts cannot be retrieved from -// the repo. +// Returns a slice of all elememts in the repo that have a +// ISearchCriteria.Weight greater than 0 sort by that weight. Throws an error +// when the elememts cannot be retrieved from the repo. func (repo *DefaultRepository[T]) GetByCriteria(c ISortCriteria[T]) ([]T, error) { all, err := repo.GetAll() if err != nil { return nil, err } - slices.SortFunc(all, func(a, b T) int { + filtered := make([]T, 0) + for _, elem := range all { + if c.Weight(elem) > 0 { filtered = append(filtered, elem) } + } + + slices.SortFunc(filtered, func(a, b T) int { wa, wb := c.Weight(a), c.Weight(b) - switch { - case wa > wb: - return 1 - case wa < wb: - return -1 - default: - return 0 - } + if wa > wb { return -1 } + return 1 }) - return all, nil + return filtered, nil } diff --git a/templates/article.html b/templates/article.html index 0bfb650..79d9c35 100644 --- a/templates/article.html +++ b/templates/article.html @@ -1,5 +1,6 @@ {{ define "content" }} +
{{ range . }}
@@ -11,5 +12,6 @@
{{ end }} +
{{ end }} diff --git a/templates/layout.html b/templates/layout.html index 05178f4..4642a41 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -3,13 +3,14 @@ +