Compare commits
2 Commits
aaa5ac3570
...
f14e6d8249
| Author | SHA1 | Date | |
|---|---|---|---|
| f14e6d8249 | |||
| 1ab474451b |
8
TODO.md
8
TODO.md
|
|
@ -1,14 +1,12 @@
|
|||
# TODO
|
||||
|
||||
- Compile templates into binary (with go.rice)
|
||||
- Compile templates into binary (with "embed"?)
|
||||
- Generate `ek` binary with "reader" command
|
||||
- Increase ease of use for people who want to try Ekster
|
||||
- Hosted version??
|
||||
- Per user backends
|
||||
|
||||
|
||||
|
||||
|
||||
#### Code
|
||||
## Code
|
||||
|
||||
- Remove dependency between hubIncomingHandler and memoryBackend
|
||||
- Improve error handling
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"io/fs"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
|
|
@ -15,11 +18,13 @@ import (
|
|||
"p83.nl/go/ekster/pkg/microsub"
|
||||
"p83.nl/go/ekster/pkg/util"
|
||||
|
||||
"github.com/alecthomas/template"
|
||||
"github.com/gomodule/redigo/redis"
|
||||
"willnorris.com/go/microformats"
|
||||
)
|
||||
|
||||
//go:embed templates/*.html
|
||||
var templates embed.FS
|
||||
|
||||
type mainHandler struct {
|
||||
Backend *memoryBackend
|
||||
BaseURL string
|
||||
|
|
@ -106,7 +111,11 @@ func (h *mainHandler) templateFile(filename string) string {
|
|||
}
|
||||
|
||||
func (h *mainHandler) renderTemplate(w io.Writer, filename string, data interface{}) error {
|
||||
t, err := template.ParseFiles(h.templateFile("base.html"), h.templateFile(filename))
|
||||
fsys, err := fs.Sub(templates, "templates")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t, err := template.ParseFS(fsys, "base.html", filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,6 +104,10 @@ type App struct {
|
|||
|
||||
// Run runs the app
|
||||
func (app *App) Run() error {
|
||||
err := initSearch()
|
||||
if err != nil {
|
||||
return fmt.Errorf("while starting app: %v", err)
|
||||
}
|
||||
app.backend.run()
|
||||
app.hubBackend.run()
|
||||
|
||||
|
|
|
|||
|
|
@ -459,6 +459,10 @@ func getPossibleURLs(query string) []string {
|
|||
return urls
|
||||
}
|
||||
|
||||
func (b *memoryBackend) ItemSearch(channel, query string) ([]microsub.Item, error) {
|
||||
return querySearch(channel, query)
|
||||
}
|
||||
|
||||
func (b *memoryBackend) Search(query string) ([]microsub.Feed, error) {
|
||||
urls := getPossibleURLs(query)
|
||||
|
||||
|
|
@ -602,6 +606,11 @@ func (b *memoryBackend) channelAddItemWithMatcher(channel string, item microsub.
|
|||
// if regex matches item
|
||||
// - add item to channel
|
||||
|
||||
err := addToSearch(item)
|
||||
if err != nil {
|
||||
return fmt.Errorf("in channelAddItemWithMatcher: %v", err)
|
||||
}
|
||||
|
||||
var updatedChannels []string
|
||||
|
||||
b.lock.RLock()
|
||||
|
|
|
|||
88
cmd/eksterd/search.go
Normal file
88
cmd/eksterd/search.go
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/blevesearch/bleve/v2"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"p83.nl/go/ekster/pkg/microsub"
|
||||
)
|
||||
|
||||
var index bleve.Index
|
||||
|
||||
func initSearch() error {
|
||||
if _, err := os.Stat("items.bleve"); os.IsNotExist(err) {
|
||||
mapping := bleve.NewIndexMapping()
|
||||
index, err = bleve.New("items.bleve", mapping)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
index, err = bleve.Open("items.bleve")
|
||||
if err != nil {
|
||||
return fmt.Errorf("while opening search index: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func addToSearch(item microsub.Item) error {
|
||||
// TODO: add channel when indexing
|
||||
if index != nil {
|
||||
err := index.Index(item.ID, item)
|
||||
if err != nil {
|
||||
return fmt.Errorf("while indexing item: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getString(fields map[string]interface{}, key, def string) string {
|
||||
if value, e := fields[key]; e {
|
||||
if str, ok := value.(string); ok {
|
||||
return str
|
||||
}
|
||||
}
|
||||
|
||||
return def
|
||||
}
|
||||
|
||||
func querySearch(channel, query string) ([]microsub.Item, error) {
|
||||
q := bleve.NewQueryStringQuery(query)
|
||||
|
||||
cq := bleve.NewConjunctionQuery(q)
|
||||
|
||||
if channel != "global" {
|
||||
mq := bleve.NewMatchQuery(channel)
|
||||
mq.SetField("channel")
|
||||
cq.AddQuery(mq)
|
||||
}
|
||||
|
||||
req := bleve.NewSearchRequest(cq)
|
||||
req.Fields = []string{"*"}
|
||||
res, err := index.Search(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("while query %q: %v", query, err)
|
||||
}
|
||||
|
||||
items := []microsub.Item{}
|
||||
|
||||
hits := res.Hits
|
||||
for _, hit := range hits {
|
||||
fields := hit.Fields
|
||||
var item microsub.Item
|
||||
spew.Dump(fields)
|
||||
item.Type = getString(fields, "type", "entry")
|
||||
item.Name = getString(fields, "name", "")
|
||||
item.Content = µsub.Content{}
|
||||
item.Content.HTML = getString(fields, "content.html", "")
|
||||
item.Content.Text = getString(fields, "content.text", "")
|
||||
item.URL = getString(fields, "url", "")
|
||||
item.Name = getString(fields, "name", "")
|
||||
items = append(items, item)
|
||||
}
|
||||
|
||||
return items, nil
|
||||
}
|
||||
100
cmd/eksterd/templates/auth.html
Normal file
100
cmd/eksterd/templates/auth.html
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Ekster</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
|
||||
|
||||
<nav class="navbar" role="navigation" aria-label="main navigation">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item" href="/">
|
||||
Ekster
|
||||
</a>
|
||||
|
||||
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="menu">
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{ if .Session.LoggedIn }}
|
||||
<div id="menu" class="navbar-menu">
|
||||
<a class="navbar-item" href="/settings">
|
||||
Settings
|
||||
</a>
|
||||
<a class="navbar-item" href="/logs">
|
||||
Logs
|
||||
</a>
|
||||
<a class="navbar-item" href="{{ .Session.Me }}">
|
||||
Profile
|
||||
</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
</nav>
|
||||
|
||||
<h1 class="title">Ekster - Microsub server</h1>
|
||||
|
||||
<div class="box">
|
||||
<form action="/auth/approve" method="post">
|
||||
<input type="hidden" name="state" value="{{ .State }}" />
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Client ID</label>
|
||||
<div class="control">
|
||||
<p>{{ .ClientID }}</p>
|
||||
</div>
|
||||
<div class="control">
|
||||
<p>{{ .App.Name }}</p>
|
||||
</div>
|
||||
<div class="control">
|
||||
<p><img src="{{ .App.IconURL }}" /></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">RedirectURI</label>
|
||||
<div class="control">
|
||||
<p>{{ .RedirectURI }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Scope</label>
|
||||
<div class="control">
|
||||
<p>{{ .Scope }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label">Select a channel</label>
|
||||
<div class="control">
|
||||
<div class="select">
|
||||
<select name="channel">
|
||||
{{ range .Channels }}
|
||||
<option value="{{ .UID }}">{{ .Name }}</option>
|
||||
{{ end }}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<button type="submit" name="accept" value="approve" class="button is-primary">
|
||||
Approve
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
49
cmd/eksterd/templates/base.html
Normal file
49
cmd/eksterd/templates/base.html
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{template "title" .}}</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<nav class="navbar" role="navigation" aria-label="main navigation">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item" href="/">
|
||||
Ekster
|
||||
</a>
|
||||
|
||||
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="menu">
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{ if .Session.LoggedIn }}
|
||||
<div id="menu" class="navbar-menu">
|
||||
<a class="navbar-item" href="/settings">
|
||||
Settings
|
||||
</a>
|
||||
<a class="navbar-item" href="/logs">
|
||||
Logs
|
||||
</a>
|
||||
<a class="navbar-item" href="{{ .Session.Me }}">
|
||||
Profile
|
||||
</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
</nav>
|
||||
|
||||
<h1 class="title">Ekster - Microsub server</h1>
|
||||
|
||||
{{template "content" .}}
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
{{define "header"}}{{end}}
|
||||
{{define "content"}}{{end}}
|
||||
{{define "footer"}}{{end}}
|
||||
122
cmd/eksterd/templates/channel.html
Normal file
122
cmd/eksterd/templates/channel.html
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Ekster</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<nav class="navbar" role="navigation" aria-label="main navigation">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item" href="/">
|
||||
Ekster
|
||||
</a>
|
||||
|
||||
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="menu">
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{ if .Session.LoggedIn }}
|
||||
<div id="menu" class="navbar-menu">
|
||||
<a class="navbar-item" href="/settings">
|
||||
Settings
|
||||
</a>
|
||||
<a class="navbar-item" href="/logs">
|
||||
Logs
|
||||
</a>
|
||||
<a class="navbar-item" href="{{ .Session.Me }}">
|
||||
Profile
|
||||
</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
</nav>
|
||||
|
||||
<h1 class="title">Ekster - Microsub server</h1>
|
||||
|
||||
{{ $channel := .CurrentChannel }}
|
||||
|
||||
<nav class="breadcrumb" aria-label="breadcrumbs">
|
||||
<ul>
|
||||
<li><a href="/settings">Settings</a></li>
|
||||
<li class="is-active"><a href="/setttings/channel?uid={{ .CurrentChannel }}">{{ $channel.Name }}</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<h2 class="subtitle is-2">{{ $channel.Name }}</h2>
|
||||
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<h3 class="title is-4">Settings</h3>
|
||||
<form action="/settings/channel" method="post">
|
||||
<input type="hidden" name="uid" value="{{ .CurrentChannel.UID }}" />
|
||||
<div class="field">
|
||||
<label class="label" for="exclude_regex">Blocking Regex</label>
|
||||
<div class="control">
|
||||
<input type="text" class="input" id="exclude_regex" name="exclude_regex" value="{{ .CurrentSetting.ExcludeRegex }}" placeholder="enter regex to block" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="include_regex">Tracking Regex</label>
|
||||
<div class="control">
|
||||
<input type="text" class="input" id="include_regex" name="include_regex" value="{{ .CurrentSetting.IncludeRegex }}" placeholder="enter regex to track items" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="type">Channel Type</label>
|
||||
<div class="control">
|
||||
<div class="select">
|
||||
<select name="type" id="type">
|
||||
<option value="null" {{if eq (.CurrentSetting.ChannelType) "null" }}selected{{end}}>Null</option>
|
||||
<option value="sorted-set" {{if eq (.CurrentSetting.ChannelType) "sorted-set" }}selected{{end}}>Sorted Set</option>
|
||||
<option value="stream" {{if eq (.CurrentSetting.ChannelType) "stream" }}selected{{end}}>Streams</option>
|
||||
<option value="postgres-stream" {{if eq (.CurrentSetting.ChannelType) "postgres-stream" }}selected{{end}}>Postgres Stream</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="exclude_type" class="label">Exclude Types</label>
|
||||
<div class="control">
|
||||
<div class="select is-multiple">
|
||||
<select name="exclude_type" id="exclude_type" multiple>
|
||||
{{ range $key, $excluded := $.ExcludedTypes }}
|
||||
<option value="{{ $key }}" {{ if $excluded }}selected="selected"{{ end }}>{{ index $.ExcludedTypeNames $key }}</option>
|
||||
{{ end }}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<button type="submit" class="button is-primary">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<h3 class="title is-4">Feeds</h3>
|
||||
|
||||
<div class="channel">
|
||||
{{ range .Feeds }}
|
||||
<div class="feed box">
|
||||
<div class="name">
|
||||
<a href="{{ .URL }}">{{ .URL }}</a>
|
||||
</div>
|
||||
</div>
|
||||
{{ else }}
|
||||
<div class="no-channels">No feeds</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
71
cmd/eksterd/templates/index.html
Normal file
71
cmd/eksterd/templates/index.html
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Ekster</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css">
|
||||
<link rel="micropub" href="{{ .Baseurl }}/micropub" />
|
||||
<link rel="authorization_endpoint" href="{{ .Baseurl }}/auth" />
|
||||
<link rel="token_endpoint" href="{{ .Baseurl }}/auth/token" />
|
||||
</head>
|
||||
<body>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
|
||||
|
||||
<nav class="navbar" role="navigation" aria-label="main navigation">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item" href="/">
|
||||
Ekster
|
||||
</a>
|
||||
|
||||
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="menu">
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{ if .Session.LoggedIn }}
|
||||
<div id="menu" class="navbar-menu">
|
||||
<a class="navbar-item" href="/settings">
|
||||
Settings
|
||||
</a>
|
||||
<a class="navbar-item" href="/logs">
|
||||
Logs
|
||||
</a>
|
||||
<a class="navbar-item" href="{{ .Session.Me }}">
|
||||
Profile
|
||||
</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
</nav>
|
||||
|
||||
<h1 class="title">Ekster - Microsub server</h1>
|
||||
|
||||
{{ if .Session.LoggedIn }}
|
||||
<h2 class="title">Logout</h2>
|
||||
<form action="/session/logout" method="post">
|
||||
<button type="submit" class="button is-info">Logout</button>
|
||||
</form>
|
||||
{{ else }}
|
||||
<h2 class="title">Sign in to Ekster</h2>
|
||||
<form action="/session" method="post">
|
||||
<div class="field">
|
||||
<label class="label" for="url"></label>
|
||||
<div class="control">
|
||||
<input type="text" name="url" id="url" class="input" placeholder="https://example.com/">
|
||||
</div>
|
||||
</div>
|
||||
<div class="field is-grouped">
|
||||
<div class="control">
|
||||
<button type="submit" class="button is-info">Login</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{{ end }}
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
50
cmd/eksterd/templates/logs.html
Normal file
50
cmd/eksterd/templates/logs.html
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Ekster</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
|
||||
|
||||
<nav class="navbar" role="navigation" aria-label="main navigation">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item" href="/">
|
||||
Ekster
|
||||
</a>
|
||||
|
||||
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="menu">
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{ if .Session.LoggedIn }}
|
||||
<div id="menu" class="navbar-menu">
|
||||
<a class="navbar-item" href="/settings">
|
||||
Settings
|
||||
</a>
|
||||
<a class="navbar-item" href="/logs">
|
||||
Logs
|
||||
</a>
|
||||
<a class="navbar-item" href="{{ .Session.Me }}">
|
||||
Profile
|
||||
</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
</nav>
|
||||
|
||||
<h1 class="title">Ekster - Microsub server</h1>
|
||||
|
||||
<h2 class="subtitle">Logs</h2>
|
||||
|
||||
<p>Logs</p>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
63
cmd/eksterd/templates/settings.html
Normal file
63
cmd/eksterd/templates/settings.html
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Ekster</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<nav class="navbar" role="navigation" aria-label="main navigation">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item" href="/">
|
||||
Ekster
|
||||
</a>
|
||||
|
||||
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="menu">
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{ if .Session.LoggedIn }}
|
||||
<div id="menu" class="navbar-menu">
|
||||
<a class="navbar-item" href="/settings">
|
||||
Settings
|
||||
</a>
|
||||
<a class="navbar-item" href="/logs">
|
||||
Logs
|
||||
</a>
|
||||
<a class="navbar-item" href="{{ .Session.Me }}">
|
||||
Profile
|
||||
</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
</nav>
|
||||
|
||||
<h1 class="title">Ekster - Microsub server</h1>
|
||||
|
||||
{{ if .Session.LoggedIn }}
|
||||
{{ end }}
|
||||
|
||||
<h2 class="subtitle">Channels</h2>
|
||||
|
||||
<div class="channels">
|
||||
{{ range .Channels }}
|
||||
<div class="channel box">
|
||||
<div class="name">
|
||||
<a href="/settings/channel?uid={{ .UID }}">
|
||||
{{ .Name }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{{ else }}
|
||||
<div class="no-channels">No channels</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
4
go.mod
4
go.mod
|
|
@ -1,10 +1,12 @@
|
|||
module p83.nl/go/ekster
|
||||
|
||||
go 1.14
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394
|
||||
github.com/blevesearch/bleve/v2 v2.0.3 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/gilliek/go-opml v1.0.0
|
||||
github.com/gomodule/redigo v1.8.2
|
||||
github.com/lib/pq v1.10.1
|
||||
|
|
|
|||
101
go.sum
101
go.sum
|
|
@ -1,44 +1,145 @@
|
|||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
|
||||
github.com/RoaringBitmap/roaring v0.4.23 h1:gpyfd12QohbqhFO4NVDUdoPOCXsyahYRQhINmlHxKeo=
|
||||
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
|
||||
github.com/blevesearch/bleve/v2 v2.0.3 h1:mDrwrsRIA4PDYkfUNjoh5zGECvquuJIA3MJU5ivaO8E=
|
||||
github.com/blevesearch/bleve/v2 v2.0.3/go.mod h1:ip+4iafiEq2gCY5rJXe87bT6LkF/OJMCjQEYIfTBfW8=
|
||||
github.com/blevesearch/bleve_index_api v1.0.0 h1:Ds3XeuTxjXCkG6pgIwWDRyooJKNIuOKemnN0N0IkhTU=
|
||||
github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
||||
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
|
||||
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
|
||||
github.com/blevesearch/mmap-go v1.0.2 h1:JtMHb+FgQCTTYIhtMvimw15dJwu1Y5lrZDMOFXVWPk0=
|
||||
github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+7LMvAB5IbSA=
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.0.1 h1:fd+hPtZ8GsbqPK1HslGp7Vhoik4arZteA/IsCEgOisw=
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.0.1/go.mod h1:lq7yK2jQy1yQjtjTfU931aVqz7pYxEudHaDwOt1tXfU=
|
||||
github.com/blevesearch/segment v0.9.0 h1:5lG7yBCx98or7gK2cHMKPukPZ/31Kag7nONpoBt22Ac=
|
||||
github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ=
|
||||
github.com/blevesearch/snowballstem v0.9.0 h1:lMQ189YspGP6sXvZQ4WZ+MLawfV8wOmPoD/iWeNXm8s=
|
||||
github.com/blevesearch/snowballstem v0.9.0/go.mod h1:PivSj3JMc8WuaFkTSRDW2SlrulNWPl4ABg1tC/hlgLs=
|
||||
github.com/blevesearch/upsidedown_store_api v1.0.1 h1:1SYRwyoFLwG3sj0ed89RLtM15amfX2pXlYbFOnF8zNU=
|
||||
github.com/blevesearch/upsidedown_store_api v1.0.1/go.mod h1:MQDVGpHZrpe3Uy26zJBf/a8h0FZY6xJbthIMm8myH2Q=
|
||||
github.com/blevesearch/vellum v1.0.3 h1:U86G41A7CtXNzzpIJHM8lSTUqz1Mp8U870TkcdCzZc8=
|
||||
github.com/blevesearch/vellum v1.0.3/go.mod h1:2u5ax02KeDuNWu4/C+hVQMD6uLN4txH1JbtpaDNLJRo=
|
||||
github.com/blevesearch/zapx/v11 v11.2.0 h1:GBkCJYsyj3eIU4+aiLPxoMz1PYvDbQZl/oXHIBZIP60=
|
||||
github.com/blevesearch/zapx/v11 v11.2.0/go.mod h1:gN/a0alGw1FZt/YGTo1G6Z6XpDkeOfujX5exY9sCQQM=
|
||||
github.com/blevesearch/zapx/v12 v12.2.0 h1:dyRcSoZVO1jktL4UpGkCEF1AYa3xhKPirh4/N+Va+Ww=
|
||||
github.com/blevesearch/zapx/v12 v12.2.0/go.mod h1:fdjwvCwWWwJW/EYTYGtAp3gBA0geCYGLcVTtJEZnY6A=
|
||||
github.com/blevesearch/zapx/v13 v13.2.0 h1:mUqbaqQABp8nBE4t4q2qMyHCCq4sykoV8r7aJk4ih3s=
|
||||
github.com/blevesearch/zapx/v13 v13.2.0/go.mod h1:o5rAy/lRS5JpAbITdrOHBS/TugWYbkcYZTz6VfEinAQ=
|
||||
github.com/blevesearch/zapx/v14 v14.2.0 h1:UsfRqvM9RJxKNKrkR1U7aYc1cv9MWx719fsAjbF6joI=
|
||||
github.com/blevesearch/zapx/v14 v14.2.0/go.mod h1:GNgZusc1p4ot040cBQMRGEZobvwjCquiEKYh1xLFK9g=
|
||||
github.com/blevesearch/zapx/v15 v15.2.0 h1:ZpibwcrrOaeslkOw3sJ7npP7KDgRHI/DkACjKTqFwyM=
|
||||
github.com/blevesearch/zapx/v15 v15.2.0/go.mod h1:MmQceLpWfME4n1WrBFIwplhWmaQbQqLQARpaKUEOs/A=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/couchbase/ghistogram v0.1.0/go.mod h1:s1Jhy76zqfEecpNWJfWUiKZookAFaiGOEoyzgHt9i7k=
|
||||
github.com/couchbase/moss v0.1.0/go.mod h1:9MaHIaRuy9pvLPUJxB8sh8OrLfyDczECVL37grCIubs=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gilliek/go-opml v1.0.0 h1:X8xVjtySRXU/x6KvaiXkn7OV3a4DHqxY8Rpv6U/JvCY=
|
||||
github.com/gilliek/go-opml v1.0.0/go.mod h1:fOxmtlzyBvUjU6bjpdjyxCGlWz+pgtAHrHf/xRZl3lk=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2 h1:Ujru1hufTHVb++eG6OuNDKMxZnGIvF6o/u8q/8h2+I4=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k=
|
||||
github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/kljensen/snowball v0.6.0/go.mod h1:27N7E8fVU5H68RlUmnWwZCfxgt4POBJfENGMvNRhldw=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/lib/pq v1.10.1 h1:6VXZrLU0jHBYyAqrSPa+MgPfnSvTPuMgK+k0o5kVFWo=
|
||||
github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
|
||||
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
|
||||
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
|
||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/steveyen/gtreap v0.1.0 h1:CjhzTa274PyJLJuMZwIzCO1PfC00oRa8d1Kc78bFXJM=
|
||||
github.com/steveyen/gtreap v0.1.0/go.mod h1:kl/5J7XbrOmlIbYIXdRHDDE5QxHqpk0cmkT7Z4dM9/Y=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/tinylib/msgp v1.1.0 h1:9fQd+ICuRIu/ue4vxJZu6/LzxN0HwMds2nq/0cFvxHU=
|
||||
github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/willf/bitset v1.1.10 h1:NotGKqX0KwQ72NUzqrjZq5ipPNDQex9lo3WpaS8L2sc=
|
||||
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
|
||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
willnorris.com/go/microformats v1.1.0 h1:a16gADl3aFxYVUQDxX8zS2AWAHKNnuaLlZFxyDzmSf8=
|
||||
|
|
|
|||
|
|
@ -333,6 +333,28 @@ func (c *Client) Search(query string) ([]microsub.Feed, error) {
|
|||
return response.Results, nil
|
||||
}
|
||||
|
||||
// ItemSearch send a search request to the server
|
||||
func (c *Client) ItemSearch(channel, query string) ([]microsub.Item, error) {
|
||||
args := make(map[string]string)
|
||||
args["query"] = query
|
||||
args["channel"] = channel
|
||||
res, err := c.microsubPostRequest("search", args)
|
||||
if err != nil {
|
||||
return []microsub.Item{}, err
|
||||
}
|
||||
type searchResponse struct {
|
||||
Items []microsub.Item `json:"items"`
|
||||
}
|
||||
defer res.Body.Close()
|
||||
var response searchResponse
|
||||
dec := json.NewDecoder(res.Body)
|
||||
err = dec.Decode(&response)
|
||||
if err != nil {
|
||||
return []microsub.Item{}, err
|
||||
}
|
||||
return response.Items, nil
|
||||
}
|
||||
|
||||
// MarkRead marks an item read on the server.
|
||||
func (c *Client) MarkRead(channel string, uids []string) error {
|
||||
args := make(map[string]string)
|
||||
|
|
|
|||
|
|
@ -125,6 +125,8 @@ type Microsub interface {
|
|||
Search(query string) ([]Feed, error)
|
||||
PreviewURL(url string) (Timeline, error)
|
||||
|
||||
ItemSearch(channel, query string) ([]Item, error)
|
||||
|
||||
Events() (chan sse.Message, error)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -184,14 +184,27 @@ func (h *microsubHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
respondJSON(w, []string{})
|
||||
} else if action == "search" {
|
||||
query := values.Get("query")
|
||||
feeds, err := h.backend.Search(query)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), 500)
|
||||
return
|
||||
channel := values.Get("channel")
|
||||
if channel == "" {
|
||||
feeds, err := h.backend.Search(query)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), 500)
|
||||
return
|
||||
}
|
||||
respondJSON(w, map[string][]microsub.Feed{
|
||||
"results": feeds,
|
||||
})
|
||||
} else {
|
||||
items, err := h.backend.ItemSearch(channel, query)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), 500)
|
||||
return
|
||||
}
|
||||
respondJSON(w, map[string]interface{}{
|
||||
"query": query,
|
||||
"items": items,
|
||||
})
|
||||
}
|
||||
respondJSON(w, map[string][]microsub.Feed{
|
||||
"results": feeds,
|
||||
})
|
||||
} else if action == "timeline" || r.PostForm.Get("action") == "timeline" {
|
||||
method := values.Get("method")
|
||||
|
||||
|
|
|
|||
|
|
@ -70,6 +70,11 @@ func (b *NullBackend) Search(query string) ([]microsub.Feed, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// ItemSearch returns a list of zero items
|
||||
func (b *NullBackend) ItemSearch(channel, query string) ([]microsub.Item, error) {
|
||||
return []microsub.Item{}, nil
|
||||
}
|
||||
|
||||
// PreviewURL shows an empty feed
|
||||
func (b *NullBackend) PreviewURL(url string) (microsub.Timeline, error) {
|
||||
return microsub.Timeline{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user