Merge pull request #190 from velour/bid_updates

Bid updates
This commit is contained in:
Chris Sexton 2019-07-16 16:43:36 -04:00 committed by GitHub
commit 2103cfbca0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 20 deletions

View File

@ -81,10 +81,10 @@ func (p *NewsBid) message(conn bot.Connector, k bot.Kind, message msg.Message, a
} }
amount, _ := strconv.Atoi(parts[1]) amount, _ := strconv.Atoi(parts[1])
url := parts[2] url := parts[2]
if err := p.ws.Bid(message.User.Name, amount, url); err != nil { if bid, err := p.ws.Bid(message.User.Name, amount, url); err != nil {
p.bot.Send(conn, bot.Message, ch, fmt.Sprintf("Error placing bid: %s", err)) p.bot.Send(conn, bot.Message, ch, fmt.Sprintf("Error placing bid: %s", err))
} else { } else {
p.bot.Send(conn, bot.Message, ch, "Your bid has been placed.") p.bot.Send(conn, bot.Message, ch, fmt.Sprintf("Your bid has been placed on %s", bid.Title))
} }
return true return true
} }

View File

@ -123,7 +123,7 @@ func (w *Webshit) Check() ([]WeeklyResult, error) {
storyMap := map[string]Story{} storyMap := map[string]Story{}
for _, s := range stories { for _, s := range stories {
storyMap[s.Title] = s storyMap[s.URL] = s
} }
wr := w.checkBids(bids, storyMap) wr := w.checkBids(bids, storyMap)
@ -162,7 +162,7 @@ func (w *Webshit) checkBids(bids []Bid, storyMap map[string]Story) []WeeklyResul
} }
rec := wr[b.User] rec := wr[b.User]
if s, ok := storyMap[b.Title]; ok { if s, ok := storyMap[b.URL]; ok {
log.Debug().Interface("story", s).Msg("won bid") log.Debug().Interface("story", s).Msg("won bid")
rec.Won += b.Bid rec.Won += b.Bid
rec.Score += b.Bid rec.Score += b.Bid
@ -225,9 +225,13 @@ func (w *Webshit) GetWeekly() ([]Story, *time.Time, error) {
doc.Find(".storylink").Each(func(i int, s *goquery.Selection) { doc.Find(".storylink").Each(func(i int, s *goquery.Selection) {
story := Story{ story := Story{
Title: s.Find("a").Text(), Title: s.Find("a").Text(),
URL: s.Find("a").AttrOr("src", ""), URL: s.SiblingsFiltered(".small").First().Find("a").AttrOr("href", ""),
} }
items = append(items, story) items = append(items, story)
log.Debug().
Str("URL", story.URL).
Str("Title", story.Title).
Msg("Parsed webshit story")
}) })
return items, published, nil return items, published, nil
@ -274,33 +278,40 @@ func (w *Webshit) GetAllBalances() ([]Balance, error) {
} }
// Bid allows a user to place a bid on a particular story // Bid allows a user to place a bid on a particular story
func (w *Webshit) Bid(user string, amount int, URL string) error { func (w *Webshit) Bid(user string, amount int, URL string) (Bid, error) {
bal := w.GetBalance(user) bal := w.GetBalance(user)
if bal < amount { if bal < amount {
return fmt.Errorf("cannot bid more than balance, %d", bal) return Bid{}, fmt.Errorf("cannot bid more than balance, %d", bal)
} }
story, err := w.getStoryByURL(URL) story, err := w.getStoryByURL(URL)
if err != nil { if err != nil {
return err return Bid{}, err
} }
ts := time.Now().Unix()
tx := w.db.MustBegin() tx := w.db.MustBegin()
_, err = tx.Exec(`insert into webshit_bids (user,title,url,bid,placed) values (?,?,?,?,?)`, _, err = tx.Exec(`insert into webshit_bids (user,title,url,bid,placed) values (?,?,?,?,?)`,
user, story.Title, story.URL, amount, time.Now().Unix()) user, story.Title, story.URL, amount, ts)
if err != nil { if err != nil {
tx.Rollback() tx.Rollback()
return err return Bid{}, err
} }
q := `insert into webshit_balances (user,balance,score) values (?,?,0) q := `insert into webshit_balances (user,balance,score) values (?,?,0)
on conflict(user) do update set balance=?` on conflict(user) do update set balance=?`
_, err = tx.Exec(q, user, bal-amount, bal-amount) _, err = tx.Exec(q, user, bal-amount, bal-amount)
if err != nil { if err != nil {
tx.Rollback() tx.Rollback()
return err return Bid{}, err
} }
tx.Commit() tx.Commit()
return err return Bid{
User: user,
Title: story.Title,
URL: story.URL,
Placed: ts,
}, err
} }
// getStoryByURL scrapes the URL for a title // getStoryByURL scrapes the URL for a title

View File

@ -15,7 +15,7 @@ func init() {
log.Logger = log.Logger.Output(zerolog.ConsoleWriter{Out: os.Stderr}) log.Logger = log.Logger.Output(zerolog.ConsoleWriter{Out: os.Stderr})
} }
func make(t *testing.T) *Webshit { func makeWS(t *testing.T) *Webshit {
db := sqlx.MustOpen("sqlite3", "file::memory:?mode=memory&cache=shared") db := sqlx.MustOpen("sqlite3", "file::memory:?mode=memory&cache=shared")
w := New(db) w := New(db)
assert.Equal(t, w.db, db) assert.Equal(t, w.db, db)
@ -23,7 +23,7 @@ func make(t *testing.T) *Webshit {
} }
func TestWebshit_GetWeekly(t *testing.T) { func TestWebshit_GetWeekly(t *testing.T) {
w := make(t) w := makeWS(t)
weekly, pub, err := w.GetWeekly() weekly, pub, err := w.GetWeekly()
t.Logf("Pub: %v", pub) t.Logf("Pub: %v", pub)
assert.NotNil(t, pub) assert.NotNil(t, pub)
@ -32,14 +32,14 @@ func TestWebshit_GetWeekly(t *testing.T) {
} }
func TestWebshit_GetHeadlines(t *testing.T) { func TestWebshit_GetHeadlines(t *testing.T) {
w := make(t) w := makeWS(t)
headlines, err := w.GetHeadlines() headlines, err := w.GetHeadlines()
assert.Nil(t, err) assert.Nil(t, err)
assert.NotEmpty(t, headlines) assert.NotEmpty(t, headlines)
} }
func TestWebshit_getStoryByURL(t *testing.T) { func TestWebshit_getStoryByURL(t *testing.T) {
w := make(t) w := makeWS(t)
expected := "Developer Tropes: “Google Does It”" expected := "Developer Tropes: “Google Does It”"
s, err := w.getStoryByURL("https://news.ycombinator.com/item?id=20432887") s, err := w.getStoryByURL("https://news.ycombinator.com/item?id=20432887")
assert.Nil(t, err) assert.Nil(t, err)
@ -47,26 +47,26 @@ func TestWebshit_getStoryByURL(t *testing.T) {
} }
func TestWebshit_getStoryByURL_BadURL(t *testing.T) { func TestWebshit_getStoryByURL_BadURL(t *testing.T) {
w := make(t) w := makeWS(t)
_, err := w.getStoryByURL("https://google.com") _, err := w.getStoryByURL("https://google.com")
assert.Error(t, err) assert.Error(t, err)
} }
func TestWebshit_GetBalance(t *testing.T) { func TestWebshit_GetBalance(t *testing.T) {
w := make(t) w := makeWS(t)
expected := 100 expected := 100
actual := w.GetBalance("foo") actual := w.GetBalance("foo")
assert.Equal(t, expected, actual) assert.Equal(t, expected, actual)
} }
func TestWebshit_checkBids(t *testing.T) { func TestWebshit_checkBids(t *testing.T) {
w := make(t) w := makeWS(t)
bids := []Bid{ bids := []Bid{
Bid{User: "foo", Title: "bar", URL: "baz", Bid: 10}, Bid{User: "foo", Title: "bar", URL: "baz", Bid: 10},
Bid{User: "foo", Title: "bar2", URL: "baz2", Bid: 10}, Bid{User: "foo", Title: "bar2", URL: "baz2", Bid: 10},
} }
storyMap := map[string]Story{ storyMap := map[string]Story{
"bar": Story{Title: "bar", URL: "baz"}, "baz": Story{Title: "bar", URL: "baz"},
} }
result := w.checkBids(bids, storyMap) result := w.checkBids(bids, storyMap)
assert.Len(t, result, 1) assert.Len(t, result, 1)