169 lines
4.3 KiB
Go
169 lines
4.3 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/user"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
// XXX:
|
|
// This struct is temporarily not in use while an issue with marshalling
|
|
// []ToRead in the Settings struct gets worked out. In the meantime a
|
|
// []string is being used with the string in each containing a 'magic
|
|
// string' that gets split to produce the values.
|
|
type ToRead struct {
|
|
url string `json:"ToReadURL"`
|
|
title string `json:"ToReadTitle"`
|
|
}
|
|
|
|
type VisitedPage struct {
|
|
count int
|
|
u string
|
|
}
|
|
|
|
type Settings struct {
|
|
OpenWebLinks bool
|
|
OpenGopherLinks bool
|
|
OpenFileLinks bool
|
|
|
|
KeepHistory bool
|
|
History []string
|
|
|
|
UseCustomHome bool
|
|
CustomHomeHTML string
|
|
|
|
SearchURL string
|
|
BaseFontSize int
|
|
TimeOutSeconds int
|
|
ReadingList []string
|
|
}
|
|
|
|
var settingsPath = ""
|
|
|
|
func (s Settings) FontSize() int {
|
|
return s.BaseFontSize
|
|
}
|
|
|
|
func (s *Settings) IncreaseFontSize() int {
|
|
s.BaseFontSize += 1
|
|
return s.BaseFontSize
|
|
}
|
|
|
|
func (s *Settings) DecreaseFontSize() int {
|
|
s.BaseFontSize -= 1
|
|
return s.BaseFontSize
|
|
}
|
|
|
|
func (s *Settings) AddToHistory(u string) error {
|
|
if !s.KeepHistory {
|
|
s.History = make([]string, 0)
|
|
return fmt.Errorf("No history is available")
|
|
}
|
|
if len(s.History) == 0 {
|
|
s.History = make([]string, 0, 10)
|
|
s.History = append(s.History, u)
|
|
return nil
|
|
}
|
|
s.History = append([]string{u}, s.History...)
|
|
if len(s.History) > 100 {
|
|
s.History = s.History[:101]
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *Settings) AddToReadingList(title, u string) (string, error) {
|
|
// FIXME: The double-tab string is being used because json.Marshall
|
|
// would not marshall the slice of ToRead structs that was being
|
|
// used prior. It resulted in empty objects in the json. Using a
|
|
// string slice with a 'magic string' for splitting is a temporary
|
|
// solution until the json.Marshall issue can be solved
|
|
stringified := u + "\t\t" + title
|
|
s.ReadingList = append(s.ReadingList, stringified)
|
|
return s.ReadingListHTML()
|
|
}
|
|
|
|
func (s Settings) ReadingListHTML() (string, error) {
|
|
var out strings.Builder
|
|
linkFormat := `<a href="%s" id="rl-%d">%s</a> <button aria-label="Remove from reading list" class="reading-list-delete" data-index="%d">❌</button><br>`
|
|
out.WriteString("<h1 tabindex=\"-1\" id=\"rl-header\">Reading List</h1>\n<hr>\n")
|
|
for i, li := range s.ReadingList{
|
|
// FIXME: The double-tab string is being used because json.Marshall
|
|
// would not marshall the slice of ToRead structs that was being
|
|
// used prior. It resulted in empty objects in the json. Using a
|
|
// string slice with a 'magic string' for splitting is a temporary
|
|
// solution until the json.Marshall issue can be solved
|
|
sLn := strings.Split(li, "\t\t")
|
|
if len(sLn) < 2 {
|
|
continue
|
|
}
|
|
out.WriteString(fmt.Sprintf(linkFormat, sLn[0], i, sLn[1], i))
|
|
}
|
|
return out.String(), nil
|
|
}
|
|
|
|
func (s *Settings) RemoveFromReadingList(index int) (string, error) {
|
|
s.ReadingList = append(s.ReadingList[:index], s.ReadingList[index+1:]...)
|
|
return s.ReadingListHTML()
|
|
}
|
|
|
|
func (s Settings) GenerateConfig() {
|
|
err := os.MkdirAll(filepath.Dir(settingsPath), 0755)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "[SETTINGS] Unable to create directories for write operation")
|
|
return
|
|
}
|
|
|
|
s.Save()
|
|
}
|
|
|
|
func (s *Settings) Save() {
|
|
j, err := json.MarshalIndent(s, "", "\t")
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "[SETTINGS] Unable to marshall json for write opperation")
|
|
return
|
|
}
|
|
|
|
var perms os.FileMode = 0644
|
|
fstats, err := os.Stat(settingsPath)
|
|
if err == nil {
|
|
perms = fstats.Mode()
|
|
}
|
|
f, err := os.OpenFile(settingsPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, perms)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "[SETTINGS] Unable to open file for writing")
|
|
return
|
|
}
|
|
defer f.Close()
|
|
f.Write(j)
|
|
|
|
}
|
|
|
|
func (s *Settings) Load() {
|
|
configPath := os.Getenv("XDG_CONFIG_HOME")
|
|
if configPath == "" {
|
|
userinfo, _ := user.Current()
|
|
settingsPath = filepath.Join(userinfo.HomeDir, ".config", "goldberry", "goldberry.json")
|
|
} else {
|
|
settingsPath = filepath.Join(configPath, ".config", "goldberry.json")
|
|
}
|
|
|
|
_, err := os.Stat(settingsPath)
|
|
if err != nil {
|
|
s.GenerateConfig()
|
|
}
|
|
b, err := ioutil.ReadFile(settingsPath)
|
|
if err != nil {
|
|
return
|
|
}
|
|
json.Unmarshal(b, s)
|
|
}
|
|
|
|
func NewSettings() *Settings {
|
|
return &Settings{false, false, true, false, make([]string, 0, 10), false, "", "gemini://geminispace.info:1965/search?%s", 12, 5, make([]string, 0, 10)}
|
|
}
|
|
|