Compare commits
2 commits
d636da952b
...
8c28d2ee0c
| Author | SHA1 | Date | |
|---|---|---|---|
| 8c28d2ee0c | |||
| 5c669f241f |
5 changed files with 30 additions and 77 deletions
7
go.mod
7
go.mod
|
|
@ -3,14 +3,7 @@ module gemini_site
|
|||
go 1.25.0
|
||||
|
||||
require (
|
||||
git.sr.ht/~kota/goldmark-gemtext v0.3.3
|
||||
git.travisshears.com/travisshears/gemlog-cli v1.1.0
|
||||
github.com/kulak/gemini v1.2.2
|
||||
github.com/mattn/go-sqlite3 v1.14.32
|
||||
github.com/yuin/goldmark v1.7.13
|
||||
)
|
||||
|
||||
require (
|
||||
git.sr.ht/~kota/fuckery v0.2.0 // indirect
|
||||
git.sr.ht/~kota/goldmark-wiki v0.0.0-20211119234413-891f759dc3aa // indirect
|
||||
)
|
||||
|
|
|
|||
12
go.sum
12
go.sum
|
|
@ -1,15 +1,7 @@
|
|||
git.sr.ht/~kota/fuckery v0.2.0 h1:0JfnSMiQWFVFdGplolb2ZuRqDQLG5uAzDmH/oSaRj9Y=
|
||||
git.sr.ht/~kota/fuckery v0.2.0/go.mod h1:UuYM/CTzL6F/FYB/uulUV1ceymM5NSJv2Qif3VVj/s8=
|
||||
git.sr.ht/~kota/goldmark-gemtext v0.3.3 h1:Vchc1qgEoBE0XgztZFJwKyAYmzNL/C0t34F+gNw0FDU=
|
||||
git.sr.ht/~kota/goldmark-gemtext v0.3.3/go.mod h1:nWcD/0KzomgMaY9t7odGt7mc5QWiaTnrP6CwxYDJHYY=
|
||||
git.sr.ht/~kota/goldmark-wiki v0.0.0-20211119234413-891f759dc3aa h1:4JHg1p9hfnZEJtVjmhFhvYV4RO12mMDQf6NFolFJDzo=
|
||||
git.sr.ht/~kota/goldmark-wiki v0.0.0-20211119234413-891f759dc3aa/go.mod h1:7bNFInCQWKDjV6b8qsLDwQ/q5XrVMjrACQjOnJGXe/4=
|
||||
git.travisshears.com/travisshears/gemlog-cli v1.1.0 h1:iFMIeYyzPvoUw2sQqGg8PTejCcKxgmhjy5HqpVo3Ag8=
|
||||
git.travisshears.com/travisshears/gemlog-cli v1.1.0/go.mod h1:N6l94N174EhDOIHU0/RlJ0PWrxB0BMa0W6LcpgAtvCE=
|
||||
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/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/kulak/gemini v1.2.2 h1:wPFOAFFdOf9ZaHcpMwTq1xYUWxmyV3h0uQl0OXCGa+A=
|
||||
github.com/kulak/gemini v1.2.2/go.mod h1:8yiD7yhLkUGvOpdvgd/0nKQD2I0ChIAKD3yHuT13R5k=
|
||||
github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs=
|
||||
|
|
@ -19,10 +11,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
|||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/yuin/goldmark v1.4.4/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg=
|
||||
github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA=
|
||||
github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
|
|
|||
8
home.gmi
8
home.gmi
|
|
@ -35,6 +35,14 @@ What I'm currently working on:
|
|||
|
||||
## Site updates
|
||||
|
||||
=> /codeview/raw/personal-gemini-capsule/src/branch/main/tasks.txt My current TODOs for this capsule can be in my tasks.txt
|
||||
|
||||
== 2025.15.07 ==
|
||||
|
||||
Added directory listing to codeview.
|
||||
|
||||
=> /codeview/dir?repo=personal-gemini-capsule&filepath=/internal Example
|
||||
|
||||
== 2025.11.07 ==
|
||||
|
||||
Added request counter. Scroll to bottom of this page to check it out.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package codeview
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
|
@ -10,10 +9,6 @@ import (
|
|||
"net/url"
|
||||
"strings"
|
||||
|
||||
gemtext "git.sr.ht/~kota/goldmark-gemtext"
|
||||
goldmark "github.com/yuin/goldmark"
|
||||
"github.com/yuin/goldmark/extension"
|
||||
|
||||
"github.com/kulak/gemini"
|
||||
)
|
||||
|
||||
|
|
@ -24,7 +19,7 @@ import (
|
|||
* Features:
|
||||
* - [x] Individual file view with line numbers?
|
||||
* - [x] Dir view with links to files
|
||||
* - [ ] Project root view with markdown to gemtxt conversion and file tree
|
||||
* - [x] Project root view with markdown to gemtxt conversion and file tree
|
||||
*/
|
||||
|
||||
func HandleRequest(w gemini.ResponseWriter, req *gemini.Request) {
|
||||
|
|
@ -119,13 +114,13 @@ func serveDir(w gemini.ResponseWriter, req *gemini.Request, path string) {
|
|||
for _, file := range dirRes {
|
||||
if file.Type == "file" && file.Name == "README.md" {
|
||||
slog.Info("Found README.md", "file", file)
|
||||
gemtext, err := getRemoteMarkdownFile(file.RawURL)
|
||||
body, err := getRemoteFile(file.RawURL)
|
||||
if err != nil {
|
||||
slog.Error("Failed to fetch README.md", "url", file.RawURL, "error", err)
|
||||
continue
|
||||
}
|
||||
content.WriteString("README.md found. The following is a markdown to gemtext conversion with directory listing below\n")
|
||||
content.WriteString(gemtext)
|
||||
content.WriteString("README.md found, directory listing below.\n")
|
||||
content.WriteString(renderCodeFile(body))
|
||||
content.WriteString("\n\n-----------------------------\n\n")
|
||||
}
|
||||
}
|
||||
|
|
@ -145,43 +140,32 @@ func serveDir(w gemini.ResponseWriter, req *gemini.Request, path string) {
|
|||
w.WriteBody([]byte(content.String()))
|
||||
}
|
||||
|
||||
func getRemoteMarkdownFile(url string) (string, error) {
|
||||
func renderCodeFile(code string) string {
|
||||
// Escape any triple backticks in the code to avoid prematurely ending Gemini preformatted blocks
|
||||
code = strings.ReplaceAll(code, "```", "\\`\\`\\`")
|
||||
return fmt.Sprintf("```code\n%s\n```", code)
|
||||
}
|
||||
|
||||
func getRemoteFile(url string) (string, error) {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
slog.Error("Failed to fetch remote markdown file", "url", url, "error", err)
|
||||
slog.Error("Failed to fetch remote file", "url", url, "error", err)
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
slog.Error("Failed to fetch remote markdown file", "url", url, "status", resp.Status)
|
||||
return "", fmt.Errorf("failed to fetch remote markdown file")
|
||||
slog.Error("Failed to fetch remote file", "url", url, "status", resp.Status)
|
||||
return "", fmt.Errorf("failed to fetch remote file")
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
slog.Error("Failed to read remote markdown file", "url", url, "error", err)
|
||||
slog.Error("Failed to read remote file", "url", url, "error", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
return convertMdToGemtext(string(body)), nil
|
||||
}
|
||||
|
||||
func convertMdToGemtext(markdown string) string {
|
||||
var buf bytes.Buffer
|
||||
md := goldmark.New(
|
||||
goldmark.WithExtensions(
|
||||
extension.Linkify,
|
||||
extension.Strikethrough,
|
||||
),
|
||||
)
|
||||
|
||||
// set some options
|
||||
// options := []Option{WithHeadingLink(HeadingLinkAuto), WithCodeSpan(CodeSpanMarkdown)}
|
||||
|
||||
md.SetRenderer(gemtext.New())
|
||||
_ = md.Convert([]byte(markdown), &buf) // ignoring errors for example
|
||||
return buf.String()
|
||||
return string(body), nil
|
||||
}
|
||||
|
||||
func serveFile(w gemini.ResponseWriter, req *gemini.Request, path string) {
|
||||
|
|
@ -189,32 +173,12 @@ func serveFile(w gemini.ResponseWriter, req *gemini.Request, path string) {
|
|||
rawURL := strings.Replace(path, "src", "raw", 1)
|
||||
rawURL = "https://git.travisshears.com/travisshears/" + rawURL
|
||||
remoteURL := "https://git.travisshears.com/travisshears/" + path
|
||||
httpReq, err := http.NewRequest("GET", rawURL, nil)
|
||||
body, err := getRemoteFile(rawURL)
|
||||
if err != nil {
|
||||
slog.Error("Failed to create request to git server", "error", err)
|
||||
w.WriteStatusMsg(gemini.StatusGeneralPermFail, "Problem connecting to git server")
|
||||
return
|
||||
}
|
||||
res, err := http.DefaultClient.Do(httpReq)
|
||||
if err != nil {
|
||||
slog.Error("Failed to send request to git server", "error", err)
|
||||
w.WriteStatusMsg(gemini.StatusGeneralPermFail, "Problem connecting to git server")
|
||||
return
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
slog.Error("Failed to read res body", "error", err)
|
||||
w.WriteStatusMsg(gemini.StatusGeneralPermFail, "Problem connecting to git server")
|
||||
return
|
||||
}
|
||||
|
||||
if res.StatusCode < 200 || res.StatusCode >= 300 {
|
||||
slog.Error("unexpected status code", "statusCode", res.StatusCode, "body", string(body))
|
||||
w.WriteStatusMsg(gemini.StatusGeneralPermFail, "Problem connecting to git server")
|
||||
return
|
||||
}
|
||||
|
||||
var content strings.Builder
|
||||
w.WriteStatusMsg(gemini.StatusSuccess, "text/gemini")
|
||||
|
|
@ -223,9 +187,7 @@ func serveFile(w gemini.ResponseWriter, req *gemini.Request, path string) {
|
|||
content.WriteString("# File CodeView\n")
|
||||
content.WriteString(fmt.Sprintf("This is a code view which proxies my personal git server. On the clearnet the following file is available at:\n=> %s %s\n\n", remoteURL, path))
|
||||
content.WriteString("----------------------------\n\n")
|
||||
content.WriteString("```code\n")
|
||||
content.Write(body)
|
||||
content.WriteString("```\n")
|
||||
content.WriteString(renderCodeFile(body))
|
||||
content.WriteString("\n\n-----------------------------\n\n=> / Back to home\n")
|
||||
w.WriteBody([]byte(content.String()))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
task: implement dir codeview pages
|
||||
task: implement codbase root codeview pages
|
||||
task: rework the micro-blog to be more like station
|
||||
task: add mastodon and bluysky to microblog
|
||||
-----------DONE LINE-----------
|
||||
DONE task: implement dir codeview pages
|
||||
DONE task: implement codbase root codeview pages
|
||||
DONE task: add hexidecimal numbering to gemlog
|
||||
DONE task: add request counter
|
||||
DONE task: embed static pages
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue