From 938a9e832dede8a806ea090861d60c72f7f85ae1 Mon Sep 17 00:00:00 2001 From: Timur Ismagilov Date: Mon, 12 Jul 2021 18:25:57 +0500 Subject: [PATCH] Implement primitive search Basically, it looks if the query is a substring of hypha names --- shroom/search.go | 27 +++ views/stuff.qtpl | 13 ++ views/stuff.qtpl.go | 434 +++++++++++++++++++++++++------------------- web/search.go | 32 ++++ web/web.go | 1 + 5 files changed, 320 insertions(+), 187 deletions(-) create mode 100644 shroom/search.go create mode 100644 web/search.go diff --git a/shroom/search.go b/shroom/search.go new file mode 100644 index 0000000..e9ee449 --- /dev/null +++ b/shroom/search.go @@ -0,0 +1,27 @@ +package shroom + +import ( + "strings" + + "github.com/bouncepaw/mycorrhiza/hyphae" + "github.com/bouncepaw/mycorrhiza/util" +) + +func YieldHyphaNamesContainingString(query string) <-chan string { + query = util.CanonicalName(query) + out := make(chan string) + go func() { + for h := range hyphae.YieldExistingHyphae() { + if hyphaNameMatchesString(h.Name, query) { + out <- h.Name + } + } + close(out) + }() + return out +} + +// This thing gotta be changed one day, when a hero has time to implement a good searching algorithm. +func hyphaNameMatchesString(hyphaName, query string) bool { + return strings.Contains(hyphaName, query) +} diff --git a/views/stuff.qtpl b/views/stuff.qtpl index c34753f..585adb9 100644 --- a/views/stuff.qtpl +++ b/views/stuff.qtpl @@ -44,6 +44,19 @@ {% endfunc %} +{% func PrimitiveSearchHTML(query string, generator func(string) <-chan string) %} +
+
+
    + {% for hyphaName := range generator(query) %} +
  • + {%s hyphaName %} +
  • + {% endfor %} +
+
+{% endfunc %} + {% func HelpHTML(content string) %}
diff --git a/views/stuff.qtpl.go b/views/stuff.qtpl.go index b953e4a..2315693 100644 --- a/views/stuff.qtpl.go +++ b/views/stuff.qtpl.go @@ -142,95 +142,155 @@ func BaseHTML(title, body string, u *user.User, headElements ...string) string { } //line views/stuff.qtpl:47 -func StreamHelpHTML(qw422016 *qt422016.Writer, content string) { +func StreamPrimitiveSearchHTML(qw422016 *qt422016.Writer, query string, generator func(string) <-chan string) { //line views/stuff.qtpl:47 qw422016.N().S(`
+
+
+
+`) +//line views/stuff.qtpl:58 +} + +//line views/stuff.qtpl:58 +func WritePrimitiveSearchHTML(qq422016 qtio422016.Writer, query string, generator func(string) <-chan string) { +//line views/stuff.qtpl:58 + qw422016 := qt422016.AcquireWriter(qq422016) +//line views/stuff.qtpl:58 + StreamPrimitiveSearchHTML(qw422016, query, generator) +//line views/stuff.qtpl:58 + qt422016.ReleaseWriter(qw422016) +//line views/stuff.qtpl:58 +} + +//line views/stuff.qtpl:58 +func PrimitiveSearchHTML(query string, generator func(string) <-chan string) string { +//line views/stuff.qtpl:58 + qb422016 := qt422016.AcquireByteBuffer() +//line views/stuff.qtpl:58 + WritePrimitiveSearchHTML(qb422016, query, generator) +//line views/stuff.qtpl:58 + qs422016 := string(qb422016.B) +//line views/stuff.qtpl:58 + qt422016.ReleaseByteBuffer(qb422016) +//line views/stuff.qtpl:58 + return qs422016 +//line views/stuff.qtpl:58 +} + +//line views/stuff.qtpl:60 +func StreamHelpHTML(qw422016 *qt422016.Writer, content string) { +//line views/stuff.qtpl:60 + qw422016.N().S(` +
`) -//line views/stuff.qtpl:51 +//line views/stuff.qtpl:64 qw422016.N().S(content) -//line views/stuff.qtpl:51 +//line views/stuff.qtpl:64 qw422016.N().S(`
`) -//line views/stuff.qtpl:54 +//line views/stuff.qtpl:67 qw422016.N().S(helpTopicsHTML()) -//line views/stuff.qtpl:54 +//line views/stuff.qtpl:67 qw422016.N().S(`
`) -//line views/stuff.qtpl:56 +//line views/stuff.qtpl:69 } -//line views/stuff.qtpl:56 +//line views/stuff.qtpl:69 func WriteHelpHTML(qq422016 qtio422016.Writer, content string) { -//line views/stuff.qtpl:56 +//line views/stuff.qtpl:69 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/stuff.qtpl:56 +//line views/stuff.qtpl:69 StreamHelpHTML(qw422016, content) -//line views/stuff.qtpl:56 +//line views/stuff.qtpl:69 qt422016.ReleaseWriter(qw422016) -//line views/stuff.qtpl:56 +//line views/stuff.qtpl:69 } -//line views/stuff.qtpl:56 +//line views/stuff.qtpl:69 func HelpHTML(content string) string { -//line views/stuff.qtpl:56 +//line views/stuff.qtpl:69 qb422016 := qt422016.AcquireByteBuffer() -//line views/stuff.qtpl:56 +//line views/stuff.qtpl:69 WriteHelpHTML(qb422016, content) -//line views/stuff.qtpl:56 +//line views/stuff.qtpl:69 qs422016 := string(qb422016.B) -//line views/stuff.qtpl:56 +//line views/stuff.qtpl:69 qt422016.ReleaseByteBuffer(qb422016) -//line views/stuff.qtpl:56 +//line views/stuff.qtpl:69 return qs422016 -//line views/stuff.qtpl:56 +//line views/stuff.qtpl:69 } -//line views/stuff.qtpl:58 +//line views/stuff.qtpl:71 func StreamHelpEmptyErrorHTML(qw422016 *qt422016.Writer) { -//line views/stuff.qtpl:58 +//line views/stuff.qtpl:71 qw422016.N().S(`

