aboutsummaryrefslogtreecommitdiffstats
path: root/internal/port/gopher.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/port/gopher.go')
-rw-r--r--internal/port/gopher.go138
1 files changed, 102 insertions, 36 deletions
diff --git a/internal/port/gopher.go b/internal/port/gopher.go
index abbc4d9..d2283c6 100644
--- a/internal/port/gopher.go
+++ b/internal/port/gopher.go
@@ -17,16 +17,73 @@ import (
17 "github.com/temoto/robotstxt" 17 "github.com/temoto/robotstxt"
18) 18)
19 19
20type Item struct { 20type gopherTemplateVariables struct {
21 Title string
22 URL string
23 Assets AssetList
24 Lines []GopherItem
25 Nav []GopherNavItem
26 IsPlain bool
27}
28
29type GopherNavItem struct {
30 Label string
31 URL string
32 Current bool
33}
34
35type GopherItem struct {
21 Link template.URL 36 Link template.URL
22 Type string 37 Type string
23 Text string 38 Text string
24} 39}
25 40
41func trimLeftChars(s string, n int) string {
42 m := 0
43 for i := range s {
44 if m >= n {
45 return s[i:]
46 }
47 m++
48 }
49 return s[:0]
50}
51
52func urlToNav(url string) (items []GopherNavItem) {
53 partialURL := "/gopher"
54 parts := strings.Split(url, "/")
55
56 for i, part := range parts {
57 if i == 1 {
58 partialURL = partialURL + "/1"
59 part = trimLeftChars(part, 1)
60
61 if part == "" {
62 continue
63 }
64 } else {
65 partialURL = partialURL + "/" + part
66 }
67
68 current := false
69 if i == len(parts)-1 || (len(parts) == 2 && i == 0) {
70 current = true
71 }
72
73 items = append(items, GopherNavItem{
74 Label: part,
75 URL: partialURL,
76 Current: current,
77 })
78 }
79
80 return
81}
82
26func renderGopherDirectory(w http.ResponseWriter, tpl *template.Template, assetList AssetList, uri string, hostport string, d libgopher.Directory) error { 83func renderGopherDirectory(w http.ResponseWriter, tpl *template.Template, assetList AssetList, uri string, hostport string, d libgopher.Directory) error {
27 var title string 84 var title string
28 85
29 out := make([]Item, len(d.Items)) 86 out := make([]GopherItem, len(d.Items))
30 87
31 for i, x := range d.Items { 88 for i, x := range d.Items {
32 if x.Type == libgopher.INFO && x.Selector == "TITLE" { 89 if x.Type == libgopher.INFO && x.Selector == "TITLE" {
@@ -34,7 +91,7 @@ func renderGopherDirectory(w http.ResponseWriter, tpl *template.Template, assetL
34 continue 91 continue
35 } 92 }
36 93
37 tr := Item{ 94 tr := GopherItem{
38 Text: x.Description, 95 Text: x.Description,
39 Type: x.Type.String(), 96 Type: x.Type.String(),
40 } 97 }
@@ -89,12 +146,12 @@ func renderGopherDirectory(w http.ResponseWriter, tpl *template.Template, assetL
89 } 146 }
90 } 147 }
91 148
92 return tpl.Execute(w, TemplateVariables{ 149 return tpl.Execute(w, gopherTemplateVariables{
93 Title: title, 150 Title: title,
94 URI: fmt.Sprintf("%s/%s", hostport, uri), 151 URL: fmt.Sprintf("%s/%s", hostport, uri),
95 Assets: assetList, 152 Assets: assetList,
96 Lines: out, 153 Lines: out,
97 Protocol: "gopher", 154 Nav: urlToNav(fmt.Sprintf("%s/%s", hostport, uri)),
98 }) 155 })
99} 156}
100 157
@@ -130,13 +187,15 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass
130 187
131 uri, err := url.QueryUnescape(strings.Join(parts[1:], "/")) 188 uri, err := url.QueryUnescape(strings.Join(parts[1:], "/"))
132 if err != nil { 189 if err != nil {
133 if e := tpl.Execute(w, TemplateVariables{ 190 if e := tpl.Execute(w, gopherTemplateVariables{
134 Title: title, 191 Title: title,
135 URI: hostport, 192 URL: hostport,
136 Assets: assetList, 193 Assets: assetList,
137 RawText: fmt.Sprintf("Error: %s", err), 194 Lines: []GopherItem{{
138 Error: true, 195 Text: fmt.Sprintf("Error: %s", err),
139 Protocol: "gopher", 196 }},
197 Nav: urlToNav(hostport),
198 IsPlain: true,
140 }); e != nil { 199 }); e != nil {
141 log.Println("Template error: " + e.Error()) 200 log.Println("Template error: " + e.Error())
142 log.Println(err.Error()) 201 log.Println(err.Error())
@@ -158,13 +217,15 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass
158 ) 217 )
159 218
160 if err != nil { 219 if err != nil {
161 if e := tpl.Execute(w, TemplateVariables{ 220 if e := tpl.Execute(w, gopherTemplateVariables{
162 Title: title, 221 Title: title,
163 URI: fmt.Sprintf("%s/%s", hostport, uri), 222 URL: fmt.Sprintf("%s/%s", hostport, uri),
164 Assets: assetList, 223 Assets: assetList,
165 RawText: fmt.Sprintf("Error: %s", err), 224 Lines: []GopherItem{{
166 Error: true, 225 Text: fmt.Sprintf("Error: %s", err),
167 Protocol: "gopher", 226 }},
227 Nav: urlToNav(fmt.Sprintf("%s/%s", hostport, uri)),
228 IsPlain: true,
168 }); e != nil { 229 }); e != nil {
169 log.Println("Template error: " + e.Error()) 230 log.Println("Template error: " + e.Error())
170 } 231 }
@@ -178,12 +239,15 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass
178 buf := new(bytes.Buffer) 239 buf := new(bytes.Buffer)
179 buf.ReadFrom(res.Body) 240 buf.ReadFrom(res.Body)
180 241
181 if err := tpl.Execute(w, TemplateVariables{ 242 if err := tpl.Execute(w, gopherTemplateVariables{
182 Title: title, 243 Title: title,
183 URI: fmt.Sprintf("%s/%s", hostport, uri), 244 URL: fmt.Sprintf("%s/%s", hostport, uri),
184 Assets: assetList, 245 Assets: assetList,
185 RawText: buf.String(), 246 Lines: []GopherItem{{
186 Protocol: "gopher", 247 Text: buf.String(),
248 }},
249 Nav: urlToNav(fmt.Sprintf("%s/%s", hostport, uri)),
250 IsPlain: true,
187 }); err != nil { 251 }); err != nil {
188 log.Println("Template error: " + err.Error()) 252 log.Println("Template error: " + err.Error())
189 } 253 }
@@ -200,13 +264,15 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass
200 } 264 }
201 } else { 265 } else {
202 if err := renderGopherDirectory(w, tpl, assetList, uri, hostport, res.Dir); err != nil { 266 if err := renderGopherDirectory(w, tpl, assetList, uri, hostport, res.Dir); err != nil {
203 if e := tpl.Execute(w, TemplateVariables{ 267 if e := tpl.Execute(w, gopherTemplateVariables{
204 Title: title, 268 Title: title,
205 URI: fmt.Sprintf("%s/%s", hostport, uri), 269 URL: fmt.Sprintf("%s/%s", hostport, uri),
206 Assets: assetList, 270 Assets: assetList,
207 RawText: fmt.Sprintf("Error: %s", err), 271 Lines: []GopherItem{{
208 Error: true, 272 Text: fmt.Sprintf("Error: %s", err),
209 Protocol: "gopher", 273 }},
274 Nav: urlToNav(fmt.Sprintf("%s/%s", hostport, uri)),
275 IsPlain: false,
210 }); e != nil { 276 }); e != nil {
211 log.Println("Template error: " + e.Error()) 277 log.Println("Template error: " + e.Error())
212 log.Println(e.Error()) 278 log.Println(e.Error())