2024-05-07 21:49:09 +03:00
|
|
|
package redmine
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/integration/iface"
|
|
|
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/integration/null"
|
|
|
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/integration/redmine/api"
|
2024-05-10 11:46:43 +03:00
|
|
|
"go.uber.org/zap"
|
2024-05-07 21:49:09 +03:00
|
|
|
"regexp"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
var issueNumberMatcher = regexp.MustCompile(`(?m)\/issues\/(\d+)`)
|
|
|
|
|
|
|
|
var sprintNames = []string{"sprint", "спринт"}
|
|
|
|
|
|
|
|
type Redmine struct {
|
2024-05-10 11:46:43 +03:00
|
|
|
api *api.Client
|
|
|
|
log *zap.SugaredLogger
|
|
|
|
spFieldName string
|
2024-05-07 21:49:09 +03:00
|
|
|
}
|
|
|
|
|
2024-05-10 11:46:43 +03:00
|
|
|
func New(params map[string]interface{}, log *zap.SugaredLogger) iface.Integration {
|
2024-05-07 21:49:09 +03:00
|
|
|
uri, ok := params["url"]
|
|
|
|
if !ok {
|
|
|
|
return null.New()
|
|
|
|
}
|
|
|
|
key, ok := params["key"]
|
|
|
|
if !ok {
|
|
|
|
return null.New()
|
|
|
|
}
|
|
|
|
uriString, ok := uri.(string)
|
|
|
|
if !ok {
|
|
|
|
return null.New()
|
|
|
|
}
|
|
|
|
keyString, ok := key.(string)
|
|
|
|
if !ok {
|
|
|
|
return null.New()
|
|
|
|
}
|
2024-05-10 11:46:43 +03:00
|
|
|
var spField string
|
|
|
|
if spFieldName, ok := params["sp_field"]; ok {
|
|
|
|
if strField, ok := spFieldName.(string); ok {
|
|
|
|
spField = strField
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return &Redmine{api: api.New(uriString, keyString, log), log: log, spFieldName: spField}
|
2024-05-07 21:49:09 +03:00
|
|
|
}
|
|
|
|
|
2024-05-10 11:46:43 +03:00
|
|
|
func (r *Redmine) GetTaskInfo(input string) (int, string) {
|
2024-05-07 21:49:09 +03:00
|
|
|
taskNumber := r.getTaskNumber(input)
|
|
|
|
if taskNumber == 0 {
|
2024-05-10 11:46:43 +03:00
|
|
|
r.log.Debugf("[Redmine] Cannot extract task number from %s", input)
|
|
|
|
return 0, ""
|
2024-05-07 21:49:09 +03:00
|
|
|
}
|
|
|
|
task, err := r.api.Issue(taskNumber)
|
|
|
|
if err != nil {
|
2024-05-10 11:46:43 +03:00
|
|
|
r.log.Errorf("[Redmine] Cannot get Redmine issue %d: %s", taskNumber, err)
|
|
|
|
return 0, ""
|
2024-05-07 21:49:09 +03:00
|
|
|
}
|
|
|
|
sprint := r.getSprint(task.CustomFields)
|
|
|
|
if sprint != "" {
|
2024-05-10 11:46:43 +03:00
|
|
|
sprint = fmt.Sprintf(" - _%s_", sprint)
|
|
|
|
}
|
|
|
|
taskInfo := strings.ReplaceAll(fmt.Sprintf("_(%s) %s_: [%s](%s/issues/%d)%s",
|
|
|
|
task.Project.Name, task.Tracker.Name, task.Subject, r.api.URL, taskNumber, sprint), "*", "")
|
|
|
|
return task.ID, "\n" + taskInfo + ""
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *Redmine) PushVoteResult(id int, result float64) error {
|
|
|
|
task, err := r.api.Issue(id)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
issue := &api.Issue{
|
|
|
|
EstimatedHours: api.Hours(strconv.FormatFloat(result*8, 'f', 0, 64)),
|
|
|
|
}
|
|
|
|
if r.spFieldName != "" {
|
|
|
|
for _, field := range task.CustomFields {
|
|
|
|
field := field
|
|
|
|
if field.Name == r.spFieldName {
|
|
|
|
field.Value = strconv.FormatFloat(result, 'f', 1, 64)
|
|
|
|
issue.CustomFields = []api.CustomField{field}
|
|
|
|
}
|
|
|
|
}
|
2024-05-07 21:49:09 +03:00
|
|
|
}
|
2024-05-10 11:46:43 +03:00
|
|
|
return r.api.UpdateIssue(id, issue)
|
2024-05-07 21:49:09 +03:00
|
|
|
}
|
|
|
|
|
2024-05-10 11:46:43 +03:00
|
|
|
func (r *Redmine) getTaskNumber(input string) int {
|
|
|
|
num, err := strconv.Atoi(input)
|
2024-05-07 21:49:09 +03:00
|
|
|
if err == nil && num > 0 {
|
|
|
|
return num
|
|
|
|
}
|
|
|
|
matches := issueNumberMatcher.FindStringSubmatch(input)
|
|
|
|
if len(matches) < 2 {
|
|
|
|
return 0
|
|
|
|
}
|
2024-05-10 11:46:43 +03:00
|
|
|
number, err := strconv.Atoi(matches[1])
|
2024-05-07 21:49:09 +03:00
|
|
|
if err != nil {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
return number
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *Redmine) getSprint(fields []api.CustomField) string {
|
|
|
|
for _, field := range fields {
|
|
|
|
for _, name := range sprintNames {
|
|
|
|
if strings.ToLower(field.Name) == name {
|
|
|
|
return field.Value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}
|