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 := `%s
` out.WriteString("

Reading List

\n
\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)} }