Updated profile as suggested by golint

master
Michael Dvorkin 11 years ago
parent ffc491b20f
commit 2e05c91d29
  1. 135
      profile.go
  2. 3
      yahoo_quotes.go

@ -1,117 +1,130 @@
// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved. // Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style license that can
// license that can be found in the LICENSE file. // be found in the LICENSE file.
package mop package mop
import ( import (
`sort`
`encoding/json` `encoding/json`
`io/ioutil` `io/ioutil`
`os/user` `os/user`
`strings` `sort`
) )
// File name in user's home directory where we store the settings.
const moprc = `/.moprc` const moprc = `/.moprc`
// Profile manages Mop program settings as defined by user (ex. list of
// stock tickers). The settings are serialized using JSON and saved in
// the ~/.moprc file.
type Profile struct { type Profile struct {
MarketRefresh int Tickers []string // List of stock tickers to display.
QuotesRefresh int MarketRefresh int // Time interval to refresh market data.
Grouped bool QuotesRefresh int // Time interval to refresh stock quotes.
Tickers []string SortColumn int // Column number by which we sort stock quotes.
SortColumn int Ascending bool // True when sort order is ascending.
Ascending bool Grouped bool // True when stocks are grouped by advancing/declining.
selectedColumn int selectedColumn int // Stores selected column number when the column editor is active.
} }
//----------------------------------------------------------------------------- // Initialize attempts to load the settings from ~/.moprc file. If the
func (self *Profile) Initialize() *Profile { // file is not there it gets created with the default values.
data, err := ioutil.ReadFile(self.default_file_name()) func (profile *Profile) Initialize() *Profile {
if err != nil { data, err := ioutil.ReadFile(profile.defaultFileName())
// Set default values. if err != nil { // Set default values:
self.MarketRefresh = 12 profile.MarketRefresh = 12 // Market data gets fetched every 12s (5 times per minute).
self.QuotesRefresh = 5 profile.QuotesRefresh = 5 // Stock quotes get updated every 5s (12 times per minute).
self.Grouped = false profile.Grouped = false // Stock quotes are *not* grouped by advancing/declining.
self.Tickers = []string{`AAPL`, `C`, `GOOG`, `IBM`, `KO`, `ORCL`, `V`} profile.Tickers = []string{ `AAPL`, `C`, `GOOG`, `IBM`, `KO`, `ORCL`, `V` }
self.SortColumn = 0 profile.SortColumn = 0 // Stock quotes are sorted by ticker name.
self.Ascending = true profile.Ascending = true // A to Z.
self.Save() profile.Save()
} else { } else {
json.Unmarshal(data, self) json.Unmarshal(data, profile)
} }
self.selectedColumn = -1 profile.selectedColumn = -1
return self return profile
} }
//----------------------------------------------------------------------------- // Save serializes settings using JSON and saves them in ~/.moprc file.
func (self *Profile) Save() error { func (profile *Profile) Save() error {
if data, err := json.Marshal(self); err != nil { data, err := json.Marshal(profile)
if err != nil {
return err return err
} else {
return ioutil.WriteFile(self.default_file_name(), data, 0644)
}
} }
//----------------------------------------------------------------------------- return ioutil.WriteFile(profile.defaultFileName(), data, 0644)
func (self *Profile) ListOfTickers() string {
return strings.Join(self.Tickers, `+`)
} }
//----------------------------------------------------------------------------- // AddTickers updates the list of existing tikers to add the new ones making
func (self *Profile) AddTickers(tickers []string) (added int, err error) { // sure there are no duplicates.
added = 0 func (profile *Profile) AddTickers(tickers []string) (added int, err error) {
added, err = 0, nil
existing := make(map[string]bool) existing := make(map[string]bool)
for _, ticker := range self.Tickers { // Build a hash of existing tickers so we could look it up quickly.
for _, ticker := range profile.Tickers {
existing[ticker] = true existing[ticker] = true
} }
// Iterate over the list of new tickers excluding the ones that
// already exist.
for _, ticker := range tickers { for _, ticker := range tickers {
if _, found := existing[ticker]; !found { if _, found := existing[ticker]; !found {
self.Tickers = append(self.Tickers, ticker) profile.Tickers = append(profile.Tickers, ticker)
added++ added++
} }
} }
sort.Strings(self.Tickers)
err = self.Save() if added > 0 {
sort.Strings(profile.Tickers)
err = profile.Save()
}
return return
} }
//----------------------------------------------------------------------------- // RemoveTickers removes requested stock tickers from the list we track.
func (self *Profile) RemoveTickers(tickers []string) (removed int, err error) { func (profile *Profile) RemoveTickers(tickers []string) (removed int, err error) {
removed = 0 removed, err = 0, nil
for _, ticker := range tickers { for _, ticker := range tickers {
for i, existing := range self.Tickers { for i, existing := range profile.Tickers {
if ticker == existing { // Requested ticker is there: remove i-th slice item. if ticker == existing {
self.Tickers = append(self.Tickers[:i], self.Tickers[i+1:]...) // Requested ticker is there: remove i-th slice item.
profile.Tickers = append(profile.Tickers[:i], profile.Tickers[i+1:]...)
removed++ removed++
} }
} }
} }
err = self.Save()
if removed > 0 {
err = profile.Save()
}
return return
} }
//----------------------------------------------------------------------------- // Reorder gets called by the column editor to either reverse sorting order
func (self *Profile) Reorder() error { // for the current column, or to pick another sort column.
if self.selectedColumn == self.SortColumn { func (profile *Profile) Reorder() error {
self.Ascending = !self.Ascending if profile.selectedColumn == profile.SortColumn {
profile.Ascending = !profile.Ascending // Reverse sort order.
} else { } else {
self.SortColumn = self.selectedColumn profile.SortColumn = profile.selectedColumn // Pick new sort column.
} }
return self.Save() return profile.Save()
} }
//----------------------------------------------------------------------------- // Regroup flips the flag that controls whether the stock quotes are grouped
func (self *Profile) Regroup() error { // by advancing/declining issues.
self.Grouped = !self.Grouped func (profile *Profile) Regroup() error {
return self.Save() profile.Grouped = !profile.Grouped
return profile.Save()
} }
// private
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
func (self *Profile) default_file_name() string { func (profile *Profile) defaultFileName() string {
usr, err := user.Current() usr, err := user.Current()
if err != nil { if err != nil {
panic(err) panic(err)

@ -11,6 +11,7 @@ import (
`io/ioutil` `io/ioutil`
`net/http` `net/http`
`reflect` `reflect`
`strings`
) )
// See http://www.gummy-stuff.org/Yahoo-stocks.htm // See http://www.gummy-stuff.org/Yahoo-stocks.htm
@ -88,7 +89,7 @@ func (self *Quotes) Fetch() (this *Quotes) {
} }
}() }()
url := fmt.Sprintf(quotes_url, self.profile.ListOfTickers()) url := fmt.Sprintf(quotes_url, strings.Join(self.profile.Tickers, `+`))
response, err := http.Get(url) response, err := http.Get(url)
if err != nil { if err != nil {
panic(err) panic(err)

Loading…
Cancel
Save