diff --git a/yahoo_market.go b/yahoo_market.go index a538f6e..47d76db 100644 --- a/yahoo_market.go +++ b/yahoo_market.go @@ -13,7 +13,7 @@ import ( `strings` ) -const marketURL = `http://finance.yahoo.com/marketupdate/overview` +const marketURL = `http://finance.yahoo.com/` // `http://finance.yahoo.com/marketupdate/overview` // Market stores current market information displayed in the top three lines of // the screen. The market data is fetched and parsed from the HTML page above. @@ -22,11 +22,12 @@ type Market struct { Dow map[string]string // Hash of Dow Jones indicators. Nasdaq map[string]string // Hash of NASDAQ indicators. Sp500 map[string]string // Hash of S&P 500 indicators. - Advances map[string]string // Number of advanced stocks on NYSE and NASDAQ. - Declines map[string]string // Ditto for declines. - Unchanged map[string]string // Ditto for unchanged. - Highs map[string]string // Number of new highs on NYSE and NASDAQ. - Lows map[string]string // Ditto for new lows. + London map[string]string + Frankfurt map[string]string + Paris map[string]string + Tokyo map[string]string + HongKong map[string]string + Shanghai map[string]string regex *regexp.Regexp // Regex to parse market data from HTML. errors string // Error(s), if any. } @@ -34,33 +35,33 @@ type Market struct { // Initialize creates empty hashes and builds regular expression used to parse // market data from HTML page. func (market *Market) Initialize() *Market { - market.IsClosed = false - market.Dow = make(map[string]string) - market.Nasdaq = make(map[string]string) - market.Sp500 = make(map[string]string) - market.Advances = make(map[string]string) - market.Declines = make(map[string]string) - market.Unchanged = make(map[string]string) - market.Highs = make(map[string]string) - market.Lows = make(map[string]string) - market.errors = `` + market.IsClosed = false + market.Dow = make(map[string]string) + market.Nasdaq = make(map[string]string) + market.Sp500 = make(map[string]string) + market.London = make(map[string]string) + market.Frankfurt = make(map[string]string) + market.Paris = make(map[string]string) + market.Tokyo = make(map[string]string) + market.HongKong = make(map[string]string) + market.Shanghai = make(map[string]string) + market.errors = `` const any = `\s*<.+?>` - const some = `<.+?` - const space = `\s*` - const color = `#([08c]{6});">\s*` + const color = `<.+?price-change-([a-z]+)'>[\+\-]?` const price = `([\d\.,]+)` const percent = `\(([\d\.,%]+)\)` rules := []string{ - `(Dow)`, any, price, some, color, price, some, percent, any, - `(Nasdaq)`, any, price, some, color, price, some, percent, any, - `(S&P 500)`, any, price, some, color, price, some, percent, any, - `(Advances)`, any, price, space, percent, any, price, space, percent, any, - `(Declines)`, any, price, space, percent, any, price, space, percent, any, - `(Unchanged)`, any, price, space, percent, any, price, space, percent, any, - `(New Hi's)`, any, price, any, price, any, - `(New Lo's)`, any, price, any, price, any, + `S&P 500`, any, price, color, price, any, percent, any, + `Dow`, any, price, color, price, any, percent, any, + `NASDAQ`, any, price, color, price, any, percent, any, + `FTSE`, any, price, color, price, any, percent, any, + `DAX`, any, price, color, price, any, percent, any, + `CAC 40`, any, price, color, price, any, percent, any, + `NIKKEI 225`, any, price, color, price, any, percent, any, + `Hang Seng`, any, price, color, price, any, percent, any, + `SSE Comp`, any, price, color, price, any, percent, any, } market.regex = regexp.MustCompile(strings.Join(rules, ``)) @@ -101,7 +102,7 @@ func (market *Market) Ok() (bool, string) { //----------------------------------------------------------------------------- func (market *Market) checkIfMarketIsOpen(body []byte) []byte { - start := bytes.Index(body, []byte(`id="yfs_market_time"`)) + start := bytes.Index(body, []byte(`id='yfs_market_time'`)) finish := start + bytes.Index(body[start:], []byte(``)) snippet := body[start:finish] market.IsClosed = bytes.Contains(snippet, []byte(`closed`)) || bytes.Contains(snippet, []byte(`open in`)) @@ -111,8 +112,8 @@ func (market *Market) checkIfMarketIsOpen(body []byte) []byte { //----------------------------------------------------------------------------- func (market *Market) trim(body []byte) []byte { - start := bytes.Index(body, []byte(`S&P 500<`)) + finish := bytes.LastIndex(body, []byte(`id="mediafinancesuperherogs"`)) snippet := bytes.Replace(body[start:finish], []byte{'\n'}, []byte{}, -1) snippet = bytes.Replace(snippet, []byte(`&`), []byte{'&'}, -1) @@ -122,77 +123,118 @@ func (market *Market) trim(body []byte) []byte { //----------------------------------------------------------------------------- func (market *Market) extract(snippet []byte) *Market { matches := market.regex.FindAllStringSubmatch(string(snippet), -1) + //fmt.Printf("\n\n\n%q\n\n\n", matches[0]) if len(matches) < 1 || len(matches[0]) < 37 { panic(`Unable to parse ` + marketURL) } - market.Dow[`name`] = matches[0][1] - market.Dow[`latest`] = matches[0][2] - market.Dow[`change`] = matches[0][4] - switch matches[0][3] { - case `008800`: - market.Dow[`change`] = `+` + matches[0][4] - market.Dow[`percent`] = `+` + matches[0][5] - case `cc0000`: - market.Dow[`change`] = `-` + matches[0][4] - market.Dow[`percent`] = `-` + matches[0][5] - default: - market.Dow[`change`] = matches[0][4] - market.Dow[`percent`] = matches[0][5] + market.Dow[`name`] = `Dow` + market.Dow[`latest`] = matches[0][1] + market.Dow[`change`] = matches[0][3] + market.Dow[`percent`] = matches[0][4] + if matches[0][2] == `green` { + market.Dow[`change`] = `+` + market.Dow[`change`] + market.Dow[`percent`] = `+` + market.Dow[`percent`] + } else if matches[0][2] == `?` { + market.Dow[`change`] = `-` + market.Dow[`change`] + market.Dow[`percent`] = `-` + market.Dow[`percent`] } - market.Nasdaq[`name`] = matches[0][6] - market.Nasdaq[`latest`] = matches[0][7] - switch matches[0][8] { - case `008800`: - market.Nasdaq[`change`] = `+` + matches[0][9] - market.Nasdaq[`percent`] = `+` + matches[0][10] - case `cc0000`: - market.Nasdaq[`change`] = `-` + matches[0][9] - market.Nasdaq[`percent`] = `-` + matches[0][10] - default: - market.Nasdaq[`change`] = matches[0][9] - market.Nasdaq[`percent`] = matches[0][10] + market.Nasdaq[`name`] = `NASDAQ` + market.Nasdaq[`latest`] = matches[0][5] + market.Nasdaq[`change`] = matches[0][7] + market.Nasdaq[`percent`] = matches[0][8] + if matches[0][6] == `green` { + market.Nasdaq[`change`] = `+` + market.Nasdaq[`change`] + market.Nasdaq[`percent`] = `+` + market.Nasdaq[`percent`] + } else if matches[0][2] == `?` { + market.Nasdaq[`change`] = `-` + market.Nasdaq[`change`] + market.Nasdaq[`percent`] = `-` + market.Nasdaq[`percent`] } - market.Sp500[`name`] = matches[0][11] - market.Sp500[`latest`] = matches[0][12] - switch matches[0][13] { - case `008800`: - market.Sp500[`change`] = `+` + matches[0][14] - market.Sp500[`percent`] = `+` + matches[0][15] - case `cc0000`: - market.Sp500[`change`] = `-` + matches[0][14] - market.Sp500[`percent`] = `-` + matches[0][15] - default: - market.Sp500[`change`] = matches[0][14] - market.Sp500[`percent`] = matches[0][15] + market.Sp500[`name`] = `S&P 500` + market.Sp500[`latest`] = matches[0][9] + market.Sp500[`change`] = matches[0][11] + market.Sp500[`percent`] = matches[0][12] + if matches[0][10] == `green` { + market.Sp500[`change`] = `+` + market.Sp500[`change`] + market.Sp500[`percent`] = `+` + market.Sp500[`percent`] + } else if matches[0][2] == `?` { + market.Sp500[`change`] = `-` + market.Sp500[`change`] + market.Sp500[`percent`] = `-` + market.Sp500[`percent`] } - market.Advances[`name`] = matches[0][16] - market.Advances[`nyse`] = matches[0][17] - market.Advances[`nysep`] = matches[0][18] - market.Advances[`nasdaq`] = matches[0][19] - market.Advances[`nasdaqp`] = matches[0][20] - - market.Declines[`name`] = matches[0][21] - market.Declines[`nyse`] = matches[0][22] - market.Declines[`nysep`] = matches[0][23] - market.Declines[`nasdaq`] = matches[0][24] - market.Declines[`nasdaqp`] = matches[0][25] - - market.Unchanged[`name`] = matches[0][26] - market.Unchanged[`nyse`] = matches[0][27] - market.Unchanged[`nysep`] = matches[0][28] - market.Unchanged[`nasdaq`] = matches[0][29] - market.Unchanged[`nasdaqp`] = matches[0][30] - - market.Highs[`name`] = matches[0][31] - market.Highs[`nyse`] = matches[0][32] - market.Highs[`nasdaq`] = matches[0][33] - market.Lows[`name`] = matches[0][34] - market.Lows[`nyse`] = matches[0][35] - market.Lows[`nasdaq`] = matches[0][36] + market.London[`name`] = `London` + market.London[`latest`] = matches[0][13] + market.London[`change`] = matches[0][15] + market.London[`percent`] = matches[0][16] + if matches[0][14] == `green` { + market.London[`change`] = `+` + market.London[`change`] + market.London[`percent`] = `+` + market.London[`percent`] + } else if matches[0][2] == `?` { + market.London[`change`] = `-` + market.London[`change`] + market.London[`percent`] = `-` + market.London[`percent`] + } + + market.Frankfurt[`name`] = `Frankfurt` + market.Frankfurt[`latest`] = matches[0][17] + market.Frankfurt[`change`] = matches[0][19] + market.Frankfurt[`percent`] = matches[0][20] + if matches[0][18] == `green` { + market.Frankfurt[`change`] = `+` + market.Frankfurt[`change`] + market.Frankfurt[`percent`] = `+` + market.Frankfurt[`percent`] + } else if matches[0][2] == `?` { + market.Frankfurt[`change`] = `-` + market.Frankfurt[`change`] + market.Frankfurt[`percent`] = `-` + market.Frankfurt[`percent`] + } + + market.Paris[`name`] = `Paris` + market.Paris[`latest`] = matches[0][21] + market.Paris[`change`] = matches[0][23] + market.Paris[`percent`] = matches[0][24] + if matches[0][22] == `green` { + market.Paris[`change`] = `+` + market.Paris[`change`] + market.Paris[`percent`] = `+` + market.Paris[`percent`] + } else if matches[0][2] == `?` { + market.Paris[`change`] = `-` + market.Paris[`change`] + market.Paris[`percent`] = `-` + market.Paris[`percent`] + } + + market.Tokyo[`name`] = `Tokyo` + market.Tokyo[`latest`] = matches[0][25] + market.Tokyo[`change`] = matches[0][27] + market.Tokyo[`percent`] = matches[0][28] + if matches[0][26] == `green` { + market.Tokyo[`change`] = `+` + market.Tokyo[`change`] + market.Tokyo[`percent`] = `+` + market.Tokyo[`percent`] + } else if matches[0][2] == `?` { + market.Tokyo[`change`] = `-` + market.Tokyo[`change`] + market.Tokyo[`percent`] = `-` + market.Tokyo[`percent`] + } + + market.HongKong[`name`] = `Hong Kong` + market.HongKong[`latest`] = matches[0][29] + market.HongKong[`change`] = matches[0][31] + market.HongKong[`percent`] = matches[0][32] + if matches[0][30] == `green` { + market.HongKong[`change`] = `+` + market.HongKong[`change`] + market.HongKong[`percent`] = `+` + market.HongKong[`percent`] + } else if matches[0][2] == `?` { + market.HongKong[`change`] = `-` + market.HongKong[`change`] + market.HongKong[`percent`] = `-` + market.HongKong[`percent`] + } + + market.Shanghai[`name`] = `Shanghai` + market.Shanghai[`latest`] = matches[0][33] + market.Shanghai[`change`] = matches[0][36] + market.Shanghai[`percent`] = matches[0][36] + if matches[0][34] == `green` { + market.Shanghai[`change`] = `+` + market.Shanghai[`change`] + market.Shanghai[`percent`] = `+` + market.Shanghai[`percent`] + } else if matches[0][2] == `?` { + market.Shanghai[`change`] = `-` + market.Shanghai[`change`] + market.Shanghai[`percent`] = `-` + market.Shanghai[`percent`] + } return market }