func (r bot) endSession(p *robots.Payload, cmd utils.Command) error { session, err := db.GetCurrentSession(p.ChannelName) if err != nil { return err } if session == nil { r.handler.Send(p, "No active poker session on *"+p.ChannelName+"*. Use `/poker session` to start a new session.") return nil } err = session.Finish() if err != nil { return err } msg := "Finished poker session for *" + session.Title + "*.\n\n" msg += "The following stories were estimated:\n" stories, err := session.GetStories() if err != nil { return err } for _, s := range stories { msg += fmt.Sprintf("*%s* - Hours: %.2f\n", s.Title, *s.Estimation) } r.handler.Send(p, msg) return nil }
func (r bot) revealVotes(p *robots.Payload, cmd utils.Command) error { session, err := db.GetCurrentSession(p.ChannelName) if err != nil { return err } if session == nil { r.handler.Send(p, "No active poker session on *"+p.ChannelName+"*. Use `/poker session` to start a new session.") return nil } story, err := session.GetCurrentStory() if err != nil { return err } if story == nil { r.handler.Send(p, "No current story on *"+p.ChannelName+"*. Use `/poker story` to start a new session.") return nil } votes, err := story.GetVotes() if err != nil { return err } s := "Votes for *" + story.Title + "*:\n" for _, v := range votes { s += fmt.Sprintf("- *%s* voted *%.2f* hours\n", v.User, v.Vote) } r.handler.Send(p, s) return nil }
func (r bot) startStory(p *robots.Payload, cmd utils.Command) error { title := cmd.StrFrom(0) session, err := db.GetCurrentSession(p.ChannelName) if err != nil { return err } if session == nil { r.handler.Send(p, "No active poker session on *"+p.ChannelName+"*. Use `/poker session` to start a new session.") return nil } story, err := session.GetCurrentStory() if err != nil { return err } if story != nil { r.handler.Send(p, "Cannot start a new story until you estimate *"+story.Title+"*") return nil } err = session.StartPokerStory(title) if err != nil { return err } r.handler.Send(p, "We can now vote for *"+title+"*") return nil }
func (r bot) vote(p *robots.Payload, cmd utils.Command) error { args, err := cmd.ParseArgs("vote") if err != nil { return err } vote := args[0] session, err := db.GetCurrentSession(p.ChannelName) if err != nil { return err } if session == nil { r.handler.Send(p, "No active poker session on *"+p.ChannelName+"*. Use `/poker session` to start a new session.") return nil } story, err := session.GetCurrentStory() if err != nil { return err } if story == nil { r.handler.Send(p, "No current story on *"+p.ChannelName+"*. Use `/poker story` to start a new session.") return nil } err = story.CastVote(p.UserName, vote) if err != nil { return err } r.handler.Send(p, "Vote cast for *"+p.UserName+"*") users := session.Users if users != "" { expUsers := strings.Split(users, ",") votes, err := story.GetVotes() if err != nil { return err } for _, v := range votes { expUsers = utils.RemoveFromSlice(expUsers, v.User) } if len(expUsers) < 1 { r.handler.Send(p, "Everyone voted, revealing votes.") r.revealVotes(p, cmd) r.handler.Send(p, "Now set the estimate for this story with `!poker set <estimate>`") } } return nil }
func (r bot) status(p *robots.Payload, cmd utils.Command) error { session, err := db.GetCurrentSession(p.ChannelName) if err != nil { return err } if session == nil { r.handler.Send(p, "No active poker session on *"+p.ChannelName+"*.") return nil } r.handler.Send(p, "We are playing a poker planning session called *"+session.Title+"*") stories, err := session.GetEstimatedStories() if len(stories) > 0 { s := "story" if len(stories) > 1 { s = "stories" } r.handler.Send(p, fmt.Sprintf("We have estimated %d %s so far.", len(stories), s)) } story, err := session.GetCurrentStory() if err != nil { return err } if story == nil { r.handler.Send(p, "There are no stories waiting for estimations. You can use `/poker story` to start a new one or `/poker finish` to finish this session.") return nil } r.handler.Send(p, "We are estimating the story *"+story.Title+"*") votes, err := story.GetVotes() if err != nil { return err } if len(votes) < 1 { r.handler.Send(p, "No one voted yet") return nil } users := []string{} for _, v := range votes { users = append(users, v.User) } r.handler.Send(p, "The following users already voted: "+strings.Join(users, ", ")) return nil }
func (r bot) addStories(p *robots.Payload, cmd utils.Command) error { session, err := db.GetCurrentSession(p.ChannelName) if err != nil { return err } if session == nil { r.handler.Send(p, "No active poker session on *"+p.ChannelName+"*.") return nil } appUrl := os.Getenv("APP_URL") url := appUrl + "poker?channel=" + p.ChannelName + "&channel_id=" + p.ChannelID a := utils.FmtAttachment("", "Click here to add stories", url, "Add stories in back to this session by following the link") r.handler.SendWithAttachments(p, "", []robots.Attachment{a}) return nil }
func NewPokerStories(w http.ResponseWriter, r *http.Request) { webSession, _ := store.Get(r, "session") channel := q(r.URL, "channel") channelId := q(r.URL, "channel_id") session, err := db.GetCurrentSession(channel) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if session == nil { fmt.Fprintf(w, "No current session for channel %s", channel) return } stories, err := session.GetStories() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } t, err := template.ParseFiles( "web/public/index.html", "web/public/poker/new.html") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } page := &PokerPage{ SessionTitle: session.Title, ChannelName: channel, ChannelID: channelId, Stories: stories, Message: "", } if webSession.Values["message"] != nil { page.Message = webSession.Values["message"].(string) } webSession.Values["message"] = "" webSession.Save(r, w) t.Execute(w, page) return }
func (r bot) setEstimation(p *robots.Payload, cmd utils.Command) error { args, err := cmd.ParseArgs("estimation") if err != nil { return err } estimation := args[0] session, err := db.GetCurrentSession(p.ChannelName) if err != nil { return err } if session == nil { r.handler.Send(p, "No active poker session on *"+p.ChannelName+"*. Use `/poker session` to start a new session.") return nil } story, err := session.GetCurrentStory() if err != nil { return err } if story == nil { r.handler.Send(p, "No current story on *"+p.ChannelName+"*. Use `/poker story` to start a new session.") return nil } err = story.UpdateEstimation(estimation) if err != nil { return err } r.handler.Send(p, "Tracked estimation of *"+estimation+"* hours for *"+story.Title+"*") story, err = session.GetCurrentStory() if err != nil { return err } if story != nil { r.nextStory(p, cmd) } return nil }
func CreatePokerStories(w http.ResponseWriter, r *http.Request) { webSession, _ := store.Get(r, "session") err := r.ParseForm() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } channel := r.PostFormValue("channel") channelId := r.PostFormValue("channel_id") stories := r.PostFormValue("stories") session, err := db.GetCurrentSession(channel) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if session == nil { fmt.Fprintf(w, "No current session for channel %s", channel) return } lines := strings.Split(stories, "\n") for _, s := range lines { s = strings.Trim(s, "\r") session.StartPokerStory(s) } h := utils.NewSlackHandler("poker", ":game_die:") h.SendMsg(channelId, fmt.Sprintf("%d stories were added to be estimated", len(lines))) msg := fmt.Sprintf("Added %d stories to this session", len(lines)) webSession.Values["message"] = msg webSession.Save(r, w) location := fmt.Sprintf("/poker?channel_id=%s&channel=%s", channelId, channel) http.Redirect(w, r, location, 301) }
func (r bot) nextStory(p *robots.Payload, cmd utils.Command) error { session, err := db.GetCurrentSession(p.ChannelName) if err != nil { return err } if session == nil { r.handler.Send(p, "No active poker session on *"+p.ChannelName+"*. Use `/poker session` to start a new session.") return nil } story, err := session.GetCurrentStory() if err != nil { return err } if story == nil { r.handler.Send(p, "No stories left to be estimated.") return nil } r.handler.Send(p, "We can now vote for *"+story.Title+"*") return nil }