// Update retrieves BTB buy prices in both USD and BTC and saves // the prices to the database. func (c *CoinPrice) Update() error { usd, err := coinbaseQuote() if err != nil { return err } cryptsyBtc, err := cryptsyQuote() if err != nil { return err } conn := models.CloneConnection() defer conn.Close() price := &models.Price{ UsdPerBtc: usd, Cryptsy: &models.ExchangePrice{Btc: cryptsyBtc, Usd: usd * cryptsyBtc}, GeneratedAt: time.Now().UTC().Truncate(time.Minute), } if err := price.SetPercentChange(conn); err != nil { return err } return price.Insert(conn) }
func getNewRedditPosts(feedUrl, source string) ([]*models.Post, error) { conn := models.CloneConnection() defer conn.Close() // get the feed feed, err := rss.Fetch(feedUrl) if err != nil { return []*models.Post{}, err } // iterate the feed and save the new items posts := make([]*models.Post, 0) for _, item := range feed.Items { exists, err := models.PostExists(conn, item.ID) if err != nil { return []*models.Post{}, err } if !exists { post := &models.Post{ Title: item.Title, Source: source, Url: item.Link, UniqueId: item.ID, PublishedAt: item.Date, } posts = append(posts, post) } } return posts, nil }
// Update retrieves any new stores on the bitbar subreddit. func (r *Reddit) Update() error { conn := models.CloneConnection() defer conn.Close() bitbarPosts, err := getNewRedditPosts("http://www.reddit.com/r/bitbar/.rss", "/r/bitbar") if err != nil { return err } return savePosts(bitbarPosts, conn) }
func PricingRollupAction() error { conn := models.CloneConnection() defer conn.Close() // get all prices from the last 10 minutes baseTime := time.Now().UTC().Truncate(time.Minute * 10) beginning := baseTime.Add(time.Minute * -10) end := baseTime.Add(time.Minute*-1 + time.Second*59) _, err := models.GenerateAverage(conn, beginning, end) return err }
func (s *postSuite) TestUpdatingReddit(c *C) { conn := models.CloneConnection() defer conn.Close() replaceUrl(s.redditServer2.URL, &subredditUrl, func() { r := &Reddit{} r.Update() var results []*models.Post conn.DB.C("posts").Find(bson.M{}).All(&results) c.Check(len(results), Equals, 2) }) }
func (s *postSuite) TestGettingReditPosts(c *C) { conn := models.CloneConnection() defer conn.Close() replaceUrl(s.redditServer1.URL, &subredditUrl, func() { p1 := &models.Post{Title: "test title", Url: "test url", Source: "reddit", UniqueId: "http://www.reddit.com/r/worldcoin/comments/1uj486/whats_a_better_name_than_scharmbeck/"} p1.Insert(conn) posts, _ := getNewRedditPosts() c.Check(len(posts), Equals, 1) c.Check(posts[0].Title, Equals, "two worldcoins?") }) }
func (s *coinPriceSuite) TestSavingPrices(c *C) { replaceUrl(s.coinBaseServer.URL, &coinbaseUrl, func() { replaceUrl(s.cryptsyServer.URL, &cryptsyUrl, func() { conn := models.CloneConnection() defer conn.Close() coinPrice := &CoinPrice{} coinPrice.Update() var saved models.Price conn.DB.C("prices").Find(bson.M{}).One(&saved) c.Check(saved.UsdPerBtc, Equals, 676.58046) c.Check(saved.Cryptsy.Btc, Equals, 0.00053275) }) }) }
// Update retrieves BTB netork information from a blockchain api. func (n *Network) Update() error { hashRate, err := getHashRate() if err != nil { return err } diff, err := getDifficulty() if err != nil { return err } mined, err := getMined() if err != nil { return err } blockCount, err := getBlockCount() if err != nil { return err } blockReward, err := getBlockReward() if err != nil { return err } conn := models.CloneConnection() defer conn.Close() network := &models.Network{ HashRate: hashRate, Difficulty: diff, Mined: mined, BlockCount: blockCount, LatestBlockReward: blockReward, GeneratedAt: time.Now().UTC(), } return network.Insert(conn) }
func ServeAction() error { m := martini.Classic() m.Use(martini.Static("resources/public")) mainView, err := mustache.ParseFile("resources/views/main.html.mustache") if err != nil { panic(err) } homeWriter := func(useBtc bool, res http.ResponseWriter) string { conn := models.CloneConnection() defer conn.Close() // get the latest pricing data price, err := models.GetLatestPrice(conn) if err != nil { webError(err, res) return "" } // get data for the graph averages, err := models.GetAverages(conn, 24) if err != nil { webError(err, res) return "" } allAverages, err := addLatestPricesToAverages(conn, averages) if err != nil { webError(err, res) return "" } var graphAverages, graphValueType string if useBtc { graphValueType = "BTC" graphAverages = parseAverages(allAverages, true) } else { graphValueType = "USD" graphAverages = parseAverages(allAverages, false) } // get the forum posts forum, err := models.GetLatestPosts(conn, "forum", 8) if err != nil { webError(err, res) return "" } // /r/vertcoin posts redditBitBar, err := models.GetLatestPosts(conn, "/r/bitbar", 8) if err != nil { webError(err, res) return "" } // get the mining information network, err := models.GetLatestNetworkSnapshot(conn) if err != nil { webError(err, res) return "" } // generate the HTML valueMap := map[string]interface{}{ "redditBitBar": redditBitBar, "forum": forum, "averages": graphAverages, "graphValueType": graphValueType, "showBtcLink": !useBtc, "showUsdLink": useBtc, } return mainView.Render(generateTplVars(price, network), valueMap) } m.Get("/", func(res http.ResponseWriter) string { return homeWriter(false, res) }) m.Get("/:graphValue", func(params martini.Params, res http.ResponseWriter) string { var useBtc bool if params["graphValue"] == "usd" { useBtc = false } else { useBtc = true } return homeWriter(useBtc, res) }) // returns basic information about the state of the service. If any hardcoded checks fail // the message is returned with a 500 status. We can then use pingdom or another service // to alert when data integrity may be off. m.Get("/health", func(res http.ResponseWriter) string { conn := models.CloneConnection() defer conn.Close() twoHoursAgo := time.Now().Add(time.Hour * -2).Unix() // make sure the price has been updated in the last 2 hours price, err := models.GetLatestPrice(conn) if err != nil { webError(errors.New("Error getting latest price"), res) return "" } if price.GeneratedAt.Unix() < twoHoursAgo { webError(errors.New("The latest price is old"), res) return "" } // make sure the network has been updated in the last two hours network, err := models.GetLatestNetworkSnapshot(conn) if err != nil { webError(errors.New("Error getting latest network snapshot"), res) return "" } if network.GeneratedAt.Unix() < twoHoursAgo { webError(errors.New("The latest network snapshot is old"), res) return "" } return "ok" }) log.Printf("listening on port 4001") http.ListenAndServe(":4001", m) return nil }
// IndexAction is the function invoked by the index command. func IndexAction() error { conn := models.CloneConnection() defer conn.Close() return models.Index(conn) }