mirror of
https://github.com/makew0rld/amfora.git
synced 2024-09-27 23:05:55 -04:00
🎨 Move render code around
This commit is contained in:
parent
cc17b1693b
commit
fdd98a1487
@ -399,18 +399,6 @@ func Reload() {
|
|||||||
// URL loads and handles the provided URL for the current tab.
|
// URL loads and handles the provided URL for the current tab.
|
||||||
// It should be an absolute URL.
|
// It should be an absolute URL.
|
||||||
func URL(u string) {
|
func URL(u string) {
|
||||||
// Old relative URL handling stuff:
|
|
||||||
// parsed, err := url.Parse(u)
|
|
||||||
// if err != nil {
|
|
||||||
// Error("Bad URL", err.Error())
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// if tabHasContent() && parsed.Host == "" {
|
|
||||||
// // Relative link
|
|
||||||
// followLink(tabMap[curTab].Url, u)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
final, displayed := handleURL(u)
|
final, displayed := handleURL(u)
|
||||||
if displayed {
|
if displayed {
|
||||||
|
95
renderer/page.go
Normal file
95
renderer/page.go
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
package renderer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
|
"mime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/makeworld-the-better-one/amfora/structs"
|
||||||
|
"github.com/makeworld-the-better-one/go-gemini"
|
||||||
|
"golang.org/x/text/encoding/ianaindex"
|
||||||
|
)
|
||||||
|
|
||||||
|
// isUTF8 returns true for charsets that are compatible with UTF-8 and don't need to be decoded.
|
||||||
|
func isUTF8(charset string) bool {
|
||||||
|
utfCharsets := []string{"", "utf-8", "us-ascii"}
|
||||||
|
for i := range utfCharsets {
|
||||||
|
if strings.ToLower(charset) == utfCharsets[i] {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanDisplay returns true if the response is supported by Amfora
|
||||||
|
// for displaying on the screen.
|
||||||
|
// It also doubles as a function to detect whether something can be stored in a Page struct.
|
||||||
|
func CanDisplay(res *gemini.Response) bool {
|
||||||
|
if gemini.SimplifyStatus(res.Status) != 20 {
|
||||||
|
// No content
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
mediatype, params, err := mime.ParseMediaType(res.Meta)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if mediatype != "text/gemini" && mediatype != "text/plain" {
|
||||||
|
// Amfora doesn't support other filetypes
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if isUTF8(params["charset"]) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
enc, err := ianaindex.MIME.Encoding(params["charset"]) // Lowercasing is done inside
|
||||||
|
// Encoding sometimes returns nil, see #3 on this repo and golang/go#19421
|
||||||
|
return err == nil && enc != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakePage(url string, res *gemini.Response) (*structs.Page, error) {
|
||||||
|
if !CanDisplay(res) {
|
||||||
|
return nil, errors.New("not valid content for a Page")
|
||||||
|
}
|
||||||
|
|
||||||
|
rawText, err := ioutil.ReadAll(res.Body) // TODO: Don't use all memory on large pages
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res.Body.Close()
|
||||||
|
|
||||||
|
mediatype, params, _ := mime.ParseMediaType(res.Meta)
|
||||||
|
|
||||||
|
// Convert content first
|
||||||
|
var utfText string
|
||||||
|
if isUTF8(params["charset"]) {
|
||||||
|
utfText = string(rawText)
|
||||||
|
} else {
|
||||||
|
encoding, err := ianaindex.MIME.Encoding(params["charset"])
|
||||||
|
if encoding == nil || err != nil {
|
||||||
|
// Some encoding doesn't exist and wasn't caught in CanDisplay()
|
||||||
|
return nil, errors.New("unsupported encoding")
|
||||||
|
}
|
||||||
|
utfText, err = encoding.NewDecoder().String(string(rawText))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if mediatype == "text/plain" {
|
||||||
|
return &structs.Page{
|
||||||
|
Url: url,
|
||||||
|
Content: utfText,
|
||||||
|
Links: []string{}, // Plaintext has no links
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
if mediatype == "text/gemini" {
|
||||||
|
rendered, links := RenderGemini(utfText)
|
||||||
|
return &structs.Page{
|
||||||
|
Url: url,
|
||||||
|
Content: rendered,
|
||||||
|
Links: links,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.New("displayable mediatype is not handled in the code, implementation error")
|
||||||
|
}
|
@ -5,56 +5,15 @@
|
|||||||
package renderer
|
package renderer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"io/ioutil"
|
|
||||||
"mime"
|
|
||||||
urlPkg "net/url"
|
urlPkg "net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/makeworld-the-better-one/amfora/config"
|
"github.com/makeworld-the-better-one/amfora/config"
|
||||||
"github.com/makeworld-the-better-one/amfora/structs"
|
|
||||||
"github.com/makeworld-the-better-one/go-gemini"
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"gitlab.com/tslocum/cview"
|
"gitlab.com/tslocum/cview"
|
||||||
"golang.org/x/text/encoding/ianaindex"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Charsets that are compatible with UTF-8 and don't need to be decoded.
|
|
||||||
func isUTF8(charset string) bool {
|
|
||||||
utfCharsets := []string{"", "utf-8", "us-ascii"}
|
|
||||||
for i := range utfCharsets {
|
|
||||||
if strings.ToLower(charset) == utfCharsets[i] {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// CanDisplay returns true if the response is supported by Amfora
|
|
||||||
// for displaying on the screen.
|
|
||||||
// It also doubles as a function to detect whether something can be stored in a Page struct.
|
|
||||||
func CanDisplay(res *gemini.Response) bool {
|
|
||||||
if gemini.SimplifyStatus(res.Status) != 20 {
|
|
||||||
// No content
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
mediatype, params, err := mime.ParseMediaType(res.Meta)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if mediatype != "text/gemini" && mediatype != "text/plain" {
|
|
||||||
// Amfora doesn't support other filetypes
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if isUTF8(params["charset"]) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
enc, err := ianaindex.MIME.Encoding(params["charset"]) // Lowercasing is done inside
|
|
||||||
// Encoding sometimes returns nil, see #3 on this repo and golang/go#19421
|
|
||||||
return err == nil && enc != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// convertRegularGemini converts non-preformatted blocks of text/gemini
|
// convertRegularGemini converts non-preformatted blocks of text/gemini
|
||||||
// into a cview-compatible format.
|
// into a cview-compatible format.
|
||||||
// It also returns a slice of link URLs.
|
// It also returns a slice of link URLs.
|
||||||
@ -214,51 +173,3 @@ func RenderGemini(s string) (string, []string) {
|
|||||||
|
|
||||||
return rendered, links
|
return rendered, links
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakePage(url string, res *gemini.Response) (*structs.Page, error) {
|
|
||||||
if !CanDisplay(res) {
|
|
||||||
return nil, errors.New("not valid content for a Page")
|
|
||||||
}
|
|
||||||
|
|
||||||
rawText, err := ioutil.ReadAll(res.Body) // TODO: Don't use all memory on large pages
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
res.Body.Close()
|
|
||||||
|
|
||||||
mediatype, params, _ := mime.ParseMediaType(res.Meta)
|
|
||||||
|
|
||||||
// Convert content first
|
|
||||||
var utfText string
|
|
||||||
if isUTF8(params["charset"]) {
|
|
||||||
utfText = string(rawText)
|
|
||||||
} else {
|
|
||||||
encoding, err := ianaindex.MIME.Encoding(params["charset"])
|
|
||||||
if encoding == nil || err != nil {
|
|
||||||
// Some encoding doesn't exist and wasn't caught in CanDisplay()
|
|
||||||
return nil, errors.New("unsupported encoding")
|
|
||||||
}
|
|
||||||
utfText, err = encoding.NewDecoder().String(string(rawText))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if mediatype == "text/plain" {
|
|
||||||
return &structs.Page{
|
|
||||||
Url: url,
|
|
||||||
Content: utfText,
|
|
||||||
Links: []string{}, // Plaintext has no links
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
if mediatype == "text/gemini" {
|
|
||||||
rendered, links := RenderGemini(utfText)
|
|
||||||
return &structs.Page{
|
|
||||||
Url: url,
|
|
||||||
Content: rendered,
|
|
||||||
Links: links,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, errors.New("displayable mediatype is not handled in the code, implementation error")
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user