From 97dc50bcfb7d4296dd11348b9d7470821fb6afbc Mon Sep 17 00:00:00 2001 From: Feuerfuchs Date: Mon, 18 May 2020 14:14:25 +0200 Subject: WIP: Refactoring --- internal/port/gemini.go | 176 +++++++++++++++++++++++++++++++++++++----------- internal/port/gopher.go | 2 +- internal/port/main.go | 2 + 3 files changed, 140 insertions(+), 40 deletions(-) (limited to 'internal/port') diff --git a/internal/port/gemini.go b/internal/port/gemini.go index f9b0b97..b10da7d 100644 --- a/internal/port/gemini.go +++ b/internal/port/gemini.go @@ -1,6 +1,7 @@ package port import ( + "bufio" "bytes" "fmt" "html/template" @@ -15,11 +16,32 @@ import ( "golang.org/x/net/html/charset" "golang.org/x/text/transform" - "git.vulpes.one/Feuerfuchs/port/port/libgemini" + "git.vulpes.one/Feuerfuchs/port/pkg/libgemini" "github.com/temoto/robotstxt" ) +type SectionType byte + +const ( + RAW_TEXT = SectionType(0) + REFLOW_TEXT = SectionType(1) + LINK = SectionType(2) +) + +type Section struct { + Type SectionType + Text string + URL template.URL +} + +type templateVariables struct { + Title string + URI string + Assets AssetList + Sections []Section +} + var ( TermEscapeSGRPattern = regexp.MustCompile("\\[\\d+(;\\d+)*m") ) @@ -53,6 +75,80 @@ func resolveURI(uri string, baseURL *url.URL) (resolvedURI string) { return } +func parseGeminiDocument(body *bytes.Buffer, uri string, hostport string) (sections []Section) { + baseURL, err := url.Parse(fmt.Sprintf( + "gemini://%s/%s", + hostport, + uri, + )) + if err != nil { + return []Section{} + } + + skipSection := true + + section := Section{ + Type: RAW_TEXT, + } + + scanner := bufio.NewScanner(body) + + for scanner.Scan() { + line := strings.Trim(scanner.Text(), "\r\n") + line = TermEscapeSGRPattern.ReplaceAllString(line, "") + + linkMatch := libgemini.LinkPattern.FindStringSubmatch(line) + if len(linkMatch) != 0 && linkMatch[0] != "" { + curType := section.Type + + if !skipSection { + sections = append(sections, section) + } + + label := linkMatch[2] + if label == "" { + label = linkMatch[1] + } + + sections = append(sections, Section{ + Type: LINK, + Text: label, + URL: template.URL(resolveURI(linkMatch[1], baseURL)), + }) + + skipSection = false + section = Section{ + Type: curType, + } + } else { + reflowModeMatch := libgemini.ReflowModePattern.FindStringSubmatch(line) + if len(reflowModeMatch) != 0 { + newType := RAW_TEXT + if section.Type == RAW_TEXT { + newType = REFLOW_TEXT + } + + if !skipSection { + sections = append(sections, section) + } + + skipSection = false + section = Section{ + Type: newType, + } + } else { + section.Text = section.Text + "\n" + line + } + } + } + + if !skipSection { + sections = append(sections, section) + } + + return +} + func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, assetList AssetList, robotsdebug bool) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { agent := req.UserAgent() @@ -80,13 +176,14 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass uri, err := url.QueryUnescape(strings.Join(parts[1:], "/")) if err != nil { - if e := tpl.Execute(w, TemplateVariables{ - Title: title, - URI: hostport, - Assets: assetList, - RawText: fmt.Sprintf("Error: %s", err), - Error: true, - Protocol: "gemini", + if e := tpl.Execute(w, templateVariables{ + Title: title, + URI: hostport, + Assets: assetList, + Sections: []Section{{ + Type: RAW_TEXT, + Text: fmt.Sprintf("Error: %s", err), + }}, }); e != nil { log.Println("Template error: " + e.Error()) log.Println(err.Error()) @@ -108,13 +205,14 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass ) if err != nil { - if e := tpl.Execute(w, TemplateVariables{ - Title: title, - URI: fmt.Sprintf("%s/%s", hostport, uri), - Assets: assetList, - RawText: fmt.Sprintf("Error: %s", err), - Error: true, - Protocol: "gemini", + if e := tpl.Execute(w, templateVariables{ + Title: title, + URI: fmt.Sprintf("%s/%s", hostport, uri), + Assets: assetList, + Sections: []Section{{ + Type: RAW_TEXT, + Text: fmt.Sprintf("Error: %s", err), + }}, }); e != nil { log.Println("Template error: " + e.Error()) log.Println(err.Error()) @@ -129,13 +227,14 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass uri, )) if err != nil { - if e := tpl.Execute(w, TemplateVariables{ - Title: title, - URI: fmt.Sprintf("%s/%s", hostport, uri), - Assets: assetList, - RawText: fmt.Sprintf("Error: %s", err), - Error: true, - Protocol: "gemini", + if e := tpl.Execute(w, templateVariables{ + Title: title, + URI: fmt.Sprintf("%s/%s", hostport, uri), + Assets: assetList, + Sections: []Section{{ + Type: RAW_TEXT, + Text: fmt.Sprintf("Error: %s", err), + }}, }); e != nil { log.Println("Template error: " + e.Error()) log.Println(err.Error()) @@ -148,13 +247,14 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass } if int(res.Header.Status/10) != 2 { - if err := tpl.Execute(w, TemplateVariables{ - Title: title, - URI: fmt.Sprintf("%s/%s", hostport, uri), - Assets: assetList, - RawText: fmt.Sprintf("Error %d: %s", res.Header.Status, res.Header.Meta), - Error: true, - Protocol: "gemini", + if err := tpl.Execute(w, templateVariables{ + Title: title, + URI: fmt.Sprintf("%s/%s", hostport, uri), + Assets: assetList, + Sections: []Section{{ + Type: RAW_TEXT, + Text: fmt.Sprintf("Error %d: %s", res.Header.Status, res.Header.Meta), + }}, }); err != nil { log.Println("Template error: " + err.Error()) } @@ -177,24 +277,22 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass writer.Close() } - var ( - rawText string - items []Item - ) + var sections []Section if strings.HasPrefix(res.Header.Meta, libgemini.MIME_GEMINI) { - items = parseGeminiDocument(buf, uri, hostport) + sections = parseGeminiDocument(buf, uri, hostport) } else { - rawText = buf.String() + sections = append(sections, Section{ + Type: RAW_TEXT, + Text: buf.String(), + }) } - if err := tpl.Execute(w, TemplateVariables{ + if err := tpl.Execute(w, templateVariables{ Title: title, URI: fmt.Sprintf("%s/%s", hostport, uri), Assets: assetList, - Lines: items, - RawText: rawText, - Protocol: "gemini", + Sections: sections, }); err != nil { log.Println("Template error: " + err.Error()) } diff --git a/internal/port/gopher.go b/internal/port/gopher.go index ebeb213..abbc4d9 100644 --- a/internal/port/gopher.go +++ b/internal/port/gopher.go @@ -11,7 +11,7 @@ import ( "net/url" "strings" - "git.vulpes.one/Feuerfuchs/port/port/libgopher" + "git.vulpes.one/Feuerfuchs/port/pkg/libgopher" "github.com/davidbyttow/govips/pkg/vips" "github.com/temoto/robotstxt" diff --git a/internal/port/main.go b/internal/port/main.go index 5cdd794..9fa245e 100644 --- a/internal/port/main.go +++ b/internal/port/main.go @@ -205,6 +205,8 @@ func ListenAndServe(bind, startpagefile string, robotsfile string, robotsdebug b // // + var templates *template.Template + var allFiles []string files, err := ioutil.ReadDir("./tpl") if err != nil { -- cgit v1.2.3-70-g09d2