WIP: Node. New generation #1
10
go.mod
Normal file
10
go.mod
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
module github.com/idec-net/lessmore-node
|
||||||
|
|
||||||
|
go 1.16
|
||||||
|
|
||||||
|
replace github.com/idec-net/lessmore-node/node => ./node
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/idec-net/lessmore-node/node v0.0.0-00010101000000-000000000000
|
||||||
|
github.com/sirupsen/logrus v1.8.1
|
||||||
|
)
|
36
go.sum
Normal file
36
go.sum
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
gitea.difrex.ru/Umbrella/fetcher v0.0.0-20200723122826-e8bbdd12256b h1:K0vLl90b8k+JaCcxoaqbKOfK0LpyTMHQg4a0ggI6HI0=
|
||||||
|
gitea.difrex.ru/Umbrella/fetcher v0.0.0-20200723122826-e8bbdd12256b/go.mod h1:rcNfqAtzWqj1MsvxDuqTuqTNiJ7r6f1reQvsuUaiHYY=
|
||||||
|
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/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
||||||
|
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
|
||||||
|
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||||
|
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||||
|
github.com/idec-net/go-idec v0.0.0-20181106151523-61a006246343/go.mod h1:XUvr43ZLN/4bTZT7TEhJA/rsfFLQxnggX6iU5TGXgIY=
|
||||||
|
github.com/idec-net/go-idec v0.0.0-20190316125931-ba6681d1b33b h1:QnpZjlk1jtZwZzT8HKMSfFio+L/6QG16uz3zCbPTkLw=
|
||||||
|
github.com/idec-net/go-idec v0.0.0-20190316125931-ba6681d1b33b/go.mod h1:ST2XOvFc7oRd1FCiZPwYf78F43SV9D3r1S+J4OQMsUo=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
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/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
|
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||||
|
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
|
||||||
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210324051608-47abb6519492 h1:Paq34FxTluEPvVyayQqMPgHm+vTOrIifmcYxFBx9TLg=
|
||||||
|
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
gopkg.in/jarcoal/httpmock.v1 v1.0.0-20190304095222-3b6b0a8dbc05 h1:u9qyM/i6c8jhNxsMfz4qdKtZumvEhHWYu5jEeOn1SOA=
|
||||||
|
gopkg.in/jarcoal/httpmock.v1 v1.0.0-20190304095222-3b6b0a8dbc05/go.mod h1:d3R+NllX3X5e0zlG1Rful3uLvsGC/Q3OHut5464DEQw=
|
6
main.go
6
main.go
@ -4,7 +4,7 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"gitea.difrex.ru/Umbrella/lessmore/node"
|
"github.com/idec-net/lessmore-node/node"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -22,8 +22,8 @@ var (
|
|||||||
func init() {
|
func init() {
|
||||||
flag.StringVar(&listen, "listen", "127.0.0.1:15582", "Address to listen")
|
flag.StringVar(&listen, "listen", "127.0.0.1:15582", "Address to listen")
|
||||||
flag.StringVar(&es, "es", "http://127.0.0.1:9200", "ES host")
|
flag.StringVar(&es, "es", "http://127.0.0.1:9200", "ES host")
|
||||||
flag.StringVar(&esMessagesIndex, "esindex", "idec3", "ES index")
|
flag.StringVar(&esMessagesIndex, "esindex", "", "ES index")
|
||||||
flag.StringVar(&esMessagesType, "estype", "post", "ES index type")
|
flag.StringVar(&esMessagesType, "estype", "", "ES index type")
|
||||||
flag.StringVar(&add, "add", "", "User to add")
|
flag.StringVar(&add, "add", "", "User to add")
|
||||||
flag.StringVar(&email, "email", "", "User email address")
|
flag.StringVar(&email, "email", "", "User email address")
|
||||||
flag.BoolVar(&debug, "debug", false, "Debug output")
|
flag.BoolVar(&debug, "debug", false, "Debug output")
|
||||||
|
@ -230,6 +230,10 @@ func Serve(listen string, es ESConf) {
|
|||||||
// Point methods
|
// Point methods
|
||||||
r.HandleFunc("/u/point", es.UPointHandler).Methods("POST")
|
r.HandleFunc("/u/point", es.UPointHandler).Methods("POST")
|
||||||
|
|
||||||
|
// Simple and clean SSR UI
|
||||||
|
ssr := newSSR("./templates", es)
|
||||||
|
r.HandleFunc("/ssr", ssr.ssrRootHandler)
|
||||||
|
|
||||||
http.Handle("/", r)
|
http.Handle("/", r)
|
||||||
|
|
||||||
srv := http.Server{
|
srv := http.Server{
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
@ -136,12 +137,6 @@ func (es ESConf) GetEchoMessageHashes(echo string) []string {
|
|||||||
// GetLimitedEchoMessageHashes ...
|
// GetLimitedEchoMessageHashes ...
|
||||||
func (es ESConf) GetLimitedEchoMessageHashes(echo string, offset int, limit int) []string {
|
func (es ESConf) GetLimitedEchoMessageHashes(echo string, offset int, limit int) []string {
|
||||||
var hashes []string
|
var hashes []string
|
||||||
var searchURI string
|
|
||||||
if es.Index != "" && es.Type != "" {
|
|
||||||
searchURI = strings.Join([]string{es.Host, es.Index, es.Type, "_search"}, "/")
|
|
||||||
} else {
|
|
||||||
searchURI = strings.Join([]string{es.Host, "search"}, "/")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check offset
|
// Check offset
|
||||||
var order string
|
var order string
|
||||||
@ -158,7 +153,7 @@ func (es ESConf) GetLimitedEchoMessageHashes(echo string, offset int, limit int)
|
|||||||
{"date":{ "order": "`, order, `" }},{ "_score":{ "order": "`, order, `" }}],
|
{"date":{ "order": "`, order, `" }},{ "_score":{ "order": "`, order, `" }}],
|
||||||
"query": {"query_string" : {"fields": ["msgid", "echo"], "query":"`, echo, `"}}, "size":`, l, `}`}, ""))
|
"query": {"query_string" : {"fields": ["msgid", "echo"], "query":"`, echo, `"}}, "size":`, l, `}`}, ""))
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", searchURI, bytes.NewBuffer(searchQ))
|
req, err := http.NewRequest("POST", es.searchURI(), bytes.NewBuffer(searchQ))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err.Error())
|
log.Error(err.Error())
|
||||||
return hashes
|
return hashes
|
||||||
@ -375,14 +370,56 @@ func (es ESConf) GetXC(echoes string) []string {
|
|||||||
return counts
|
return counts
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetListTXT ...
|
func (es ESConf) GetLatestPosts(sum int) []i2es.ESDoc {
|
||||||
func (es ESConf) GetListTXT() []byte {
|
query := fmt.Sprintf(`{"sort": [{"date": {"order": "desc"}}, {"_score": {"order": "desc" }}], "size": %d}`, sum)
|
||||||
var searchURI string
|
req, err := http.NewRequest("POST", es.searchURI(), bytes.NewBuffer([]byte(query)))
|
||||||
if es.Index != "" && es.Type != "" {
|
if err != nil {
|
||||||
searchURI = strings.Join([]string{es.Host, es.Index, "_search"}, "/")
|
log.Error(err.Error())
|
||||||
} else {
|
return nil
|
||||||
searchURI = strings.Join([]string{es.Host, "search"}, "/")
|
|
||||||
}
|
}
|
||||||
|
req.Header.Add("Content-Type", "application/json")
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
var esr ESSearchResp
|
||||||
|
err = json.NewDecoder(resp.Body).Decode(&esr)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var posts []i2es.ESDoc
|
||||||
|
for _, hit := range esr.Hits.Hits {
|
||||||
|
hit.Source.Date = parseTime(hit.Source.Date)
|
||||||
|
hit.Source.Message = strings.Trim(hit.Source.Message, "\n")
|
||||||
|
posts = append(posts, hit.Source)
|
||||||
|
}
|
||||||
|
|
||||||
|
return posts
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseTime(t string) string {
|
||||||
|
i, err := strconv.ParseInt(t, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
ts := time.Unix(i, 0)
|
||||||
|
return ts.Format(time.UnixDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
type echo struct {
|
||||||
|
Name string
|
||||||
|
Docs int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es ESConf) GetEchoesList() []echo {
|
||||||
searchQ := []byte(`{
|
searchQ := []byte(`{
|
||||||
"size": 0,
|
"size": 0,
|
||||||
"aggs": {
|
"aggs": {
|
||||||
@ -399,12 +436,11 @@ func (es ESConf) GetListTXT() []byte {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`)
|
}`)
|
||||||
log.Print("Search URI: ", searchURI)
|
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", searchURI, bytes.NewBuffer(searchQ))
|
req, err := http.NewRequest("POST", es.searchURI(), bytes.NewBuffer(searchQ))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err.Error())
|
log.Error(err.Error())
|
||||||
return []byte("")
|
return nil
|
||||||
}
|
}
|
||||||
req.Header.Add("Content-Type", "application/json")
|
req.Header.Add("Content-Type", "application/json")
|
||||||
|
|
||||||
@ -412,7 +448,7 @@ func (es ESConf) GetListTXT() []byte {
|
|||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err.Error())
|
log.Error(err.Error())
|
||||||
return []byte("")
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
@ -421,15 +457,26 @@ func (es ESConf) GetListTXT() []byte {
|
|||||||
err = json.NewDecoder(resp.Body).Decode(&esr)
|
err = json.NewDecoder(resp.Body).Decode(&esr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err.Error())
|
log.Error(err.Error())
|
||||||
return []byte("")
|
return nil
|
||||||
}
|
}
|
||||||
log.Infof("%+v", esr)
|
|
||||||
|
|
||||||
var echoes []string
|
var echoes []echo
|
||||||
for _, bucket := range esr.EchoAgg["echo"].Buckets {
|
for _, bucket := range esr.EchoAgg["echo"].Buckets {
|
||||||
echoes = append(echoes, fmt.Sprintf("%s:%d:", bucket.Key, bucket.DocCount))
|
echoes = append(echoes, echo{bucket.Key, int64(bucket.DocCount)})
|
||||||
}
|
}
|
||||||
log.Print("Getting ", len(echoes), " echoes")
|
|
||||||
|
|
||||||
return []byte(strings.Join(echoes, "\n"))
|
return echoes
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetListTXT ...
|
||||||
|
func (es ESConf) GetListTXT() []byte {
|
||||||
|
var listTXT []string
|
||||||
|
echoes := es.GetEchoesList()
|
||||||
|
for _, echo := range echoes {
|
||||||
|
listTXT = append(listTXT, fmt.Sprintf("%s:%d:(TODO) description support", echo.Name, echo.Docs))
|
||||||
|
}
|
||||||
|
// Add new line to be more compatible with fetchers
|
||||||
|
listTXT[len(listTXT)-1] = listTXT[len(listTXT)-1] + "\n"
|
||||||
|
|
||||||
|
return []byte(strings.Join(listTXT, "\n"))
|
||||||
}
|
}
|
||||||
|
13
node/go.mod
Normal file
13
node/go.mod
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
module github.com/idec-net/lessmore-node/node
|
||||||
|
|
||||||
|
go 1.16
|
||||||
|
|
||||||
|
require (
|
||||||
|
gitea.difrex.ru/Umbrella/fetcher v0.0.0-20200723122826-e8bbdd12256b
|
||||||
|
github.com/google/uuid v1.2.0 // indirect
|
||||||
|
github.com/gorilla/mux v1.8.0
|
||||||
|
github.com/idec-net/go-idec v0.0.0-20190316125931-ba6681d1b33b
|
||||||
|
github.com/sirupsen/logrus v1.8.1
|
||||||
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
|
||||||
|
golang.org/x/sys v0.0.0-20210324051608-47abb6519492 // indirect
|
||||||
|
)
|
38
node/go.sum
Normal file
38
node/go.sum
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
gitea.difrex.ru/Umbrella/fetcher v0.0.0-20200723122826-e8bbdd12256b h1:K0vLl90b8k+JaCcxoaqbKOfK0LpyTMHQg4a0ggI6HI0=
|
||||||
|
gitea.difrex.ru/Umbrella/fetcher v0.0.0-20200723122826-e8bbdd12256b/go.mod h1:rcNfqAtzWqj1MsvxDuqTuqTNiJ7r6f1reQvsuUaiHYY=
|
||||||
|
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/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
||||||
|
github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA=
|
||||||
|
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
|
||||||
|
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||||
|
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||||
|
github.com/idec-net/go-idec v0.0.0-20181106151523-61a006246343/go.mod h1:XUvr43ZLN/4bTZT7TEhJA/rsfFLQxnggX6iU5TGXgIY=
|
||||||
|
github.com/idec-net/go-idec v0.0.0-20190316125931-ba6681d1b33b h1:QnpZjlk1jtZwZzT8HKMSfFio+L/6QG16uz3zCbPTkLw=
|
||||||
|
github.com/idec-net/go-idec v0.0.0-20190316125931-ba6681d1b33b/go.mod h1:ST2XOvFc7oRd1FCiZPwYf78F43SV9D3r1S+J4OQMsUo=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
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/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
|
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||||
|
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
|
||||||
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210324051608-47abb6519492 h1:Paq34FxTluEPvVyayQqMPgHm+vTOrIifmcYxFBx9TLg=
|
||||||
|
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
gopkg.in/jarcoal/httpmock.v1 v1.0.0-20190304095222-3b6b0a8dbc05 h1:u9qyM/i6c8jhNxsMfz4qdKtZumvEhHWYu5jEeOn1SOA=
|
||||||
|
gopkg.in/jarcoal/httpmock.v1 v1.0.0-20190304095222-3b6b0a8dbc05/go.mod h1:d3R+NllX3X5e0zlG1Rful3uLvsGC/Q3OHut5464DEQw=
|
67
node/ssr.go
Normal file
67
node/ssr.go
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package node
|
||||||
|
|
||||||
|
import (
|
||||||
|
"html/template"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"gitea.difrex.ru/Umbrella/fetcher/i2es"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ssr struct {
|
||||||
|
es ESConf
|
||||||
|
templatesDir string
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSSR(templatesDir string, es ESConf) *ssr {
|
||||||
|
return &ssr{
|
||||||
|
es: es,
|
||||||
|
templatesDir: templatesDir,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ssr) templatePath(name string) string {
|
||||||
|
return s.templatesDir + string(os.PathSeparator) + name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ssr) getTemplate(name string) (*template.Template, error) {
|
||||||
|
t := template.New("root.html")
|
||||||
|
|
||||||
|
tpl, err := t.ParseFiles(
|
||||||
|
s.templatePath(name+".html"),
|
||||||
|
s.templatePath("style.html"),
|
||||||
|
s.templatePath("echoes.html"),
|
||||||
|
s.templatePath("post.html"),
|
||||||
|
s.templatePath("latest_posts.html"),
|
||||||
|
s.templatePath("header.html"),
|
||||||
|
s.templatePath("footer.html"),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tpl, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ssr) ssrRootHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
LogRequest(r)
|
||||||
|
|
||||||
|
tpl, err := s.getTemplate("root")
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var root struct {
|
||||||
|
Echoes []echo
|
||||||
|
CurrentPage string
|
||||||
|
Posts []i2es.ESDoc
|
||||||
|
}
|
||||||
|
root.Echoes = s.es.GetEchoesList()
|
||||||
|
root.Posts = s.es.GetLatestPosts(100)
|
||||||
|
|
||||||
|
if err := tpl.Execute(w, root); err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,10 @@
|
|||||||
package node
|
package node
|
||||||
|
|
||||||
import "gitea.difrex.ru/Umbrella/fetcher/i2es"
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"gitea.difrex.ru/Umbrella/fetcher/i2es"
|
||||||
|
)
|
||||||
|
|
||||||
// PointRequest with message
|
// PointRequest with message
|
||||||
type PointRequest struct {
|
type PointRequest struct {
|
||||||
@ -11,6 +15,16 @@ type PointRequest struct {
|
|||||||
// ESConf ...
|
// ESConf ...
|
||||||
type ESConf i2es.ESConf
|
type ESConf i2es.ESConf
|
||||||
|
|
||||||
|
// searchURI returns an ElasticSearch search URL string
|
||||||
|
func (es ESConf) searchURI() (searchURI string) {
|
||||||
|
if es.Index != "" && es.Type != "" {
|
||||||
|
searchURI = strings.Join([]string{es.Host, es.Index, es.Type, "_search"}, "/")
|
||||||
|
} else {
|
||||||
|
searchURI = strings.Join([]string{es.Host, "search"}, "/")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Bucket ...
|
// Bucket ...
|
||||||
type Bucket struct {
|
type Bucket struct {
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
|
22
templates/echoes.html
Normal file
22
templates/echoes.html
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{{ define "echoes" }}
|
||||||
|
|
||||||
|
<div class="echoList">
|
||||||
|
{{ range .Echoes }}
|
||||||
|
|
||||||
|
<div class="card dynamic-echo mb-1">
|
||||||
|
<div class="card-header text-info container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-9">
|
||||||
|
<a class="text-white-50" href="/ssr#{{ .Name }}">{{ .Name }}</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-3 text-end">
|
||||||
|
<span class="text-white-50">{{ .Docs }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ end }}
|
8
templates/footer.html
Normal file
8
templates/footer.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{{ define "footer" }}
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.bundle.min.js" integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
{{ end }}
|
35
templates/header.html
Normal file
35
templates/header.html
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{{ define "header" }}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<title>{{ if .CurrentPage }}staic | {{ .CurrentPage }}{{ else }}dynamic{{ end }}</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
|
||||||
|
<body class="dynamic-bg">
|
||||||
|
|
||||||
|
<!-- Panel -->
|
||||||
|
<nav class="navbar navbar-expand-lg position-static navbar-dark dynamic-panel mb-2">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<a class="navbar-brand" href="#">static | more</a>
|
||||||
|
|
||||||
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
|
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
menu
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||||
|
<li><a class="dropdown-item" href="#">Action</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#">Another action</a></li>
|
||||||
|
<li><hr class="dropdown-divider"></li>
|
||||||
|
<li><a class="dropdown-item" href="#">Something else here</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<form class="d-flex">
|
||||||
|
<input class="form-control me-2 bg-dark text-black-50 border-0" type="search" placeholder='search query' aria-label="Search">
|
||||||
|
<button class="btn btn-outline-success" type="submit">Search</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{{ end }}
|
9
templates/latest_posts.html
Normal file
9
templates/latest_posts.html
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{{ define "latest posts" }}
|
||||||
|
|
||||||
|
{{ range .Posts }}
|
||||||
|
|
||||||
|
{{ template "post" . }}
|
||||||
|
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ end }}
|
29
templates/post.html
Normal file
29
templates/post.html
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{{ define "post" }}
|
||||||
|
|
||||||
|
<div class="card container dynamic-post dynamic-opacity-95 p-3 mb-3">
|
||||||
|
<div class="card-body p-3">
|
||||||
|
<h3 class="card-title">
|
||||||
|
<a class="dynamic-post-title" href="/ssr#{{ .TopicID }}">{{ .Subg }}</a>
|
||||||
|
</h3>
|
||||||
|
<div class="card-subtitle text-white-50">
|
||||||
|
<p>
|
||||||
|
[<a href="/ssr#{{ .Echo }}"
|
||||||
|
title="Go to {{ .Echo }} echo">{{ .Echo }}</a>]
|
||||||
|
{{ .Date }}
|
||||||
|
@<a
|
||||||
|
title="{{ .Author }} posts"
|
||||||
|
href="/ssr#/author/{{ .Author }}">{{ .Author }}</a> ->
|
||||||
|
{{ if .Repto }}<a href="/ssr#{{.Repto}}">{{ .To }}</a>
|
||||||
|
{{ else }}{{ .To }}{{ end }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="card-text dynamic-post-text">
|
||||||
|
{{ .Message }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer text-white-50">
|
||||||
|
[<a href="/ssr#{{ .MsgID }}">#</a>] [<a href="/ssr#{{ .MsgID }}">reply</a>]
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ end }}
|
17
templates/root.html
Normal file
17
templates/root.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{{ template "header" . }}
|
||||||
|
|
||||||
|
{{ template "style" }}
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-2">
|
||||||
|
{{ template "echoes" . }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-9 text-primary">
|
||||||
|
{{ template "latest posts" . }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ template "footer" . }}
|
56
templates/style.html
Normal file
56
templates/style.html
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
{{ define "style" }}
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-image: url("https://dynamic.lessmore.pw/assets/bg.webp");
|
||||||
|
/* Full height */
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
/* Center and scale the image nicely */
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
background-attachment: fixed;
|
||||||
|
|
||||||
|
color: #657b83;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic-echo {
|
||||||
|
background-color: #002b36;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic-bg {
|
||||||
|
background-color: #002b36;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic-panel {
|
||||||
|
opacity: 0.75;
|
||||||
|
background-color: #002b36;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic-post-title {
|
||||||
|
color: #839496;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic-post-text {
|
||||||
|
white-space: pre-line;
|
||||||
|
color: #839496;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic-opacity-1 {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic-opacity-95 {
|
||||||
|
opacity: 0.95;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic-post {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
background-color: #002b36;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic-post a {
|
||||||
|
color: #268bd2;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{{ end }}
|
Loading…
Reference in New Issue
Block a user