This entry does not exist!

Try finding a different entry that would help you.

If you want to write this entry by yourself, consider contributing to Mycorrhiza Wiki directly.

`) -//line views/stuff.qtpl:62 +//line views/stuff.qtpl:75 } -//line views/stuff.qtpl:62 +//line views/stuff.qtpl:75 func WriteHelpEmptyErrorHTML(qq422016 qtio422016.Writer) { -//line views/stuff.qtpl:62 +//line views/stuff.qtpl:75 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/stuff.qtpl:62 +//line views/stuff.qtpl:75 StreamHelpEmptyErrorHTML(qw422016) -//line views/stuff.qtpl:62 +//line views/stuff.qtpl:75 qt422016.ReleaseWriter(qw422016) -//line views/stuff.qtpl:62 +//line views/stuff.qtpl:75 } -//line views/stuff.qtpl:62 +//line views/stuff.qtpl:75 func HelpEmptyErrorHTML() string { -//line views/stuff.qtpl:62 +//line views/stuff.qtpl:75 qb422016 := qt422016.AcquireByteBuffer() -//line views/stuff.qtpl:62 +//line views/stuff.qtpl:75 WriteHelpEmptyErrorHTML(qb422016) -//line views/stuff.qtpl:62 +//line views/stuff.qtpl:75 qs422016 := string(qb422016.B) -//line views/stuff.qtpl:62 +//line views/stuff.qtpl:75 qt422016.ReleaseByteBuffer(qb422016) -//line views/stuff.qtpl:62 +//line views/stuff.qtpl:75 return qs422016 -//line views/stuff.qtpl:62 +//line views/stuff.qtpl:75 } -//line views/stuff.qtpl:64 +//line views/stuff.qtpl:77 func streamhelpTopicsHTML(qw422016 *qt422016.Writer) { -//line views/stuff.qtpl:64 +//line views/stuff.qtpl:77 qw422016.N().S(` `) -//line views/stuff.qtpl:81 +//line views/stuff.qtpl:94 } -//line views/stuff.qtpl:81 +//line views/stuff.qtpl:94 func writehelpTopicsHTML(qq422016 qtio422016.Writer) { -//line views/stuff.qtpl:81 +//line views/stuff.qtpl:94 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/stuff.qtpl:81 +//line views/stuff.qtpl:94 streamhelpTopicsHTML(qw422016) -//line views/stuff.qtpl:81 +//line views/stuff.qtpl:94 qt422016.ReleaseWriter(qw422016) -//line views/stuff.qtpl:81 +//line views/stuff.qtpl:94 } -//line views/stuff.qtpl:81 +//line views/stuff.qtpl:94 func helpTopicsHTML() string { -//line views/stuff.qtpl:81 +//line views/stuff.qtpl:94 qb422016 := qt422016.AcquireByteBuffer() -//line views/stuff.qtpl:81 +//line views/stuff.qtpl:94 writehelpTopicsHTML(qb422016) -//line views/stuff.qtpl:81 +//line views/stuff.qtpl:94 qs422016 := string(qb422016.B) -//line views/stuff.qtpl:81 +//line views/stuff.qtpl:94 qt422016.ReleaseByteBuffer(qb422016) -//line views/stuff.qtpl:81 +//line views/stuff.qtpl:94 return qs422016 -//line views/stuff.qtpl:81 +//line views/stuff.qtpl:94 } -//line views/stuff.qtpl:83 +//line views/stuff.qtpl:96 func StreamUserListHTML(qw422016 *qt422016.Writer) { -//line views/stuff.qtpl:83 +//line views/stuff.qtpl:96 qw422016.N().S(`

