Emoji favicon support - fixes #62

This commit is contained in:
makeworld 2020-08-05 13:31:59 -04:00
parent edd128e7c5
commit 0bc5939600
12 changed files with 221 additions and 38 deletions

View File

@ -7,11 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
### Added ### Added
- Emoji favicons can now be seen if `emoji_favicons` is enabled in the config (#62)
### Changed ### Changed
### Fixed ### Fixed
- Two digit (and higher) link texts are now in line with one digit ones (#60) - Two digit (and higher) link texts are now in line with one digit ones (#60)
- Race condition when reloading pages, could have caused the cache to still be used
## [1.4.0] - 2020-07-28 ## [1.4.0] - 2020-07-28

View File

@ -97,7 +97,7 @@ Features in *italics* are in the master branch, but not in the latest release.
- [x] Theming - [x] Theming
- [ ] Subscribe to RSS and Atom feeds and display them - [ ] Subscribe to RSS and Atom feeds and display them
- Subscribing to page changes, similar to how Spacewalk works, will also be supported - Subscribing to page changes, similar to how Spacewalk works, will also be supported
- [ ] Emoji favicons - [x] *Emoji favicons*
- See `gemini://mozz.us/files/rfc_gemini_favicon.gmi` for details - See `gemini://mozz.us/files/rfc_gemini_favicon.gmi` for details
- [ ] Stream support - [ ] Stream support
- [ ] Full client certificate UX within the client - [ ] Full client certificate UX within the client

58
cache/favicons.go vendored Normal file
View File

@ -0,0 +1,58 @@
package cache
import (
"fmt"
"sync"
)
// Functions for caching emoji favicons.
// See gemini://mozz.us/files/rfc_gemini_favicon.gmi for details.
var favicons = make(map[string]string) // domain to emoji
var favMu = sync.RWMutex{}
var KnownNoFavicon = "no"
// AddFavicon will add an emoji to the cache under that host.
// It does not verify that the string passed is actually an emoji.
// You can pass KnownNoFavicon as the emoji when a host doesn't have a valid favicon.
func AddFavicon(host, emoji string) {
favMu.Lock()
favicons[host] = emoji
favMu.Unlock()
}
// ClearFavicons removes all favicons from the cache
func ClearFavicons() {
favMu.Lock()
favicons = make(map[string]string)
favMu.Unlock()
}
// GetFavicon returns the favicon string for the host.
// It returns an empty string if there is no favicon cached.
// It might also return KnownNoFavicon to indicate that that host does not have
// a favicon at all.
func GetFavicon(host string) string {
favMu.RLock()
defer favMu.RUnlock()
return favicons[host]
}
func NumFavicons() int {
favMu.RLock()
defer favMu.RUnlock()
return len(favicons)
}
func RemoveFavicon(host string) {
favMu.Lock()
delete(favicons, host)
favMu.Unlock()
}
func AllFavicons() string {
favMu.RLock()
defer favMu.RUnlock()
return fmt.Sprintf("%v", favicons)
}

2
cache/redir.go vendored
View File

@ -31,8 +31,8 @@ func AddRedir(og, redir string) {
// ClearRedirs removes all redirects from the cache. // ClearRedirs removes all redirects from the cache.
func ClearRedirs() { func ClearRedirs() {
redirMu.Lock() redirMu.Lock()
defer redirMu.Unlock()
redirUrls = make(map[string]string) redirUrls = make(map[string]string)
redirMu.Unlock()
} }
// Redirect takes the provided URL and returns a redirected version, if a redirect // Redirect takes the provided URL and returns a redirected version, if a redirect

View File

@ -153,6 +153,7 @@ func Init() error {
viper.SetDefault("a-general.downloads", "") viper.SetDefault("a-general.downloads", "")
viper.SetDefault("a-general.page_max_size", 2097152) viper.SetDefault("a-general.page_max_size", 2097152)
viper.SetDefault("a-general.page_max_time", 10) viper.SetDefault("a-general.page_max_time", 10)
viper.SetDefault("a-general.emoji_favicons", false)
viper.SetDefault("cache.max_size", 0) viper.SetDefault("cache.max_size", 0)
viper.SetDefault("cache.max_pages", 20) viper.SetDefault("cache.max_pages", 20)

View File

@ -12,6 +12,7 @@ var defaultConf = []byte(`# This is the default config file.
# example.com:123 # example.com:123
[a-general] [a-general]
# Press Ctrl-H to access it
home = "gemini://gemini.circumlunar.space" home = "gemini://gemini.circumlunar.space"
# What command to run to open a HTTP URL. Set to "default" to try to guess the browser, # What command to run to open a HTTP URL. Set to "default" to try to guess the browser,
@ -19,21 +20,36 @@ home = "gemini://gemini.circumlunar.space"
# If a command is set, than the URL will be added (in quotes) to the end of the command. # If a command is set, than the URL will be added (in quotes) to the end of the command.
# A space will be prepended if necessary. # A space will be prepended if necessary.
http = "default" http = "default"
search = "gemini://gus.guru/search" # Any URL that will accept a query string can be put here
color = true # Whether colors will be used in the terminal # Any URL that will accept a query string can be put here
bullets = true # Whether to replace list asterisks with unicode bullets search = "gemini://gus.guru/search"
# Whether colors will be used in the terminal
color = true
# Whether to replace list asterisks with unicode bullets
bullets = true
# A number from 0 to 1, indicating what percentage of the terminal width the left margin should take up. # A number from 0 to 1, indicating what percentage of the terminal width the left margin should take up.
left_margin = 0.15 left_margin = 0.15
max_width = 100 # The max number of columns to wrap a page's text to. Preformatted blocks are not wrapped.
# The max number of columns to wrap a page's text to. Preformatted blocks are not wrapped.
max_width = 100
# 'downloads' is the path to a downloads folder. # 'downloads' is the path to a downloads folder.
# An empty value means the code will find the default downloads folder for your system. # An empty value means the code will find the default downloads folder for your system.
# If the path does not exist it will be created. # If the path does not exist it will be created.
downloads = "" downloads = ""
# Max size for displayable content in bytes - after that size a download window pops up # Max size for displayable content in bytes - after that size a download window pops up
page_max_size = 2097152 # 2 MiB page_max_size = 2097152 # 2 MiB
# Max time it takes to load a page in seconds - after that a download window pops up # Max time it takes to load a page in seconds - after that a download window pops up
page_max_time = 10 page_max_time = 10
# Whether to replace tab numbers with emoji favicons, which are cached.
emoji_favicons = false
# Options for page cache - which is only for text/gemini pages # Options for page cache - which is only for text/gemini pages
# Increase the cache size to speed up browsing at the expense of memory # Increase the cache size to speed up browsing at the expense of memory
[cache] [cache]
@ -41,15 +57,16 @@ page_max_time = 10
max_size = 0 # Size in bytes max_size = 0 # Size in bytes
max_pages = 30 # The maximum number of pages the cache will store max_pages = 30 # The maximum number of pages the cache will store
[theme] [theme]
# This section is for changing the COLORS used in Amfora. # This section is for changing the COLORS used in Amfora.
# These colors only apply if color is enabled above. # These colors only apply if 'color' is enabled above.
# Colors can be set using a W3C color name, or a hex value such as #ffffff". # Colors can be set using a W3C color name, or a hex value such as "#ffffff".
# Note that not all colors will work on terminals that do not have truecolor support. # Note that not all colors will work on terminals that do not have truecolor support.
# If you want to stick to the standard 16 or 256 colors, you can get # If you want to stick to the standard 16 or 256 colors, you can get
# a list of those here: https://jonasjacek.github.io/colors/ # a list of those here: https://jonasjacek.github.io/colors/
# Do NOT use the names from that site, just the hex codes. # DO NOT use the names from that site, just the hex codes.
# Definitions: # Definitions:
# bg = background # bg = background

View File

@ -486,24 +486,7 @@ func CloseTab() {
} }
tabPages.SwitchToPage(strconv.Itoa(curTab)) // Go to previous page tabPages.SwitchToPage(strconv.Itoa(curTab)) // Go to previous page
// Rewrite the tab display rewriteTabRow()
tabRow.Clear()
if viper.GetBool("a-general.color") {
for i := 0; i < NumTabs(); i++ {
fmt.Fprintf(tabRow, `["%d"][%s] %d [%s][""]|`,
i,
config.GetColorString("tab_num"),
i+1,
config.GetColorString("tab_divider"),
)
}
} else {
for i := 0; i < NumTabs(); i++ {
fmt.Fprintf(tabRow, `["%d"] %d [""]|`, i, i+1)
}
}
tabRow.Highlight(strconv.Itoa(curTab)).ScrollToHighlight()
// Restore previous tab's state // Restore previous tab's state
tabs[curTab].applyAll() tabs[curTab].applyAll()
@ -550,8 +533,10 @@ func Reload() {
return return
} }
go cache.RemovePage(tabs[curTab].page.Url) parsed, _ := url.Parse(tabs[curTab].page.Url)
go func(t *tab) { go func(t *tab) {
cache.RemovePage(tabs[curTab].page.Url)
cache.RemoveFavicon(parsed.Host)
handleURL(t, t.page.Url) // goURL is not used bc history shouldn't be added to handleURL(t, t.page.Url) // goURL is not used bc history shouldn't be added to
if t == tabs[curTab] { if t == tabs[curTab] {
// Display the bottomBar state that handleURL set // Display the bottomBar state that handleURL set

View File

@ -1,16 +1,22 @@
package display package display
import ( import (
"bytes"
"fmt"
"io"
"net/url" "net/url"
"os/exec" "os/exec"
"strconv"
"strings" "strings"
"github.com/makeworld-the-better-one/amfora/cache" "github.com/makeworld-the-better-one/amfora/cache"
"github.com/makeworld-the-better-one/amfora/client" "github.com/makeworld-the-better-one/amfora/client"
"github.com/makeworld-the-better-one/amfora/config"
"github.com/makeworld-the-better-one/amfora/renderer" "github.com/makeworld-the-better-one/amfora/renderer"
"github.com/makeworld-the-better-one/amfora/structs" "github.com/makeworld-the-better-one/amfora/structs"
"github.com/makeworld-the-better-one/amfora/webbrowser" "github.com/makeworld-the-better-one/amfora/webbrowser"
"github.com/makeworld-the-better-one/go-gemini" "github.com/makeworld-the-better-one/go-gemini"
"github.com/makeworld-the-better-one/go-isemoji"
"github.com/spf13/viper" "github.com/spf13/viper"
"gitlab.com/tslocum/cview" "gitlab.com/tslocum/cview"
) )
@ -106,8 +112,16 @@ func setPage(t *tab, p *structs.Page) {
// Make sure the page content is fitted to the terminal every time it's displayed // Make sure the page content is fitted to the terminal every time it's displayed
reformatPage(p) reformatPage(p)
// Change page on screen oldFav := t.page.Favicon
t.page = p t.page = p
go func() {
parsed, _ := url.Parse(p.Url)
handleFavicon(t, parsed.Host, oldFav)
}()
// Change page on screen
t.view.SetText(p.Content) t.view.SetText(p.Content)
t.view.Highlight("") // Turn off highlights, other funcs may restore if necessary t.view.Highlight("") // Turn off highlights, other funcs may restore if necessary
t.view.ScrollToBeginning() t.view.ScrollToBeginning()
@ -144,6 +158,81 @@ func handleHTTP(u string, showInfo bool) {
App.Draw() App.Draw()
} }
// handleFavicon handles getting and displaying a favicon.
// `old` is the previous favicon for the tab.
func handleFavicon(t *tab, host, old string) {
defer func() {
// Update display if needed
if t.page.Favicon != old && isValidTab(t) {
rewriteTabRow()
}
}()
if !viper.GetBool("a-general.emoji_favicons") {
// Not enabled
return
}
if t.page.Favicon != "" {
return
}
if host == "" {
return
}
fav := cache.GetFavicon(host)
if fav == cache.KnownNoFavicon {
// It's been cached that this host doesn't have a favicon
return
}
if fav != "" {
t.page.Favicon = fav
rewriteTabRow()
return
}
// No favicon cached
res, err := client.Fetch("gemini://" + host + "/favicon.txt")
if err != nil {
if res != nil {
res.Body.Close()
}
cache.AddFavicon(host, cache.KnownNoFavicon)
return
}
defer res.Body.Close()
if res.Status != 20 {
cache.AddFavicon(host, cache.KnownNoFavicon)
return
}
if !strings.HasPrefix(res.Meta, "text/plain") {
cache.AddFavicon(host, cache.KnownNoFavicon)
return
}
// It's a regular plain response
buf := new(bytes.Buffer)
_, err = io.CopyN(buf, res.Body, 29+2+1) // 29 is the max emoji length, +2 for CRLF, +1 so that the right size will EOF
if err == nil {
// Content was too large
cache.AddFavicon(host, cache.KnownNoFavicon)
return
} else if err != io.EOF {
// Some network reading error
// No favicon is NOT known, could be a temporary error
return
}
// EOF, which is what we want.
emoji := strings.TrimRight(buf.String(), "\r\n")
if !isemoji.IsEmoji(emoji) {
cache.AddFavicon(host, cache.KnownNoFavicon)
return
}
// Valid favicon found
t.page.Favicon = emoji
cache.AddFavicon(host, emoji)
}
// goURL is like handleURL, but takes care of history and the bottomBar. // goURL is like handleURL, but takes care of history and the bottomBar.
// It should be preferred over handleURL in most cases. // It should be preferred over handleURL in most cases.
// It has no return values to be processed. // It has no return values to be processed.
@ -336,3 +425,32 @@ func handleURL(t *tab, u string) (string, bool) {
go dlChoice("That file could not be displayed. What would you like to do?", u, res) go dlChoice("That file could not be displayed. What would you like to do?", u, res)
return ret("", false) return ret("", false)
} }
// rewriteTabRow clears the tabRow and writes all the tabs number/favicons into it.
func rewriteTabRow() {
tabRow.Clear()
if viper.GetBool("a-general.color") {
for i := 0; i < NumTabs(); i++ {
char := strconv.Itoa(i + 1)
if tabs[i].page.Favicon != "" {
char = tabs[i].page.Favicon
}
fmt.Fprintf(tabRow, `["%d"][%s] %s [%s][""]|`,
i,
config.GetColorString("tab_num"),
char,
config.GetColorString("tab_divider"),
)
}
} else {
for i := 0; i < NumTabs(); i++ {
char := strconv.Itoa(i + 1)
if tabs[i].page.Favicon != "" {
char = tabs[i].page.Favicon
}
fmt.Fprintf(tabRow, `["%d"] %s [""]|`, i, char)
}
}
tabRow.Highlight(strconv.Itoa(curTab)).ScrollToHighlight()
App.Draw()
}

4
go.mod
View File

@ -7,6 +7,7 @@ require (
github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/gdamore/tcell v1.3.1-0.20200608133353-cb1e5d6fa606 github.com/gdamore/tcell v1.3.1-0.20200608133353-cb1e5d6fa606
github.com/makeworld-the-better-one/go-gemini v0.7.0 github.com/makeworld-the-better-one/go-gemini v0.7.0
github.com/makeworld-the-better-one/go-isemoji v1.0.0
github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f
github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/mapstructure v1.3.1 // indirect github.com/mitchellh/mapstructure v1.3.1 // indirect
@ -16,10 +17,9 @@ require (
github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.7.0 github.com/spf13/viper v1.7.0
github.com/stretchr/testify v1.6.0 github.com/stretchr/testify v1.6.1
gitlab.com/tslocum/cview v1.4.8-0.20200713214710-cc7796c4ca44 gitlab.com/tslocum/cview v1.4.8-0.20200713214710-cc7796c4ca44
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1 // indirect golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1 // indirect
golang.org/x/text v0.3.3 golang.org/x/text v0.3.3
gopkg.in/ini.v1 v1.57.0 // indirect gopkg.in/ini.v1 v1.57.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20200603094226-e3079894b1e8 // indirect
) )

10
go.sum
View File

@ -126,6 +126,8 @@ github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzR
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/makeworld-the-better-one/go-gemini v0.7.0 h1:TCerE47eYHLXj6RQDjfd5HdGVbcVqpBC6OoPBlyY7q4= github.com/makeworld-the-better-one/go-gemini v0.7.0 h1:TCerE47eYHLXj6RQDjfd5HdGVbcVqpBC6OoPBlyY7q4=
github.com/makeworld-the-better-one/go-gemini v0.7.0/go.mod h1:P7/FbZ+IEIbA/d+A0Y3w2GNgD8SA2AcNv7aDGJbaWG4= github.com/makeworld-the-better-one/go-gemini v0.7.0/go.mod h1:P7/FbZ+IEIbA/d+A0Y3w2GNgD8SA2AcNv7aDGJbaWG4=
github.com/makeworld-the-better-one/go-isemoji v1.0.0 h1:W3O4+qwtXeT8PUDzcQ1UjxiupQWgc/oJHpqwrllx3xM=
github.com/makeworld-the-better-one/go-isemoji v1.0.0/go.mod h1:FBjkPl9rr0G4vlZCc+Mr+QcnOfGCTbGWYW8/1sp06I0=
github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f h1:YEUlTs5gb35UlBLTgqrub9axWTYB3d7/8TxrkJDZpRI= github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f h1:YEUlTs5gb35UlBLTgqrub9axWTYB3d7/8TxrkJDZpRI=
github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f/go.mod h1:X6sxWNi9PBgQybpR4fpXPVD5fm7svLqZTQ5DJuERIoM= github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f/go.mod h1:X6sxWNi9PBgQybpR4fpXPVD5fm7svLqZTQ5DJuERIoM=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
@ -203,8 +205,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.0 h1:jlIyCplCJFULU/01vCkhKuTyc3OorI3bJFuw6obfgho= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@ -345,8 +347,8 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200603094226-e3079894b1e8 h1:jL/vaozO53FMfZLySWM+4nulF3gQEC6q5jH90LPomDo= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
gopkg.in/yaml.v3 v3.0.0-20200603094226-e3079894b1e8/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@ -67,7 +67,6 @@ func MakePage(url string, res *gemini.Response, width, leftMargin int) (*structs
_, err := io.CopyN(buf, res.Body, viper.GetInt64("a-general.page_max_size")+1) _, err := io.CopyN(buf, res.Body, viper.GetInt64("a-general.page_max_size")+1)
res.Body.Close() res.Body.Close()
rawText := buf.Bytes()
if err == nil { if err == nil {
// Content was larger than max size // Content was larger than max size
return nil, ErrTooLarge return nil, ErrTooLarge
@ -86,14 +85,14 @@ func MakePage(url string, res *gemini.Response, width, leftMargin int) (*structs
// Convert content first // Convert content first
var utfText string var utfText string
if isUTF8(params["charset"]) { if isUTF8(params["charset"]) {
utfText = string(rawText) utfText = buf.String()
} else { } else {
encoding, err := ianaindex.MIME.Encoding(params["charset"]) encoding, err := ianaindex.MIME.Encoding(params["charset"])
if encoding == nil || err != nil { if encoding == nil || err != nil {
// Some encoding doesn't exist and wasn't caught in CanDisplay() // Some encoding doesn't exist and wasn't caught in CanDisplay()
return nil, errors.New("unsupported encoding") return nil, errors.New("unsupported encoding")
} }
utfText, err = encoding.NewDecoder().String(string(rawText)) utfText, err = encoding.NewDecoder().String(buf.String())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -29,6 +29,7 @@ type Page struct {
Selected string // The current text or link selected Selected string // The current text or link selected
SelectedID string // The cview region ID for the selected text/link SelectedID string // The cview region ID for the selected text/link
Mode PageMode Mode PageMode
Favicon string
} }
// Size returns an approx. size of a Page in bytes. // Size returns an approx. size of a Page in bytes.