예제 #1
0
파일: project.go 프로젝트: gistia/slackbot
func (r bot) estimate(p *robots.Payload, cmd utils.Command) error {
	args, err := cmd.ParseArgs("pivotal-id", "estimate")
	if err != nil {
		return err
	}

	pvtId, estimate := args[0], args[1]

	pvt, err := pivotal.NewFor(p.UserName)
	if err != nil {
		return err
	}

	// pvtStory, err := pvt.GetStory(pvtId)
	// if err != nil {
	// 	return err
	// }
	//
	numEstimate, err := strconv.Atoi(estimate)
	if err != nil {
		return err
	}

	story, err := pvt.EstimateStory(pvtId, numEstimate)
	if err != nil {
		return err
	}

	s := "Story successfully updated:\n"
	r.handler.SendWithAttachments(p, s, []robots.Attachment{
		utils.FmtAttachment("", story.Name, story.Url, ""),
	})

	return nil
}
예제 #2
0
파일: project.go 프로젝트: gistia/slackbot
func (r bot) assign(p *robots.Payload, cmd utils.Command) error {
	res, err := cmd.ParseArgs("pivotal-story-id", "username")
	if err != nil {
		return err
	}

	storyId, username := res[0], res[1]

	pvt, err := pivotal.NewFor(p.UserName)
	if err != nil {
		return err
	}

	user, err := db.GetUserByName(username)
	if err != nil {
		return err
	}
	if user == nil {
		return errors.New("User *" + username + "* not found")
	}

	story, err := pvt.AssignStory(storyId, *user.PivotalId)
	if err != nil {
		return err
	}

	s := "Story successfully updated:\n"
	r.handler.SendWithAttachments(p, s, []robots.Attachment{
		utils.FmtAttachment("", story.Name, story.Url, ""),
	})

	return nil
}
예제 #3
0
파일: project.go 프로젝트: gistia/slackbot
func (r bot) getPvtProject(p *robots.Payload, id string) (*pivotal.Project, error) {
	pvt, err := pivotal.NewFor(p.UserName)
	if err != nil {
		return nil, err
	}
	return pvt.GetProject(id)
}
예제 #4
0
파일: project.go 프로젝트: gistia/slackbot
func (r bot) members(p *robots.Payload, cmd utils.Command) error {
	name := cmd.Arg(0)
	if name == "" {
		err := errors.New(
			"Missing project name. Use `!project addtask <project> <task-name>`")
		return err
	}
	pr, err := getProject(name)
	if err != nil {
		return err
	}

	pvt, err := pivotal.NewFor(p.UserName)
	if err != nil {
		return err
	}

	if pr == nil {
		r.handler.Send(p, "Project *"+name+"* not found")
		return nil
	}

	members, err := pvt.GetProjectMemberships(pr.StrPivotalId())
	if err != nil {
		return err
	}

	s := "Pivotal members for project *" + pr.Name + "*:\n"
	for _, m := range members {
		s += fmt.Sprintf("%d - %s\n", m.Person.Id, m.Person.Name)
	}

	r.handler.Send(p, s)
	return nil
}
예제 #5
0
파일: project.go 프로젝트: gistia/slackbot
func (r bot) unassigned(p *robots.Payload, cmd utils.Command) error {
	res, err := cmd.ParseArgs("project")
	if err != nil {
		return err
	}

	name := res[0]
	pr, err := getProject(name)
	if err != nil {
		return err
	}

	pvt, err := pivotal.NewFor(p.UserName)
	if err != nil {
		return err
	}

	msg := "Unassigned stories for *" + name + "*:\n"

	stories, err := pvt.GetUnassignedStories(pr.StrPivotalId())

	if len(stories) < 1 {
		r.handler.Send(p, "No unassigned stories for *"+name+"*")
		return nil
	}

	for _, s := range stories {
		msg += fmt.Sprintf("%d - %s\n", s.Id, s.Name)
	}

	r.handler.Send(p, msg)
	return nil
}
예제 #6
0
파일: project.go 프로젝트: gistia/slackbot
func (r bot) startTask(p *robots.Payload, cmd utils.Command) error {
	// pr, err := getProject(cmd.Arg(0))
	// if err != nil {
	// 	return err
	// }
	mvn, err := mavenlink.NewFor(p.UserName)
	if err != nil {
		return err
	}
	pvt, err := pivotal.NewFor(p.UserName)
	if err != nil {
		return err
	}

	if storyId := cmd.Arg(0); storyId != "" {
		pvtStory, err := pvt.GetStory(storyId)
		if err != nil {
			return err
		}

		pvtStory, err = pvt.SetStoryState(pvtStory.GetStringId(), "started")
		if err != nil {
			return err
		}

		if mvnId := pvtStory.GetMavenlinkId(); mvnId != "" {
			mvnStory, err := mvn.GetStory(mvnId)
			if err != nil {
				return err
			}

			fmt.Printf(" ** Got story: %+v\n", mvnStory)

			mvnStory.State = "started"
			mvnStory, err = mvn.SetStoryState(mvnStory.Id, "started")
			if err != nil {
				return err
			}
		}

		r.handler.Send(p, "Story *"+pvtStory.Name+"* started")
		return nil
	}

	// stories, err := mvn.ChildStories(pr.MvnSprintStoryId)
	// if err != nil {
	// 	return err
	// }

	// r.handler.Send(p, "Click the story you want to start on *"+pr.Name+"*:")
	// url := os.Getenv("APP_URL")
	// atts := mavenlink.CustomFormatStories(stories, url+"selection/startTask/")
	// for _, a := range atts {
	// 	r.handler.SendWithAttachments(p, "", []robots.Attachment{a})
	// }
	return nil
}
예제 #7
0
파일: project.go 프로젝트: gistia/slackbot
func (r bot) myStories(p *robots.Payload, cmd utils.Command) error {
	name := cmd.Arg(0)
	var pr *db.Project
	var err error

	if name == "" {
		pr, err = db.GetProjectByChannel(p.ChannelName)
	} else {
		pr, err = db.GetProjectByName(name)
	}

	if err != nil {
		return err
	}

	if pr == nil {
		r.handler.Send(p, "Missing project name.")
		return nil
	}

	pvt, err := pivotal.NewFor(p.UserName)
	if err != nil {
		return err
	}

	user, err := db.GetUserByName(p.UserName)
	if err != nil {
		return err
	}

	filter := map[string]string{
		"owned_by": user.StrPivotalId(),
		"state":    "started,finished",
	}
	stories, err := pvt.FilteredStories(pr.StrPivotalId(), filter)
	if err != nil {
		return err
	}

	if len(stories) < 1 {
		r.handler.Send(p, "No open stories in project *"+pr.Name+"* for *"+p.UserName+"*")
		return nil
	}

	str := "Current stories in project *" + pr.Name + "* for *" + p.UserName + "*:\n"
	atts := []robots.Attachment{}
	for _, s := range stories {
		fallback := fmt.Sprintf("%d - %s - %s\n", s.Id, s.Name, s.State)
		title := fmt.Sprintf("%d - %s\n", s.Id, s.Name)
		a := utils.FmtAttachment(fallback, title, s.Url, s.State)
		atts = append(atts, a)
	}

	r.handler.SendWithAttachments(p, str, atts)
	return nil
}
예제 #8
0
파일: project.go 프로젝트: gistia/slackbot
func (r bot) create(p *robots.Payload, cmd utils.Command) error {
	alias := cmd.Arg(0)
	if alias == "" {
		r.handler.Send(p, "Missing project alias. Usage: `!project createproject <alias> <long-name>`")
		return nil
	}
	name := cmd.StrFrom(1)
	if name == "" {
		r.handler.Send(p, "Missing project name. Usage: `!project createproject <alias> <long-name>`")
		return nil
	}
	mvn, err := mavenlink.NewFor(p.UserName)
	if err != nil {
		return err
	}
	pvt, err := pivotal.NewFor(p.UserName)
	if err != nil {
		return err
	}
	pvtProject := pivotal.Project{
		Name: name,
		// PointScale: "1,2,3,4,5,6,7,8,9,10,16,20",
	}
	pvtNewProject, err := pvt.CreateProject(pvtProject)
	if err != nil {
		return err
	}
	mvnProject := mavenlink.Project{
		Title:       name,
		Description: fmt.Sprintf("[pvt:%s]", pvtNewProject.Id),
		CreatorRole: "maven",
	}
	mvnNewProject, err := mvn.CreateProject(mvnProject)
	if err != nil {
		return err
	}
	if mvnNewProject == nil {
		return errors.New("Mavenlink returned a nil project")
	}
	pvtNewProject.Description = "[mvn:" + mvnNewProject.Id + "]"
	pvtNewProject, err = pvt.UpdateProject(*pvtNewProject)
	if err != nil {
		return err
	}

	err = r.makeLink(p, alias, mvnNewProject.Id, strconv.FormatInt(pvtNewProject.Id, 10))
	if err != nil {
		return err
	}

	r.handler.Send(p, "Project *"+name+"* created on Pivotal and Mavenlink.")
	return nil
}
예제 #9
0
파일: commands.go 프로젝트: gistia/slackbot
func StartedTasks(bot *UserBot, cmd utils.Command) error {
	username := bot.lastMessage.User.Name
	projects, err := db.GetProjects()
	if err != nil {
		return err
	}

	if projects == nil || len(projects) < 1 {
		bot.reply("There are no linked projects currently. Use `/project link` command to add one.")
		return nil
	}

	user, err := db.GetUserByName(username)
	if err != nil {
		return err
	}

	pvt, err := pivotal.NewFor(username)
	if err != nil {
		return err
	}

	msg := ""
	for _, p := range projects {
		filter := map[string]string{
			"owned_by": user.StrPivotalId(),
			"state":    "started",
		}
		stories, err := pvt.FilteredStories(p.StrPivotalId(), filter)
		if err != nil {
			return err
		}

		if len(stories) < 1 {
			continue
		}

		msg += "Stories for *" + p.Name + "*:\n"
		for _, s := range stories {
			msg += fmt.Sprintf("%d - %s - %s\n", s.Id, s.Name, s.State)
		}
	}

	if msg == "" {
		msg = "No started tasks for you"
	}

	bot.reply(msg)
	return nil
}
예제 #10
0
파일: project.go 프로젝트: gistia/slackbot
func (r bot) addmember(p *robots.Payload, cmd utils.Command) error {
	name := cmd.Arg(0)
	if name == "" {
		err := errors.New(
			"Missing project name. Use `!project addmember <project> <username>`")
		return err
	}
	username := cmd.Arg(1)
	if name == "" {
		err := errors.New(
			"Missing user name. Use `!project addmember <project> <username>`")
		return err
	}

	pr, err := getProject(name)
	if err != nil {
		return err
	}

	pvt, err := pivotal.NewFor(p.UserName)
	if err != nil {
		return err
	}

	if pr == nil {
		r.handler.Send(p, "Project *"+name+"* not found")
		return nil
	}

	user, err := db.GetUserByName(username)
	if pr == nil {
		r.handler.Send(p, "Project *"+name+"* not found")
		return nil
	}
	if user == nil {
		r.handler.Send(p, "User *"+username+"* not found")
		return nil
	}

	_, err = pvt.CreateProjectMembership(pr.StrPivotalId(), *user.PivotalId, "member")
	if err != nil {
		return err
	}

	r.handler.Send(p, "New member *"+username+"* added to *"+name+"*")
	return nil
}
예제 #11
0
파일: project.go 프로젝트: gistia/slackbot
func (r bot) addStory(p *robots.Payload, cmd utils.Command) error {
	name := cmd.Arg(0)
	if name == "" {
		err := errors.New(
			"Missing project name. Use `!project addtask <project> [type:<story-type>] <task-name>`")
		return err
	}

	storyType := cmd.Param("type")
	if storyType == "" {
		storyType = "feature"
	}

	storyName := strings.Join(cmd.ArgsFrom(1), " ")
	if storyName == "" {
		err := errors.New(
			"Missing story name. Use `!project addtask <project> <task-name>`")
		return err
	}

	pr, err := getProject(name)
	if err != nil {
		return err
	}
	mvn, err := mavenlink.NewFor(p.UserName)
	if err != nil {
		return err
	}
	pvt, err := pivotal.NewFor(p.UserName)
	if err != nil {
		return err
	}

	pvtStory := pivotal.Story{
		Name:      storyName,
		ProjectId: pr.PivotalId,
		Type:      storyType,
	}
	pvtNewStory, err := pvt.CreateStory(pvtStory)
	if err != nil {
		return err
	}

	desc := fmt.Sprintf("[pvt:%d]", pvtNewStory.Id)
	mvnStory := mavenlink.Story{
		Title:       storyName,
		Description: desc,
		ParentId:    pr.MvnSprintStoryId,
		WorkspaceId: strconv.FormatInt(pr.MavenlinkId, 10),
		StoryType:   "task",
	}
	mvnNewStory, err := mvn.CreateStory(mvnStory)
	if err != nil {
		return err
	}

	tmpStory := pivotal.Story{
		Id:          pvtNewStory.Id,
		Description: "[mvn:" + mvnNewStory.Id + "]",
	}
	pvtNewStory, err = pvt.UpdateStory(tmpStory)
	if err != nil {
		return err
	}

	pvtAtt := utils.FmtAttachment(
		fmt.Sprintf("- Pivotal %d - %s\n", pvtNewStory.Id, pvtNewStory.Name),
		fmt.Sprintf("Pivotal %d - %s\n", pvtNewStory.Id, pvtNewStory.Name),
		pvtNewStory.Url, "")
	mvnAtt := utils.FmtAttachment(
		fmt.Sprintf("- Mavenlink %s - %s\n", mvnNewStory.Id, mvnNewStory.Title),
		fmt.Sprintf("Mavenlink %s - %s\n", mvnNewStory.Id, mvnNewStory.Title),
		mvnNewStory.URL(), "")

	s := "Stories successfully added:\n"
	r.handler.SendWithAttachments(p, s, []robots.Attachment{pvtAtt, mvnAtt})
	return nil
}
예제 #12
0
파일: commands.go 프로젝트: gistia/slackbot
func claimTimer(bot *UserBot, cmd utils.Command) error {
	timerName := cmd.Arg(0)
	if timerName == "" {
		return errors.New("Missing timer. Usage: `claim <timer-name> <pivotal-task-id>`")
	}

	taskID := cmd.Arg(1)
	if taskID == "" {
		return errors.New("Missing task id. Usage: `claim <timer-name> <pivotal-task-id>`")
	}

	username := bot.lastMessage.User.Name
	timer, err := db.GetTimerByName(username, timerName)
	if err != nil {
		return err
	}
	if timer == nil {
		return errors.New("You have no timer with name *" + timerName + "*")
	}

	err = timer.Stop()
	if err != nil {
		return err
	}
	bot.reply("Timer *" + timer.Name + "* stopped.")

	pvt, err := pivotal.NewFor(username)
	if err != nil {
		return err
	}

	mvn, err := mavenlink.NewFor(username)
	if err != nil {
		return err
	}

	task, err := pvt.GetStory(taskID)
	if err != nil {
		return err
	}

	mvnID := task.GetMavenlinkId()
	if mvnID == "" {
		return errors.New("Can't claim because the Pivotal task doesn't have a mavenlink tag like `[mvn:<id>]`")
	}

	story, err := mvn.GetStory(mvnID)
	if err != nil {
		return err
	}

	_, err = mvn.AddTimeEntry(story, timer.Minutes())
	if err != nil {
		return err
	}

	bot.reply(fmt.Sprintf("Added *%d* minutes to story *%s - %s*",
		timer.Minutes(), story.Id, story.Title))

	return nil
}