List of users

`) -//line views/stuff.qtpl:88 +//line views/stuff.qtpl:101 var ( admins = make([]string, 0) moderators = make([]string, 0) @@ -303,345 +363,345 @@ func StreamUserListHTML(qw422016 *qt422016.Writer) { } } -//line views/stuff.qtpl:103 +//line views/stuff.qtpl:116 qw422016.N().S(`

Admins

    `) -//line views/stuff.qtpl:106 +//line views/stuff.qtpl:119 for _, name := range admins { -//line views/stuff.qtpl:106 +//line views/stuff.qtpl:119 qw422016.N().S(`
  1. `) -//line views/stuff.qtpl:107 +//line views/stuff.qtpl:120 qw422016.E().S(name) -//line views/stuff.qtpl:107 +//line views/stuff.qtpl:120 qw422016.N().S(`
  2. `) -//line views/stuff.qtpl:108 +//line views/stuff.qtpl:121 } -//line views/stuff.qtpl:108 +//line views/stuff.qtpl:121 qw422016.N().S(`

Moderators

    `) -//line views/stuff.qtpl:112 +//line views/stuff.qtpl:125 for _, name := range moderators { -//line views/stuff.qtpl:112 +//line views/stuff.qtpl:125 qw422016.N().S(`
  1. `) -//line views/stuff.qtpl:113 +//line views/stuff.qtpl:126 qw422016.E().S(name) -//line views/stuff.qtpl:113 +//line views/stuff.qtpl:126 qw422016.N().S(`
  2. `) -//line views/stuff.qtpl:114 +//line views/stuff.qtpl:127 } -//line views/stuff.qtpl:114 +//line views/stuff.qtpl:127 qw422016.N().S(`

Editors

    `) -//line views/stuff.qtpl:118 +//line views/stuff.qtpl:131 for _, name := range editors { -//line views/stuff.qtpl:118 +//line views/stuff.qtpl:131 qw422016.N().S(`
  1. `) -//line views/stuff.qtpl:119 +//line views/stuff.qtpl:132 qw422016.E().S(name) -//line views/stuff.qtpl:119 +//line views/stuff.qtpl:132 qw422016.N().S(`
  2. `) -//line views/stuff.qtpl:120 +//line views/stuff.qtpl:133 } -//line views/stuff.qtpl:120 +//line views/stuff.qtpl:133 qw422016.N().S(`
`) -//line views/stuff.qtpl:124 +//line views/stuff.qtpl:137 } -//line views/stuff.qtpl:124 +//line views/stuff.qtpl:137 func WriteUserListHTML(qq422016 qtio422016.Writer) { -//line views/stuff.qtpl:124 +//line views/stuff.qtpl:137 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/stuff.qtpl:124 +//line views/stuff.qtpl:137 StreamUserListHTML(qw422016) -//line views/stuff.qtpl:124 +//line views/stuff.qtpl:137 qt422016.ReleaseWriter(qw422016) -//line views/stuff.qtpl:124 +//line views/stuff.qtpl:137 } -//line views/stuff.qtpl:124 +//line views/stuff.qtpl:137 func UserListHTML() string { -//line views/stuff.qtpl:124 +//line views/stuff.qtpl:137 qb422016 := qt422016.AcquireByteBuffer() -//line views/stuff.qtpl:124 +//line views/stuff.qtpl:137 WriteUserListHTML(qb422016) -//line views/stuff.qtpl:124 +//line views/stuff.qtpl:137 qs422016 := string(qb422016.B) -//line views/stuff.qtpl:124 +//line views/stuff.qtpl:137 qt422016.ReleaseByteBuffer(qb422016) -//line views/stuff.qtpl:124 +//line views/stuff.qtpl:137 return qs422016 -//line views/stuff.qtpl:124 +//line views/stuff.qtpl:137 } -//line views/stuff.qtpl:126 +//line views/stuff.qtpl:139 func StreamHyphaListHTML(qw422016 *qt422016.Writer) { -//line views/stuff.qtpl:126 +//line views/stuff.qtpl:139 qw422016.N().S(`

List of hyphae

This wiki has `) -//line views/stuff.qtpl:130 +//line views/stuff.qtpl:143 qw422016.N().D(hyphae.Count()) -//line views/stuff.qtpl:130 +//line views/stuff.qtpl:143 qw422016.N().S(` hyphae.

    `) -//line views/stuff.qtpl:132 +//line views/stuff.qtpl:145 for h := range hyphae.YieldExistingHyphae() { -//line views/stuff.qtpl:132 +//line views/stuff.qtpl:145 qw422016.N().S(`
  • `) -//line views/stuff.qtpl:134 +//line views/stuff.qtpl:147 qw422016.E().S(util.BeautifulName(h.Name)) -//line views/stuff.qtpl:134 +//line views/stuff.qtpl:147 qw422016.N().S(` `) -//line views/stuff.qtpl:135 +//line views/stuff.qtpl:148 if h.BinaryPath != "" { -//line views/stuff.qtpl:135 +//line views/stuff.qtpl:148 qw422016.N().S(` `) -//line views/stuff.qtpl:136 +//line views/stuff.qtpl:149 qw422016.E().S(filepath.Ext(h.BinaryPath)[1:]) -//line views/stuff.qtpl:136 +//line views/stuff.qtpl:149 qw422016.N().S(` `) -//line views/stuff.qtpl:137 +//line views/stuff.qtpl:150 } -//line views/stuff.qtpl:137 +//line views/stuff.qtpl:150 qw422016.N().S(`
  • `) -//line views/stuff.qtpl:139 +//line views/stuff.qtpl:152 } -//line views/stuff.qtpl:139 +//line views/stuff.qtpl:152 qw422016.N().S(`
`) -//line views/stuff.qtpl:143 +//line views/stuff.qtpl:156 } -//line views/stuff.qtpl:143 +//line views/stuff.qtpl:156 func WriteHyphaListHTML(qq422016 qtio422016.Writer) { -//line views/stuff.qtpl:143 +//line views/stuff.qtpl:156 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/stuff.qtpl:143 +//line views/stuff.qtpl:156 StreamHyphaListHTML(qw422016) -//line views/stuff.qtpl:143 +//line views/stuff.qtpl:156 qt422016.ReleaseWriter(qw422016) -//line views/stuff.qtpl:143 +//line views/stuff.qtpl:156 } -//line views/stuff.qtpl:143 +//line views/stuff.qtpl:156 func HyphaListHTML() string { -//line views/stuff.qtpl:143 +//line views/stuff.qtpl:156 qb422016 := qt422016.AcquireByteBuffer() -//line views/stuff.qtpl:143 +//line views/stuff.qtpl:156 WriteHyphaListHTML(qb422016) -//line views/stuff.qtpl:143 +//line views/stuff.qtpl:156 qs422016 := string(qb422016.B) -//line views/stuff.qtpl:143 +//line views/stuff.qtpl:156 qt422016.ReleaseByteBuffer(qb422016) -//line views/stuff.qtpl:143 +//line views/stuff.qtpl:156 return qs422016 -//line views/stuff.qtpl:143 +//line views/stuff.qtpl:156 } -//line views/stuff.qtpl:145 +//line views/stuff.qtpl:158 func StreamAboutHTML(qw422016 *qt422016.Writer) { -//line views/stuff.qtpl:145 +//line views/stuff.qtpl:158 qw422016.N().S(`

About `) -//line views/stuff.qtpl:149 +//line views/stuff.qtpl:162 qw422016.E().S(cfg.WikiName) -//line views/stuff.qtpl:149 +//line views/stuff.qtpl:162 qw422016.N().S(`

See /list for information about hyphae on this wiki.

