kopia lustrzana https://github.com/cblgh/lieu
finalize fts + ui
rodzic
793a9867cc
commit
bd03b61420
|
@ -69,7 +69,7 @@ func createTables(db *sql.DB) {
|
||||||
url TEXT NOT NULL,
|
url TEXT NOT NULL,
|
||||||
FOREIGN KEY(url) REFERENCES pages(url)
|
FOREIGN KEY(url) REFERENCES pages(url)
|
||||||
)`,
|
)`,
|
||||||
`CREATE VIRTUAL TABLE IF NOT EXISTS external_links USING fts5 (url, tokenize="trigram")`,
|
`CREATE VIRTUAL TABLE IF NOT EXISTS external_links USING fts5 (url, tokenize="trigram")`,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, query := range queries {
|
for _, query := range queries {
|
||||||
|
@ -110,16 +110,16 @@ func FulltextSearchWords(db *sql.DB, phrase string) []types.PageData {
|
||||||
util.Check(err)
|
util.Check(err)
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
var pageData types.PageData
|
var pageData types.PageData
|
||||||
var pages []types.PageData
|
var pages []types.PageData
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
if err := rows.Scan(&pageData.URL); err != nil {
|
if err := rows.Scan(&pageData.URL); err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
pageData.Title = pageData.URL
|
pageData.Title = pageData.URL
|
||||||
pages = append(pages, pageData)
|
pages = append(pages, pageData)
|
||||||
}
|
}
|
||||||
return pages
|
return pages
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDomainCount(db *sql.DB) int {
|
func GetDomainCount(db *sql.DB) int {
|
||||||
|
|
|
@ -142,6 +142,20 @@ nav li {
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Search Results */
|
||||||
|
.result-nav-list {
|
||||||
|
display: grid;
|
||||||
|
grid-auto-flow: column;
|
||||||
|
justify-content: start;
|
||||||
|
grid-column-gap: 0.75rem;
|
||||||
|
padding-bottom: 0;
|
||||||
|
font-size: 1.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result__current {
|
||||||
|
/* font-weight: bold; */
|
||||||
|
text-decoration-line: underline;
|
||||||
|
}
|
||||||
|
|
||||||
/* Entries */
|
/* Entries */
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{{ template "head" . }}
|
{{ template "head" . }}
|
||||||
{{ template "nav" . }}
|
{{ template "nav" . }}
|
||||||
<main id="results" class="flow2">
|
<main id="results" class="flow2">
|
||||||
<h1>Results</h1>
|
<h1>{{ .Data.Title }}</h1>
|
||||||
<form method="GET" class="search">
|
<form method="GET" class="search">
|
||||||
<label for="search">Search {{ .SiteName }}</label>
|
<label for="search">Search {{ .SiteName }}</label>
|
||||||
<span class="search__input">
|
<span class="search__input">
|
||||||
|
@ -11,6 +11,18 @@
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</form>
|
</form>
|
||||||
|
<nav>
|
||||||
|
<ul class="result-nav-list">
|
||||||
|
<li title="content from webring sites only"
|
||||||
|
class="{{ if .Data.IsInternal }} result__current {{ end }}">
|
||||||
|
<a href="/?q={{ .Data.Query }}">Webring</a>
|
||||||
|
</li>
|
||||||
|
<li title="content linked from webring sites, but which reside outside it"
|
||||||
|
class="{{ if .Data.IsInternal | not }} result__current {{ end }}">
|
||||||
|
<a href="/outgoing?q={{ .Data.Query }}">Outgoing</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
<article>
|
<article>
|
||||||
<ul role="list" class="flow2 two-columns width-126ch">
|
<ul role="list" class="flow2 two-columns width-126ch">
|
||||||
{{ range $index, $a := .Data.Pages }}
|
{{ range $index, $a := .Data.Pages }}
|
||||||
|
|
|
@ -80,7 +80,7 @@ func Ingest(config types.Config) {
|
||||||
var count int
|
var count int
|
||||||
var batchsize = 100
|
var batchsize = 100
|
||||||
batch := make([]types.SearchFragment, 0, 0)
|
batch := make([]types.SearchFragment, 0, 0)
|
||||||
var externalLinks []string
|
var externalLinks []string
|
||||||
|
|
||||||
scanner := bufio.NewScanner(buf)
|
scanner := bufio.NewScanner(buf)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
|
@ -142,8 +142,8 @@ func Ingest(config types.Config) {
|
||||||
page.Lang = rawdata
|
page.Lang = rawdata
|
||||||
case "keywords":
|
case "keywords":
|
||||||
processed = strings.Split(strings.ReplaceAll(payload, ", ", ","), ",")
|
processed = strings.Split(strings.ReplaceAll(payload, ", ", ","), ",")
|
||||||
case "non-webring-link":
|
case "non-webring-link":
|
||||||
externalLinks = append(externalLinks, payload)
|
externalLinks = append(externalLinks, payload)
|
||||||
default:
|
default:
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ func Ingest(config types.Config) {
|
||||||
|
|
||||||
if len(pages) > batchsize {
|
if len(pages) > batchsize {
|
||||||
ingestBatch(db, batch, pages, externalLinks)
|
ingestBatch(db, batch, pages, externalLinks)
|
||||||
externalLinks = make([]string, 0, 0)
|
externalLinks = make([]string, 0, 0)
|
||||||
batch = make([]types.SearchFragment, 0, 0)
|
batch = make([]types.SearchFragment, 0, 0)
|
||||||
// TODO: make sure we don't partially insert any page data
|
// TODO: make sure we don't partially insert any page data
|
||||||
pages = make(map[string]types.PageData)
|
pages = make(map[string]types.PageData)
|
||||||
|
@ -189,7 +189,7 @@ func ingestBatch(db *sql.DB, batch []types.SearchFragment, pageMap map[string]ty
|
||||||
database.InsertManyDomains(db, pages)
|
database.InsertManyDomains(db, pages)
|
||||||
database.InsertManyPages(db, pages)
|
database.InsertManyPages(db, pages)
|
||||||
database.InsertManyWords(db, batch)
|
database.InsertManyWords(db, batch)
|
||||||
database.InsertManyExternalLinks(db, links)
|
database.InsertManyExternalLinks(db, links)
|
||||||
log.Println("finished ingesting batch")
|
log.Println("finished ingesting batch")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,10 @@ type TemplateView struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type SearchData struct {
|
type SearchData struct {
|
||||||
Query string
|
Query string
|
||||||
Pages []types.PageData
|
Title string
|
||||||
|
Pages []types.PageData
|
||||||
|
IsInternal bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type IndexData struct {
|
type IndexData struct {
|
||||||
|
@ -83,8 +85,10 @@ func (h RequestHandler) searchRoute(res http.ResponseWriter, req *http.Request)
|
||||||
}
|
}
|
||||||
|
|
||||||
view.Data = SearchData{
|
view.Data = SearchData{
|
||||||
Query: query,
|
Title: "Results",
|
||||||
Pages: pages,
|
Query: query,
|
||||||
|
Pages: pages,
|
||||||
|
IsInternal: true,
|
||||||
}
|
}
|
||||||
h.renderView(res, "search", view)
|
h.renderView(res, "search", view)
|
||||||
}
|
}
|
||||||
|
@ -112,8 +116,10 @@ func (h RequestHandler) externalSearchRoute(res http.ResponseWriter, req *http.R
|
||||||
}
|
}
|
||||||
|
|
||||||
view.Data = SearchData{
|
view.Data = SearchData{
|
||||||
Query: query,
|
Title: "External Results",
|
||||||
Pages: pages,
|
Query: query,
|
||||||
|
Pages: pages,
|
||||||
|
IsInternal: false,
|
||||||
}
|
}
|
||||||
h.renderView(res, "search", view)
|
h.renderView(res, "search", view)
|
||||||
}
|
}
|
||||||
|
@ -191,8 +197,8 @@ func Serve(config types.Config) {
|
||||||
|
|
||||||
http.HandleFunc("/about", handler.aboutRoute)
|
http.HandleFunc("/about", handler.aboutRoute)
|
||||||
http.HandleFunc("/", handler.searchRoute)
|
http.HandleFunc("/", handler.searchRoute)
|
||||||
http.HandleFunc("/external", handler.externalSearchRoute)
|
http.HandleFunc("/outgoing", handler.externalSearchRoute)
|
||||||
http.HandleFunc("/random/external", handler.randomExternalRoute)
|
http.HandleFunc("/random/outgoing", handler.randomExternalRoute)
|
||||||
http.HandleFunc("/random", handler.randomRoute)
|
http.HandleFunc("/random", handler.randomRoute)
|
||||||
http.HandleFunc("/webring", handler.webringRoute)
|
http.HandleFunc("/webring", handler.webringRoute)
|
||||||
http.HandleFunc("/filtered", handler.filteredRoute)
|
http.HandleFunc("/filtered", handler.filteredRoute)
|
||||||
|
|
Ładowanie…
Reference in New Issue