switched tabs for spaces

This commit is contained in:
drevil 2023-08-05 10:43:42 -04:00
parent 1713893f02
commit cdf89ace54
1 changed files with 210 additions and 210 deletions

420
main.go
View File

@ -1,257 +1,257 @@
package main
import (
"os"
"fmt"
"flag"
"strings"
"net/http"
"io/ioutil"
"html/template"
"encoding/json"
"os"
"fmt"
"flag"
"strings"
"net/http"
"io/ioutil"
"html/template"
"encoding/json"
)
type Options struct {
Port int
Address string
ArchivePath string
Port int
Address string
ArchivePath string
}
type PostsCache struct {
Text string
Indexes [][2]int
Archive []interface{}
Text string
Indexes [][2]int
Archive []interface{}
}
type PostSummary struct {
URL string
Content string
Datetime string
URL string
Content string
Datetime string
}
type Context struct {
Name string
Prompt string
Posts []*PostSummary
Count int
Name string
Prompt string
Posts []*PostSummary
Count int
}
const APP_NAME = "manfred"
const APP_NAME = "manfred"
const BASE_TEMPLATE = `
<!DOCTYPE html>
<html>
<head>
<style>
body {
width: 70%;
margin: auto;
}
.prompt {
width: 100%
}
.prompt h1 {
text-align: center;
}
.result {
text-align: justify;
margin-top: 2em;
border-top: 1px solid black;
border-bottom: 1px solid black;
}
</style>
<meta charset="utf-8">
<title>{{ .Name }}</title>
</head>
<body>
<div class="top">
<div class="title">
<h1>{{ .Name }} </h1>
</div>
</div>
<head>
<style>
body {
width: 70%;
margin: auto;
}
.prompt {
width: 100%
}
.prompt h1 {
text-align: center;
}
.result {
text-align: justify;
margin-top: 2em;
border-top: 1px solid black;
border-bottom: 1px solid black;
}
</style>
<meta charset="utf-8">
<title>{{ .Name }}</title>
</head>
<body>
<div class="top">
<div class="title">
<h1>{{ .Name }} </h1>
</div>
</div>
<div class="prompt">
<form action="/" method="post">
<input type="text" placeholder="Plaintext.." name="prompt">
<button type="submit">Search</button>
</form>
<p>Showing {{ .Count }} result(s) for "{{ .Prompt }}"</p>
</div>
<div class="prompt">
<form action="/" method="post">
<input type="text" placeholder="Plaintext.." name="prompt">
<button type="submit">Search</button>
</form>
<p>Showing {{ .Count }} result(s) for "{{ .Prompt }}"</p>
</div>
<div class="results">
{{ range $p := .Posts }}
<div class="result">
<a href="{{ $p.URL }}">{{ $p.URL }}</a>
<p>{{ $p.Datetime }}</p>
{{ $p.Content }}
</div>
{{ end }}
</div>
</body>
<div class="results">
{{ range $p := .Posts }}
<div class="result">
<a href="{{ $p.URL }}">{{ $p.URL }}</a>
<p>{{ $p.Datetime }}</p>
{{ $p.Content }}
</div>
{{ end }}
</div>
</body>
</html>
`
var cache *PostsCache = &PostsCache{}
var options Options = Options{}
var indexTemplate *template.Template = nil
var cache *PostsCache = &PostsCache{}
var options Options = Options{}
var indexTemplate *template.Template = nil
func (c *PostsCache) LoadArchiveCache(path string) error {
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
b, _ := ioutil.ReadAll(f)
a := make(map[string]interface{})
err = json.Unmarshal(b, &a)
if err != nil {
return err
}
fi := a["orderedItems"].([]interface{})
for _, e := range fi {
ei, ok := e.(map[string]interface{})
if !ok {
continue
}
eo, ok := ei["object"].(map[string]interface{})
if !ok {
continue
}
s, ok := eo["content"].(string)
if !ok {
continue
}
c.Archive = append(c.Archive, e)
tl := len(c.Text)
c.Indexes = append(c.Indexes, [2]int{tl, tl+ len(s)})
c.Text += s
}
return nil
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
b, _ := ioutil.ReadAll(f)
a := make(map[string]interface{})
err = json.Unmarshal(b, &a)
if err != nil {
return err
}
fi := a["orderedItems"].([]interface{})
for _, e := range fi {
ei, ok := e.(map[string]interface{})
if !ok {
continue
}
eo, ok := ei["object"].(map[string]interface{})
if !ok {
continue
}
s, ok := eo["content"].(string)
if !ok {
continue
}
c.Archive = append(c.Archive, e)
tl := len(c.Text)
c.Indexes = append(c.Indexes, [2]int{tl, tl+ len(s)})
c.Text += s
}
return nil
}
func (c *PostsCache) FindPostFromIndex(index int) int {
a, b, m := 0, 0, 0
a, b, m := 0, 0, 0
b = len(c.Indexes)-1
for a <= b {
m = a + (b - a)/2;
if c.Indexes[m][0] <= index && index <= c.Indexes[m][1]{
return m
}
if c.Indexes[m][0] < index {
a = m + 1
} else {
b = m - 1
}
}
return -1
b = len(c.Indexes)-1
for a <= b {
m = a + (b - a)/2;
if c.Indexes[m][0] <= index && index <= c.Indexes[m][1]{
return m
}
if c.Indexes[m][0] < index {
a = m + 1
} else {
b = m - 1
}
}
return -1
}
func (c *PostsCache) FindPosts(kw string) []int {
r := []int{}
i, a, l := 0, 0, len(c.Text)
for a < l {
i = strings.Index(c.Text[a:], kw)
if i < 0 {
break;
}
a += i +1
p := c.FindPostFromIndex(a-1)
if p < 0 {
break
}
fnd := false
for _, ri := range r {
if ri == p {
fnd = true
break
}
}
if fnd {
continue
}
r = append(r, p)
}
return r
r := []int{}
i, a, l := 0, 0, len(c.Text)
for a < l {
i = strings.Index(c.Text[a:], kw)
if i < 0 {
break;
}
a += i +1
p := c.FindPostFromIndex(a-1)
if p < 0 {
break
}
fnd := false
for _, ri := range r {
if ri == p {
fnd = true
break
}
}
if fnd {
continue
}
r = append(r, p)
}
return r
}
func (c *PostsCache) GetPostSummary(p int) *PostSummary {
ps := new(PostSummary)
if p < 0 || p >= len(c.Indexes) {
return nil
}
a := c.Archive[p].(map[string]interface{})
obj := a["object"].(map[string]interface{})
ps.URL = obj["id"].(string)
ps.Content = obj["content"].(string)
ps.Datetime = a["published"].(string)
return ps
ps := new(PostSummary)
if p < 0 || p >= len(c.Indexes) {
return nil
}
a := c.Archive[p].(map[string]interface{})
obj := a["object"].(map[string]interface{})
ps.URL = obj["id"].(string)
ps.Content = obj["content"].(string)
ps.Datetime = a["published"].(string)
return ps
}
func Index(w http.ResponseWriter, r * http.Request) {
ctx := &Context{
Name : APP_NAME,
}
ctx := &Context{
Name : APP_NAME,
}
if r.Method == "POST" {
r.ParseForm()
ctx.Prompt = r.FormValue("prompt")
px := cache.FindPosts(ctx.Prompt)
for _, p := range px {
ps := cache.GetPostSummary(p)
if ps == nil {
continue
}
ctx.Posts = append(ctx.Posts, ps)
}
ctx.Count = len(ctx.Posts)
}
indexTemplate.Execute(w, ctx)
if r.Method == "POST" {
r.ParseForm()
ctx.Prompt = r.FormValue("prompt")
px := cache.FindPosts(ctx.Prompt)
for _, p := range px {
ps := cache.GetPostSummary(p)
if ps == nil {
continue
}
ctx.Posts = append(ctx.Posts, ps)
}
ctx.Count = len(ctx.Posts)
}
indexTemplate.Execute(w, ctx)
}
func main() {
flag.StringVar(&options.Address, "a", "127.0.0.1", "Address the web server will be listening for")
flag.StringVar(&options.ArchivePath, "o", "./outbox.json", "Path to outbox.json")
flag.IntVar(&options.Port, "p", 8123, "Port the web server will be listening in")
flag.StringVar(&options.Address, "a", "127.0.0.1", "Address the web server will be listening for")
flag.StringVar(&options.ArchivePath, "o", "./outbox.json", "Path to outbox.json")
flag.IntVar(&options.Port, "p", 8123, "Port the web server will be listening in")
flag.Parse()
flag.Parse()
err := cache.LoadArchiveCache(options.ArchivePath)
if err != nil {
panic(err)
}
cache.GetPostSummary(0)
indexTemplate, err = template.New("index").Parse(BASE_TEMPLATE)
if err != nil {
panic(err)
}
http.HandleFunc("/", Index)
uri := fmt.Sprintf("%s:%d", options.Address, options.Port)
fmt.Println("listening to http://" + uri)
panic(http.ListenAndServe(uri, nil))
err := cache.LoadArchiveCache(options.ArchivePath)
if err != nil {
panic(err)
}
cache.GetPostSummary(0)
indexTemplate, err = template.New("index").Parse(BASE_TEMPLATE)
if err != nil {
panic(err)
}
http.HandleFunc("/", Index)
uri := fmt.Sprintf("%s:%d", options.Address, options.Port)
fmt.Println("listening to http://" + uri)
panic(http.ListenAndServe(uri, nil))
}