summaryrefslogtreecommitdiff
path: root/gemini
diff options
context:
space:
mode:
authortjpcc <tjp@ctrl-c.club>2023-08-31 20:16:16 -0600
committertjpcc <tjp@ctrl-c.club>2023-08-31 20:16:16 -0600
commit0fe9ec0c90bfe82f637f1897e47fec07f90805ec (patch)
treec483fd2b4834a9ba281c92220bcf8adb9e13fb46 /gemini
parentd3d5d0df7fcc353318feadb57e1775f10778d505 (diff)
move gemtext->atom conversion into package atomconv like the other converters
Diffstat (limited to 'gemini')
-rw-r--r--gemini/gemtext/atomconv/convert.go (renamed from gemini/gemtext/sub.go)50
-rw-r--r--gemini/gemtext/atomconv/convert_test.go (renamed from gemini/gemtext/sub_test.go)13
2 files changed, 33 insertions, 30 deletions
diff --git a/gemini/gemtext/sub.go b/gemini/gemtext/atomconv/convert.go
index 269695f..30228f3 100644
--- a/gemini/gemtext/sub.go
+++ b/gemini/gemtext/atomconv/convert.go
@@ -1,4 +1,4 @@
-package gemtext
+package atomconv
import (
"bytes"
@@ -13,44 +13,46 @@ import (
"time"
"tildegit.org/tjp/sliderule/gemini"
+ "tildegit.org/tjp/sliderule/gemini/gemtext"
"tildegit.org/tjp/sliderule/internal/types"
)
-// GmisubToAtom converts a gemini document to Atom format.
+// Convert turns a gemini document to Atom format.
//
// It identifies feed fields and entries according to the specification at
// gemini://gemini.circumlunar.space/docs/companion/subscription.gmi
-func GmisubToAtom(doc Document, location url.URL, out io.Writer) error {
- if _, err := out.Write([]byte(`<?xml version="1.0" encoding="utf-8"?>`)); err != nil {
- return err
+func Convert(wr io.Writer, doc gemtext.Document, location *url.URL) error {
+ if location == nil {
+ panic("atomconv.Convert: provided location was nil")
}
- if _, err := out.Write([]byte{'\n'}); err != nil {
+
+ if _, err := wr.Write([]byte(`<?xml version="1.0" encoding="utf-8"?>`)); err != nil {
return err
}
- if err := atomTmpl.Execute(out, parseGemSub(doc, &location)); err != nil {
+ if _, err := wr.Write([]byte{'\n'}); err != nil {
return err
}
- return nil
+ return atomTmpl.Execute(wr, parseGemSub(doc, location))
}
-// AutoAtom is a middleware which builds atom feeds for any gemtext pages.
+// Auto is a middleware which builds atom feeds for any gemtext pages.
//
// It looks for requests ending with the '.atom' extension, passes through the request
// with the extension clipped off, then if the response is in gemtext it converts it to
// an Atom feed according to the gmisub spec at
// gemini://gemini.circumlunar.space/docs/companion/subscription.gmi
-var AutoAtom = types.Middleware(func(h types.Handler) types.Handler {
+var Auto = types.Middleware(func(h types.Handler) types.Handler {
return types.HandlerFunc(func(ctx context.Context, request *types.Request) *types.Response {
if request.Scheme != "gemini" || !strings.HasSuffix(request.Path, ".atom") {
return h.Handle(ctx, request)
}
- req := *request
+ r := *request
u := *request.URL
- u.Path = strings.TrimSuffix(u.Path, ".atom")
- req.URL = &u
+ u.Path = u.Path[:len(u.Path)-5]
+ r.URL = &u
- response := h.Handle(ctx, &req)
+ response := h.Handle(ctx, &r)
if response.Status != gemini.StatusSuccess {
return response
}
@@ -64,13 +66,13 @@ var AutoAtom = types.Middleware(func(h types.Handler) types.Handler {
_ = response.Close()
}()
- doc, err := Parse(response.Body)
+ doc, err := gemtext.Parse(response.Body)
if err != nil {
return gemini.Failure(err)
}
buf := &bytes.Buffer{}
- if err := GmisubToAtom(doc, *request.URL, buf); err != nil {
+ if err := Convert(buf, doc, request.URL); err != nil {
return gemini.Failure(err)
}
return gemini.Success("application/atom+xml; charset=utf-8", buf)
@@ -94,18 +96,18 @@ type gmiSubEntry struct {
var linkElemRE = regexp.MustCompile(`(\d{4})-([0-1]\d)-([0-3]\d)`)
-func parseGemSub(doc Document, location *url.URL) *gmiSub {
+func parseGemSub(doc gemtext.Document, location *url.URL) *gmiSub {
sub := &gmiSub{ID: template.URL(location.String())}
updated := time.Time{}
for i, line := range doc {
switch line.Type() {
- case LineTypeHeading1:
+ case gemtext.LineTypeHeading1:
if sub.Title != "" {
continue
}
- sub.Title = line.(HeadingLine).Body()
+ sub.Title = line.(gemtext.HeadingLine).Body()
for { // skip any empty lines
i += 1
@@ -113,11 +115,11 @@ func parseGemSub(doc Document, location *url.URL) *gmiSub {
break
}
}
- if i < len(doc) && doc[i].Type() == LineTypeHeading2 {
- sub.Subtitle = doc[i].(HeadingLine).Body()
+ if i < len(doc) && doc[i].Type() == gemtext.LineTypeHeading2 {
+ sub.Subtitle = doc[i].(gemtext.HeadingLine).Body()
}
- case LineTypeLink:
- label := line.(LinkLine).Label()
+ case gemtext.LineTypeLink:
+ label := line.(gemtext.LinkLine).Label()
if len(label) < 10 {
continue
}
@@ -143,7 +145,7 @@ func parseGemSub(doc Document, location *url.URL) *gmiSub {
entryTitle := strings.TrimLeft(strings.TrimPrefix(strings.TrimLeft(label[10:], " \t"), "-"), " \t")
sub.Entries = append(sub.Entries, gmiSubEntry{
- ID: template.URL(line.(LinkLine).URL()),
+ ID: template.URL(line.(gemtext.LinkLine).URL()),
Updated: entryUpdated.Format(time.RFC3339),
Title: entryTitle,
})
diff --git a/gemini/gemtext/sub_test.go b/gemini/gemtext/atomconv/convert_test.go
index 9e0fcc8..8adaa2e 100644
--- a/gemini/gemtext/sub_test.go
+++ b/gemini/gemtext/atomconv/convert_test.go
@@ -1,4 +1,4 @@
-package gemtext
+package atomconv
import (
"bytes"
@@ -10,10 +10,11 @@ import (
"tildegit.org/tjp/sliderule"
"tildegit.org/tjp/sliderule/gemini"
+ "tildegit.org/tjp/sliderule/gemini/gemtext"
"tildegit.org/tjp/sliderule/internal/types"
)
-func TestGemsubToAtom(t *testing.T) {
+func TestConvert(t *testing.T) {
tests := []struct {
url string
input string
@@ -50,7 +51,7 @@ func TestGemsubToAtom(t *testing.T) {
for _, test := range tests {
t.Run(test.url, func(t *testing.T) {
- doc, err := Parse(bytes.NewBufferString(test.input))
+ doc, err := gemtext.Parse(bytes.NewBufferString(test.input))
if err != nil {
t.Fatal(err)
}
@@ -59,7 +60,7 @@ func TestGemsubToAtom(t *testing.T) {
t.Fatal(err)
}
out := &bytes.Buffer{}
- if err := GmisubToAtom(doc, *loc, out); err != nil {
+ if err := Convert(out, doc, loc); err != nil {
t.Fatal(err)
}
if out.String() != test.output {
@@ -69,7 +70,7 @@ func TestGemsubToAtom(t *testing.T) {
}
}
-func TestAutoAtom(t *testing.T) {
+func TestAuto(t *testing.T) {
rout := &sliderule.Router{}
rout.Route("/foo.gmi", types.HandlerFunc(func(ctx context.Context, request *types.Request) *types.Response {
@@ -92,7 +93,7 @@ func TestAutoAtom(t *testing.T) {
`[1:]))
}))
- h := AutoAtom(rout.Handler())
+ h := Auto(rout.Handler())
response := h.Handle(context.Background(), &types.Request{URL: &url.URL{
Scheme: "gemini",