`) -//line views/stuff.qtpl:167 +//line views/stuff.qtpl:180 } -//line views/stuff.qtpl:167 +//line views/stuff.qtpl:180 func WriteAboutHTML(qq422016 qtio422016.Writer) { -//line views/stuff.qtpl:167 +//line views/stuff.qtpl:180 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/stuff.qtpl:167 +//line views/stuff.qtpl:180 StreamAboutHTML(qw422016) -//line views/stuff.qtpl:167 +//line views/stuff.qtpl:180 qt422016.ReleaseWriter(qw422016) -//line views/stuff.qtpl:167 +//line views/stuff.qtpl:180 } -//line views/stuff.qtpl:167 +//line views/stuff.qtpl:180 func AboutHTML() string { -//line views/stuff.qtpl:167 +//line views/stuff.qtpl:180 qb422016 := qt422016.AcquireByteBuffer() -//line views/stuff.qtpl:167 +//line views/stuff.qtpl:180 WriteAboutHTML(qb422016) -//line views/stuff.qtpl:167 +//line views/stuff.qtpl:180 qs422016 := string(qb422016.B) -//line views/stuff.qtpl:167 +//line views/stuff.qtpl:180 qt422016.ReleaseByteBuffer(qb422016) -//line views/stuff.qtpl:167 +//line views/stuff.qtpl:180 return qs422016 -//line views/stuff.qtpl:167 +//line views/stuff.qtpl:180 } -//line views/stuff.qtpl:169 +//line views/stuff.qtpl:182 func StreamCommonScripts(qw422016 *qt422016.Writer) { -//line views/stuff.qtpl:169 +//line views/stuff.qtpl:182 qw422016.N().S(` `) -//line views/stuff.qtpl:170 +//line views/stuff.qtpl:183 for _, scriptPath := range cfg.CommonScripts { -//line views/stuff.qtpl:170 +//line views/stuff.qtpl:183 qw422016.N().S(` `) -//line views/stuff.qtpl:172 +//line views/stuff.qtpl:185 } -//line views/stuff.qtpl:172 +//line views/stuff.qtpl:185 qw422016.N().S(` `) -//line views/stuff.qtpl:173 +//line views/stuff.qtpl:186 } -//line views/stuff.qtpl:173 +//line views/stuff.qtpl:186 func WriteCommonScripts(qq422016 qtio422016.Writer) { -//line views/stuff.qtpl:173 +//line views/stuff.qtpl:186 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/stuff.qtpl:173 +//line views/stuff.qtpl:186 StreamCommonScripts(qw422016) -//line views/stuff.qtpl:173 +//line views/stuff.qtpl:186 qt422016.ReleaseWriter(qw422016) -//line views/stuff.qtpl:173 +//line views/stuff.qtpl:186 } -//line views/stuff.qtpl:173 +//line views/stuff.qtpl:186 func CommonScripts() string { -//line views/stuff.qtpl:173 +//line views/stuff.qtpl:186 qb422016 := qt422016.AcquireByteBuffer() -//line views/stuff.qtpl:173 +//line views/stuff.qtpl:186 WriteCommonScripts(qb422016) -//line views/stuff.qtpl:173 +//line views/stuff.qtpl:186 qs422016 := string(qb422016.B) -//line views/stuff.qtpl:173 +//line views/stuff.qtpl:186 qt422016.ReleaseByteBuffer(qb422016) -//line views/stuff.qtpl:173 +//line views/stuff.qtpl:186 return qs422016 -//line views/stuff.qtpl:173 +//line views/stuff.qtpl:186 } diff --git a/web/search.go b/web/search.go new file mode 100644 index 0000000..b99dbc6 --- /dev/null +++ b/web/search.go @@ -0,0 +1,32 @@ +package web + +import ( + "github.com/bouncepaw/mycorrhiza/shroom" + "github.com/bouncepaw/mycorrhiza/user" + "github.com/bouncepaw/mycorrhiza/views" + "io" + "net/http" + + "github.com/bouncepaw/mycorrhiza/util" +) + +func initSearch() { + http.HandleFunc("/primitive-search/", handlerPrimitiveSearch) +} + +func handlerPrimitiveSearch(w http.ResponseWriter, rq *http.Request) { + util.PrepareRq(rq) + var ( + // It just so happened that this function does what we need! Sorry for party rocking. + query = util.HyphaNameFromRq(rq, "primitive-search") + u = user.FromRequest(rq) + ) + _, _ = io.WriteString( + w, + views.BaseHTML( + "Search: "+query, + views.PrimitiveSearchHTML(query, shroom.YieldHyphaNamesContainingString), + u, + ), + ) +} diff --git a/web/web.go b/web/web.go index a2c6741..05bb4a9 100644 --- a/web/web.go +++ b/web/web.go @@ -80,6 +80,7 @@ func Init() { initAuth() initHistory() initStuff() + initSearch() // Miscellaneous http.HandleFunc("/user-list/", handlerUserList)