vegapokerbot/internal/handler/wizard/redmine_setup.go

205 lines
5.7 KiB
Go

package wizard
import (
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/db/model"
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/iface"
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/store"
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/util"
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/locale"
"github.com/mymmrac/telego"
tu "github.com/mymmrac/telego/telegoutil"
"net/http"
"net/url"
"strings"
"time"
)
type RedmineSetup struct {
iface.Base
Redmine *store.RedmineSetup
}
func NewRedmineSetup(app iface.App, userID, chatID int64, config *store.RedmineSetup) *RedmineSetup {
return &RedmineSetup{
Base: iface.NewBase(app, userID, chatID),
Redmine: config,
}
}
func (h *RedmineSetup) Handle(wh telego.Update) error {
if h.Redmine == nil {
return nil
}
loc := h.Localizer(wh.Message.From.LanguageCode)
if h.Redmine.URL == "" {
return h.handleURLStep(wh.Message.Text, loc)
}
if h.Redmine.Key == "" {
return h.handleKeyStep(wh.Message.Text, loc)
}
if h.Redmine.SPFieldName == "" && h.Redmine.WaitingForSPField {
return h.handleSPFieldStep(wh.Message.Text, loc)
}
return nil
}
func (h *RedmineSetup) handleURLStep(text string, loc locale.Localizer) error {
h.Redmine.URL = h.processURL(text)
if h.Redmine.URL == "" {
_, err := h.App.TG().SendMessage(&telego.SendMessageParams{
ChatID: tu.ID(h.ChatID),
Text: loc.Message("please_send_redmine_url"),
ParseMode: telego.ModeMarkdown,
})
return err
}
_, err := h.App.TG().SendMessage(&telego.SendMessageParams{
ChatID: tu.ID(h.ChatID),
Text: loc.Template("please_send_redmine_key", map[string]interface{}{"Origin": h.Redmine.URL}),
ParseMode: telego.ModeMarkdown,
})
return err
}
func (h *RedmineSetup) handleKeyStep(text string, loc locale.Localizer) error {
h.Redmine.Key = strings.TrimSpace(text)
if h.Redmine.Key == "" {
_, err := h.App.TG().SendMessage(&telego.SendMessageParams{
ChatID: tu.ID(h.ChatID),
Text: loc.Template("please_send_redmine_key", map[string]interface{}{"Origin": h.Redmine.URL}),
ParseMode: telego.ModeMarkdown,
})
return err
}
if !h.verifyRedmine() {
_, err := h.App.TG().SendMessage(&telego.SendMessageParams{
ChatID: tu.ID(h.ChatID),
Text: loc.Message("invalid_redmine_credentials"),
ParseMode: telego.ModeMarkdown,
ReplyMarkup: &telego.InlineKeyboardMarkup{InlineKeyboard: [][]telego.InlineKeyboardButton{
{
{
Text: loc.Message("yes"),
CallbackData: util.NewRedmineQuestionPayload(h.UserID, h.Redmine.Chat, true).String(),
},
{
Text: loc.Message("no"),
CallbackData: util.NewRedmineQuestionPayload(h.UserID, h.Redmine.Chat, false).String(),
},
},
}},
})
return err
}
chat, err := h.App.DB().ForChat().ByTelegramID(h.Redmine.Chat)
if err != nil {
_ = util.SendInternalError(h.App.TG(), h.ChatID, loc)
return err
}
if chat == nil || chat.ID == 0 {
_ = util.SendInternalError(h.App.TG(), h.ChatID, loc)
return nil
}
integration := &model.Integration{
Type: model.RedmineIntegration,
ChatID: chat.ID,
}
integration.StoreRedmine(h.Redmine)
if err := h.App.DB().ForIntegration().Save(integration); err != nil {
_ = util.SendInternalError(h.App.TG(), h.ChatID, loc)
return err
}
_, _ = h.App.TG().SendMessage(&telego.SendMessageParams{
ChatID: tu.ID(h.ChatID),
Text: loc.Message("redmine_was_connected"),
ParseMode: telego.ModeMarkdown,
})
_, err = h.App.TG().SendMessage(&telego.SendMessageParams{
ChatID: tu.ID(h.ChatID),
Text: loc.Message("should_send_estimated_hours_redmine"),
ParseMode: telego.ModeMarkdown,
ReplyMarkup: &telego.InlineKeyboardMarkup{InlineKeyboard: [][]telego.InlineKeyboardButton{
{
{
Text: loc.Message("yes"),
CallbackData: util.NewRedmineHoursQuestionPayload(h.UserID, h.Redmine.Chat, true).String(),
},
{
Text: loc.Message("no"),
CallbackData: util.NewRedmineHoursQuestionPayload(h.UserID, h.Redmine.Chat, false).String(),
},
},
}},
})
return err
}
func (h *RedmineSetup) handleSPFieldStep(text string, loc locale.Localizer) error {
h.Redmine.SPFieldName = strings.TrimSpace(text)
if h.Redmine.SPFieldName == "" {
_, err := h.App.TG().SendMessage(&telego.SendMessageParams{
ChatID: tu.ID(h.ChatID),
Text: loc.Message("specify_result_field"),
ParseMode: telego.ModeMarkdown,
})
return err
}
h.Redmine.WaitingForSPField = false
chat, err := h.App.DB().ForChat().ByTelegramIDWithIntegrations(h.Redmine.Chat)
if err != nil {
return err
}
for _, integration := range chat.Integrations {
if integration.Type == model.RedmineIntegration {
rs := integration.LoadRedmine()
rs.SPFieldName = h.Redmine.SPFieldName
integration.StoreRedmine(rs)
if err := h.App.DB().ForIntegration().Save(&integration); err != nil {
return err
}
break
}
}
_, _ = h.App.TG().SendMessage(&telego.SendMessageParams{
ChatID: tu.ID(h.ChatID),
Text: loc.Template("redmine_poker_will_be_configured",
map[string]interface{}{"Name": h.Redmine.SPFieldName}),
ParseMode: telego.ModeMarkdown,
})
store.RedmineSetups.Delete(h.ChatID)
return util.SendSetupDone(h.App.TG(), h.ChatID, loc)
}
func (h *RedmineSetup) processURL(input string) string {
uri, err := url.Parse(strings.TrimSpace(input))
if err != nil {
return ""
}
return uri.Scheme + "://" + uri.Host
}
func (h *RedmineSetup) verifyRedmine() bool {
req, err := http.NewRequest(http.MethodGet, h.Redmine.URL+"/issues.json", nil)
if err != nil {
return false
}
req.Header.Set("X-Redmine-Api-Key", h.Redmine.Key)
client := &http.Client{Timeout: 5 * time.Second}
resp, err := client.Do(req)
if err != nil {
return false
}
return resp.StatusCode == http.StatusOK
}