mirror of
https://github.com/makeworld-the-better-one/amfora.git
synced 2024-09-11 14:55:51 +03:00
Co-authored-by: Mattias Jadelius <mattias.jadelius>
This commit is contained in:
parent
a04c281ae0
commit
51fd32e1ea
116
display/file.go
Normal file
116
display/file.go
Normal file
@ -0,0 +1,116 @@
|
||||
package display
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"mime"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/makeworld-the-better-one/amfora/renderer"
|
||||
"github.com/makeworld-the-better-one/amfora/structs"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// handleFile handles urls using file:// protocol
|
||||
func handleFile(u string) (*structs.Page, bool) {
|
||||
page := &structs.Page{}
|
||||
|
||||
uri, err := url.ParseRequestURI(u)
|
||||
if err != nil {
|
||||
Error("File Error", "Cannot parse URI: "+err.Error())
|
||||
return page, false
|
||||
}
|
||||
fi, err := os.Stat(uri.Path)
|
||||
if err != nil {
|
||||
Error("File Error", "Cannot open local file: "+err.Error())
|
||||
return page, false
|
||||
}
|
||||
|
||||
switch mode := fi.Mode(); {
|
||||
case mode.IsDir():
|
||||
return createDirectoryListing(u)
|
||||
case mode.IsRegular():
|
||||
if fi.Size() > viper.GetInt64("a-general.page_max_size") {
|
||||
Error("File Error", "Cannot open local file, exceeds page max size")
|
||||
return page, false
|
||||
}
|
||||
|
||||
mimetype := mime.TypeByExtension(filepath.Ext(uri.Path))
|
||||
if strings.HasSuffix(u, ".gmi") || strings.HasSuffix(u, ".gemini") {
|
||||
mimetype = "text/gemini"
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(mimetype, "text/") {
|
||||
Error("File Error", "Cannot open file, not recognized as text.")
|
||||
return page, false
|
||||
}
|
||||
|
||||
content, err := ioutil.ReadFile(uri.Path)
|
||||
if err != nil {
|
||||
Error("File Error", "Cannot open local file: "+err.Error())
|
||||
return page, false
|
||||
}
|
||||
|
||||
if mimetype == "text/gemini" {
|
||||
rendered, links := renderer.RenderGemini(string(content), textWidth(), leftMargin(), false)
|
||||
page = &structs.Page{
|
||||
Mediatype: structs.TextGemini,
|
||||
URL: u,
|
||||
Raw: string(content),
|
||||
Content: rendered,
|
||||
Links: links,
|
||||
Width: termW,
|
||||
}
|
||||
} else {
|
||||
page = &structs.Page{
|
||||
Mediatype: structs.TextPlain,
|
||||
URL: u,
|
||||
Raw: string(content),
|
||||
Content: renderer.RenderPlainText(string(content), leftMargin()),
|
||||
Links: []string{},
|
||||
Width: termW,
|
||||
}
|
||||
}
|
||||
}
|
||||
return page, true
|
||||
}
|
||||
|
||||
// createDirectoryListing creates a text/gemini page for a directory
|
||||
// that lists all the files as links.
|
||||
func createDirectoryListing(u string) (*structs.Page, bool) {
|
||||
page := &structs.Page{}
|
||||
|
||||
uri, err := url.ParseRequestURI(u)
|
||||
if err != nil {
|
||||
Error("Directory Error", "Cannot parse URI: "+err.Error())
|
||||
}
|
||||
|
||||
files, err := ioutil.ReadDir(uri.Path)
|
||||
if err != nil {
|
||||
Error("Directory error", "Cannot open local directory: "+err.Error())
|
||||
return page, false
|
||||
}
|
||||
content := "Index of " + uri.Path + "\n"
|
||||
content += "=> ../ ../\n"
|
||||
for _, f := range files {
|
||||
separator := ""
|
||||
if f.IsDir() {
|
||||
separator = "/"
|
||||
}
|
||||
content += fmt.Sprintf("=> %s%s %s%s\n", f.Name(), separator, f.Name(), separator)
|
||||
}
|
||||
|
||||
rendered, links := renderer.RenderGemini(content, textWidth(), leftMargin(), false)
|
||||
page = &structs.Page{
|
||||
Mediatype: structs.TextGemini,
|
||||
URL: u,
|
||||
Raw: content,
|
||||
Content: rendered,
|
||||
Links: links,
|
||||
Width: termW,
|
||||
}
|
||||
return page, true
|
||||
}
|
@ -78,7 +78,9 @@ func reformatPage(p *structs.Page) {
|
||||
case structs.TextGemini:
|
||||
// Links are not recorded because they won't change
|
||||
proxied := true
|
||||
if strings.HasPrefix(p.URL, "gemini") || strings.HasPrefix(p.URL, "about") {
|
||||
if strings.HasPrefix(p.URL, "gemini") ||
|
||||
strings.HasPrefix(p.URL, "about") ||
|
||||
strings.HasPrefix(p.URL, "file") {
|
||||
proxied = false
|
||||
}
|
||||
rendered, _ = renderer.RenderGemini(p.Raw, textWidth(), leftMargin(), proxied)
|
||||
@ -370,7 +372,16 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) {
|
||||
usingProxy = true
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(u, "http") && !strings.HasPrefix(u, "gemini") {
|
||||
if strings.HasPrefix(u, "file") {
|
||||
page, ok := handleFile(u)
|
||||
if !ok {
|
||||
return ret("", false)
|
||||
}
|
||||
setPage(t, page)
|
||||
return ret(u, true)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(u, "http") && !strings.HasPrefix(u, "gemini") && !strings.HasPrefix(u, "file") {
|
||||
// Not a Gemini URL
|
||||
if proxy == "" || proxy == "off" {
|
||||
// No proxy available
|
||||
|
Loading…
Reference in New Issue
Block a user