From e117402a8506aa4bd14cfbb186e77930c88e4167 Mon Sep 17 00:00:00 2001 From: mappu Date: Sun, 13 Aug 2017 16:15:03 +1200 Subject: [PATCH] search + regexp search --- ArchiveState.go | 78 +++++++++++++++++++++++++++++++++++++++++++++---- Router.go | 23 ++++++++++++--- 2 files changed, 92 insertions(+), 9 deletions(-) diff --git a/ArchiveState.go b/ArchiveState.go index 4838cfd..54070c6 100644 --- a/ArchiveState.go +++ b/ArchiveState.go @@ -1,11 +1,14 @@ package archive import ( + "bufio" "fmt" "html/template" "io/ioutil" "math" "net/http" + "os" + "regexp" "strings" ) @@ -40,11 +43,6 @@ func (this *ArchiveState) selectSource(log *LogSource, slug string) { // - Mandatory: log, ym // - Optional: page func (this *ArchiveState) renderView(w http.ResponseWriter) { - if this.log == nil { - this.renderError(w, "Invalid log source selected") - return - } - fname, err := this.svr.LogFile(this.log, this.ym) if err != nil { this.renderError(w, err.Error()) @@ -81,6 +79,76 @@ func (this *ArchiveState) renderView(w http.ResponseWriter) { this.renderTemplate(w, []byte(output)) } +// renderSearch renders the search results. +// - Mandatory: log, query, queryIsRegex +func (this *ArchiveState) renderSearch(w http.ResponseWriter) { + + var matcher func(line string) bool + if this.queryIsRegex { + rx, err := regexp.Compile(`(?i)` + this.query) + if err != nil { + this.renderError(w, "Invalid regular expression "+this.query+" ("+err.Error()+")") + return + } + + matcher = rx.MatchString + } else { + queryLower := strings.ToLower(this.query) + matcher = func(line string) bool { + return strings.Contains(strings.ToLower(line), queryLower) + } + } + + this.renderTemplateHead(w) + totalResults := 0 + w.Write([]byte(``)) + + if totalResults == 0 { + w.Write([]byte(`No search results for "` + template.HTMLEscapeString(this.query) + `"`)) + } else { + w.Write([]byte(`
Found ` + fmt.Sprintf("%d", totalResults) + ` total result(s).

`)) + } + + this.renderTemplateFoot(w) +} + +// renderError renders a plain text string, escaping it for HTML use. func (this *ArchiveState) renderError(w http.ResponseWriter, msg string) { this.renderTemplate(w, []byte(template.HTMLEscapeString(msg))) } diff --git a/Router.go b/Router.go index 7ed9a9e..00336f5 100644 --- a/Router.go +++ b/Router.go @@ -118,12 +118,27 @@ func (this *ArchiveServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { arc.renderError(w, fmt.Sprintf("Unknown source '%s'", matches[1])) } - } else if this.rxSearch.MatchString(r.URL.Path) { - arc.renderError(w, "Not implemented.") // FIXME + } else if matches := this.rxSearch.FindStringSubmatch(r.URL.Path); len(matches) > 0 { + if ls := this.lookupSource(matches[1]); ls != nil { + arc.selectSource(ls, matches[1]) + arc.query, _ = url.QueryUnescape(matches[2]) + arc.queryIsRegex = false + arc.renderSearch(w) - } else if this.rxSearchRx.MatchString(r.URL.Path) { - arc.renderError(w, "Not implemented.") // FIXME + } else { + arc.renderError(w, fmt.Sprintf("Unknown source '%s'", matches[1])) + } + } else if matches := this.rxSearchRx.FindStringSubmatch(r.URL.Path); len(matches) > 0 { + if ls := this.lookupSource(matches[1]); ls != nil { + arc.selectSource(ls, matches[1]) + arc.query, _ = url.QueryUnescape(matches[2]) + arc.queryIsRegex = true + arc.renderSearch(w) + + } else { + arc.renderError(w, fmt.Sprintf("Unknown source '%s'", matches[1])) + } } else { arc.renderError(w, "Unknown route.")