mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2025-01-08 10:51:09 +00:00
Add proof-of-concept Gemini output of /hypha/
This commit is contained in:
parent
5d8ee3a997
commit
5cafaaa3d8
3
Makefile
3
Makefile
@ -4,6 +4,9 @@ run: build
|
|||||||
run_with_fixed_auth: build
|
run_with_fixed_auth: build
|
||||||
./mycorrhiza -auth-method fixed metarrhiza
|
./mycorrhiza -auth-method fixed metarrhiza
|
||||||
|
|
||||||
|
run_with_gemini: build
|
||||||
|
./mycorrhiza -gemini-cert-path "." metarrhiza
|
||||||
|
|
||||||
build:
|
build:
|
||||||
go generate
|
go generate
|
||||||
go build .
|
go build .
|
||||||
|
1
flag.go
1
flag.go
@ -19,6 +19,7 @@ func init() {
|
|||||||
flag.StringVar(&util.AuthMethod, "auth-method", "none", "What auth method to use. Variants: \"none\", \"fixed\"")
|
flag.StringVar(&util.AuthMethod, "auth-method", "none", "What auth method to use. Variants: \"none\", \"fixed\"")
|
||||||
flag.StringVar(&util.FixedCredentialsPath, "fixed-credentials-path", "mycocredentials.json", "Used when -auth-method=fixed. Path to file with user credentials.")
|
flag.StringVar(&util.FixedCredentialsPath, "fixed-credentials-path", "mycocredentials.json", "Used when -auth-method=fixed. Path to file with user credentials.")
|
||||||
flag.StringVar(&util.HeaderLinksHypha, "header-links-hypha", "", "Optional hypha that overrides the header links")
|
flag.StringVar(&util.HeaderLinksHypha, "header-links-hypha", "", "Optional hypha that overrides the header links")
|
||||||
|
flag.StringVar(&util.GeminiCertPath, "gemini-cert-path", "", "Directory where you store Gemini certificates. Leave empty if you don't want to use Gemini.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do the things related to cli args and die maybe
|
// Do the things related to cli args and die maybe
|
||||||
|
83
gemini.go
Normal file
83
gemini.go
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509/pkix"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.sr.ht/~adnano/go-gemini"
|
||||||
|
"git.sr.ht/~adnano/go-gemini/certificate"
|
||||||
|
|
||||||
|
"github.com/bouncepaw/mycorrhiza/markup"
|
||||||
|
"github.com/bouncepaw/mycorrhiza/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
func geminiHomeHypha(w *gemini.ResponseWriter, rq *gemini.Request) {
|
||||||
|
log.Println(rq.URL)
|
||||||
|
w.Write([]byte(`# MycorrhizaWiki
|
||||||
|
|
||||||
|
You have successfully served the wiki through Gemini. Currently, support is really work-in-progress; you should resort to using Mycorrhiza through the web protocols.
|
||||||
|
|
||||||
|
Visit home hypha:
|
||||||
|
=> /hypha/` + util.HomePage))
|
||||||
|
}
|
||||||
|
|
||||||
|
func geminiHypha(w *gemini.ResponseWriter, rq *gemini.Request) {
|
||||||
|
log.Println(rq.URL)
|
||||||
|
var (
|
||||||
|
hyphaName = geminiHyphaNameFromRq(rq, "page", "hypha")
|
||||||
|
data, hyphaExists = HyphaStorage[hyphaName]
|
||||||
|
hasAmnt = hyphaExists && data.BinaryPath != ""
|
||||||
|
contents string
|
||||||
|
)
|
||||||
|
if hyphaExists {
|
||||||
|
fileContentsT, errT := ioutil.ReadFile(data.TextPath)
|
||||||
|
if errT == nil {
|
||||||
|
md := markup.Doc(hyphaName, string(fileContentsT))
|
||||||
|
contents = md.AsGemtext()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if hasAmnt {
|
||||||
|
w.Write([]byte("This hypha has an attachment\n"))
|
||||||
|
}
|
||||||
|
w.Write([]byte(contents))
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleGemini() {
|
||||||
|
if util.GeminiCertPath == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
certPath, err := filepath.Abs(util.GeminiCertPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var server gemini.Server
|
||||||
|
server.ReadTimeout = 30 * time.Second
|
||||||
|
server.WriteTimeout = 1 * time.Minute
|
||||||
|
if err := server.Certificates.Load(certPath); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
server.CreateCertificate = func(hostname string) (tls.Certificate, error) {
|
||||||
|
return certificate.Create(certificate.CreateOptions{
|
||||||
|
Subject: pkix.Name{
|
||||||
|
CommonName: hostname,
|
||||||
|
},
|
||||||
|
DNSNames: []string{hostname},
|
||||||
|
Duration: 365 * 24 * time.Hour,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var mux gemini.ServeMux
|
||||||
|
mux.HandleFunc("/", geminiHomeHypha)
|
||||||
|
mux.HandleFunc("/hypha/", geminiHypha)
|
||||||
|
mux.HandleFunc("/page/", geminiHypha)
|
||||||
|
|
||||||
|
server.Handle("localhost", &mux)
|
||||||
|
if err := server.ListenAndServe(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
2
go.mod
2
go.mod
@ -3,8 +3,10 @@ module github.com/bouncepaw/mycorrhiza
|
|||||||
go 1.14
|
go 1.14
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
git.sr.ht/~adnano/go-gemini v0.1.13
|
||||||
github.com/adrg/xdg v0.2.2
|
github.com/adrg/xdg v0.2.2
|
||||||
github.com/gorilla/feeds v1.1.1
|
github.com/gorilla/feeds v1.1.1
|
||||||
github.com/kr/pretty v0.2.1 // indirect
|
github.com/kr/pretty v0.2.1 // indirect
|
||||||
github.com/valyala/quicktemplate v1.6.3
|
github.com/valyala/quicktemplate v1.6.3
|
||||||
|
tildegit.org/solderpunk/gemcert v0.0.0-20200801165357-fc14deb27512 // indirect
|
||||||
)
|
)
|
||||||
|
4
go.sum
4
go.sum
@ -1,3 +1,5 @@
|
|||||||
|
git.sr.ht/~adnano/go-gemini v0.1.13 h1:vzKkkVrOzMpfJ1AAeE/PChg0Rw5Zf+9HrnwsgVxXUT4=
|
||||||
|
git.sr.ht/~adnano/go-gemini v0.1.13/go.mod h1:If1VxEWcZDrRt5FeAFnGTcM2Ud1E3BXs3VJ5rnZWKq0=
|
||||||
github.com/adrg/xdg v0.2.2 h1:A7ZHKRz5KGOLJX/bg7IPzStryhvCzAE1wX+KWawPiAo=
|
github.com/adrg/xdg v0.2.2 h1:A7ZHKRz5KGOLJX/bg7IPzStryhvCzAE1wX+KWawPiAo=
|
||||||
github.com/adrg/xdg v0.2.2/go.mod h1:7I2hH/IT30IsupOpKZ5ue7/qNi3CoKzD6tL3HwpaRMQ=
|
github.com/adrg/xdg v0.2.2/go.mod h1:7I2hH/IT30IsupOpKZ5ue7/qNi3CoKzD6tL3HwpaRMQ=
|
||||||
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||||
@ -33,3 +35,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
|
|||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
tildegit.org/solderpunk/gemcert v0.0.0-20200801165357-fc14deb27512 h1:reGEt1vmGompn/6FitHdBatILTsK9CYnQOCw3weoW/s=
|
||||||
|
tildegit.org/solderpunk/gemcert v0.0.0-20200801165357-fc14deb27512/go.mod h1:gqBK7AJ5wPR1bpFOuPmlQObYxwXrFdZmNb2vdzquqoA=
|
||||||
|
2
main.go
2
main.go
@ -193,6 +193,8 @@ func main() {
|
|||||||
history.Start(WikiDir)
|
history.Start(WikiDir)
|
||||||
setHeaderLinks()
|
setHeaderLinks()
|
||||||
|
|
||||||
|
go handleGemini()
|
||||||
|
|
||||||
// See http_readers.go for /page/, /hypha/, /text/, /binary/
|
// See http_readers.go for /page/, /hypha/, /text/, /binary/
|
||||||
// See http_mutators.go for /upload-binary/, /upload-text/, /edit/, /delete-ask/, /delete-confirm/, /rename-ask/, /rename-confirm/, /unattach-ask/, /unattach-confirm/
|
// See http_mutators.go for /upload-binary/, /upload-text/, /edit/, /delete-ask/, /delete-confirm/, /rename-ask/, /rename-confirm/, /unattach-ask/, /unattach-confirm/
|
||||||
// See http_auth.go for /login, /login-data, /logout, /logout-confirm
|
// See http_auth.go for /login, /login-data, /logout, /logout-confirm
|
||||||
|
@ -48,6 +48,11 @@ func (md *MycoDoc) AsHTML() string {
|
|||||||
return md.html
|
return md.html
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AsGemtext returns a gemtext representation of the document. Currently really limited, just returns source text
|
||||||
|
func (md *MycoDoc) AsGemtext() string {
|
||||||
|
return md.contents
|
||||||
|
}
|
||||||
|
|
||||||
// Used to clear opengraph description from html tags. This method is usually bad because of dangers of malformed HTML, but I'm going to use it only for Mycorrhiza-generated HTML, so it's okay. The question mark is required; without it the whole string is eaten away.
|
// Used to clear opengraph description from html tags. This method is usually bad because of dangers of malformed HTML, but I'm going to use it only for Mycorrhiza-generated HTML, so it's okay. The question mark is required; without it the whole string is eaten away.
|
||||||
var htmlTagRe = regexp.MustCompile(`<.*?>`)
|
var htmlTagRe = regexp.MustCompile(`<.*?>`)
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit be5b922e9b564551601d21ed45bf7d9ced65c6bb
|
Subproject commit e7040f3e0dc41809063b77fcbc12fe33b234ea87
|
14
name.go
14
name.go
@ -6,6 +6,8 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"git.sr.ht/~adnano/go-gemini"
|
||||||
|
|
||||||
"github.com/bouncepaw/mycorrhiza/util"
|
"github.com/bouncepaw/mycorrhiza/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -58,3 +60,15 @@ func HyphaNameFromRq(rq *http.Request, actions ...string) string {
|
|||||||
log.Fatal("HyphaNameFromRq: no matching action passed")
|
log.Fatal("HyphaNameFromRq: no matching action passed")
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// geminiHyphaNameFromRq extracts hypha name from gemini request. You have to also pass the action which is embedded in the url or several actions. For url /hypha/hypha, the action would be "hypha".
|
||||||
|
func geminiHyphaNameFromRq(rq *gemini.Request, actions ...string) string {
|
||||||
|
p := rq.URL.Path
|
||||||
|
for _, action := range actions {
|
||||||
|
if strings.HasPrefix(p, "/"+action+"/") {
|
||||||
|
return util.CanonicalName(strings.TrimPrefix(p, "/"+action+"/"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Fatal("HyphaNameFromRq: no matching action passed")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
@ -19,6 +19,7 @@ var (
|
|||||||
HeaderLinksHypha string
|
HeaderLinksHypha string
|
||||||
AuthMethod string
|
AuthMethod string
|
||||||
FixedCredentialsPath string
|
FixedCredentialsPath string
|
||||||
|
GeminiCertPath string
|
||||||
)
|
)
|
||||||
|
|
||||||
// ShorterPath is used by handlerList to display shorter path to the files. It simply strips WikiDir.
|
// ShorterPath is used by handlerList to display shorter path to the files. It simply strips WikiDir.
|
||||||
|
Loading…
Reference in New Issue
Block a user