- fix folder creation process;
This commit is contained in:
parent
6752028e00
commit
6c07f434fc
|
|
@ -7,7 +7,6 @@ RUN apk add git
|
||||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go install -ldflags '-extldflags "-static"' -tags timetzdata ./cmd/main.go
|
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go install -ldflags '-extldflags "-static"' -tags timetzdata ./cmd/main.go
|
||||||
|
|
||||||
FROM scratch
|
FROM scratch
|
||||||
# the test program:
|
|
||||||
COPY --from=app-builder /go/bin/main /ticket-pimp
|
COPY --from=app-builder /go/bin/main /ticket-pimp
|
||||||
COPY --from=app-builder /go/src/ticket-pimp/cmd/prod.env /
|
COPY --from=app-builder /go/src/ticket-pimp/cmd/prod.env /
|
||||||
# the tls certificates:
|
# the tls certificates:
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,12 @@ import (
|
||||||
"github.com/bwmarrin/discordgo"
|
"github.com/bwmarrin/discordgo"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initBotWith(token string) (*discordgo.Session, error) {
|
func initBotWith(token string) *discordgo.Session {
|
||||||
discord, err := discordgo.New("Bot " + token)
|
discord, err := discordgo.New("Bot " + token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
log.Fatalf("unable to create discord session: %v", err)
|
||||||
}
|
}
|
||||||
return discord, nil
|
return discord
|
||||||
}
|
}
|
||||||
|
|
||||||
type DiscordOptions struct {
|
type DiscordOptions struct {
|
||||||
|
|
@ -28,10 +28,7 @@ type DiscordOptions struct {
|
||||||
func Run(conf domain.Config, opts DiscordOptions) error {
|
func Run(conf domain.Config, opts DiscordOptions) error {
|
||||||
token := conf.Discord.Token
|
token := conf.Discord.Token
|
||||||
|
|
||||||
session, err := initBotWith(token)
|
session := initBotWith(token)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
router := handler.InitRouter(*opts.Controller)
|
router := handler.InitRouter(*opts.Controller)
|
||||||
|
|
||||||
|
|
@ -41,7 +38,6 @@ func Run(conf domain.Config, opts DiscordOptions) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
session.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
session.AddHandler(func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||||
|
|
||||||
if h, ok := commandHandlers[i.ApplicationCommandData().Name]; ok {
|
if h, ok := commandHandlers[i.ApplicationCommandData().Name]; ok {
|
||||||
h(s, i)
|
h(s, i)
|
||||||
}
|
}
|
||||||
|
|
@ -73,7 +69,7 @@ func Run(conf domain.Config, opts DiscordOptions) error {
|
||||||
|
|
||||||
log.Println("Removing commands...")
|
log.Println("Removing commands...")
|
||||||
for _, h := range cmds {
|
for _, h := range cmds {
|
||||||
err = session.ApplicationCommandDelete(session.State.User.ID, "", h.ID)
|
err := session.ApplicationCommandDelete(session.State.User.ID, "", h.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicf("Cannot delete '%v' command: %v", h.Name, err)
|
log.Panicf("Cannot delete '%v' command: %v", h.Name, err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/bwmarrin/discordgo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h *router) CreateFolderHandler(nameMinLenght int) route {
|
||||||
|
const (
|
||||||
|
nameOption string = "folder_name"
|
||||||
|
)
|
||||||
|
return route{
|
||||||
|
|
||||||
|
Command: discordgo.ApplicationCommand{
|
||||||
|
Name: "folder",
|
||||||
|
Description: "Command for cloud folder creation",
|
||||||
|
Options: []*discordgo.ApplicationCommandOption{
|
||||||
|
{
|
||||||
|
Type: discordgo.ApplicationCommandOptionString,
|
||||||
|
Name: nameOption,
|
||||||
|
Description: "Type the folder's name",
|
||||||
|
Required: false,
|
||||||
|
MinLength: &nameMinLenght,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
Handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||||
|
initialResponse := discordgo.InteractionResponse{
|
||||||
|
// Ignore type for now, they will be discussed in "responses"
|
||||||
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||||
|
Data: &discordgo.InteractionResponseData{
|
||||||
|
Flags: discordgo.MessageFlagsEphemeral,
|
||||||
|
Content: "..folder is going to be created",
|
||||||
|
Title: "📂 Folder creation",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
s.InteractionRespond(i.Interaction, &initialResponse)
|
||||||
|
|
||||||
|
var result string = "unexpected result"
|
||||||
|
|
||||||
|
options := i.ApplicationCommandData().Options
|
||||||
|
|
||||||
|
optionMap := make(map[string]*discordgo.ApplicationCommandInteractionDataOption, len(options))
|
||||||
|
for _, opt := range options {
|
||||||
|
optionMap[opt.Name] = opt
|
||||||
|
}
|
||||||
|
|
||||||
|
var str string = ""
|
||||||
|
|
||||||
|
dchan, err := s.Channel(i.ChannelID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error while identifying channel: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if dchan.ParentID == strconv.Itoa(1150719794853716028) {
|
||||||
|
log.Println("yes, channel is from `Projects`")
|
||||||
|
project, err := h.controller.GetProjectByChannelID(context.TODO(), i.ChannelID)
|
||||||
|
if err != nil {
|
||||||
|
result = fmt.Sprintf("unable to retrieve project from db, error: %v", err)
|
||||||
|
} else {
|
||||||
|
switch {
|
||||||
|
case project == nil:
|
||||||
|
if option, ok := optionMap[nameOption]; ok {
|
||||||
|
str = option.StringValue()
|
||||||
|
} else {
|
||||||
|
str = "Ты, либо в проекте директорию создавай, либо имя напиши, блет!"
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
str = project.ShortName
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := h.controller.ICloud.CreateFolder(str)
|
||||||
|
if resp.ErrMessage != nil {
|
||||||
|
result = fmt.Sprintf("Command executed w/ errors: ``` %v``` \n But check this link: %s\n", resp.ErrMessage, resp.Folder.PrivateURL)
|
||||||
|
} else {
|
||||||
|
result = fmt.Sprintf("📂 Folder was created: %s", resp.Folder.PrivateURL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = s.FollowupMessageCreate(i.Interaction, true, &discordgo.WebhookParams{
|
||||||
|
Content: result,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
s.FollowupMessageCreate(i.Interaction, true, &discordgo.WebhookParams{
|
||||||
|
Content: fmt.Sprintf("Something went wrong: %v", err),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/bwmarrin/discordgo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h *router) Ping() route {
|
||||||
|
return route{
|
||||||
|
Command: discordgo.ApplicationCommand{
|
||||||
|
Name: "ping",
|
||||||
|
Description: "pongs in a reply",
|
||||||
|
},
|
||||||
|
Handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||||
|
log.Println("ok, I'm here..")
|
||||||
|
|
||||||
|
err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||||
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||||
|
Data: &discordgo.InteractionResponseData{
|
||||||
|
Content: "`pong`",
|
||||||
|
Title: "Pong reply",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,109 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/bwmarrin/discordgo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h *router) CreateRepoHandler(repoNameMinLength int) route {
|
||||||
|
const (
|
||||||
|
projectRepo = "project_repo"
|
||||||
|
buildRepo = "build_repo"
|
||||||
|
)
|
||||||
|
|
||||||
|
return route{
|
||||||
|
Command: discordgo.ApplicationCommand{
|
||||||
|
Name: "repo",
|
||||||
|
Description: "Command for repository creation",
|
||||||
|
Options: []*discordgo.ApplicationCommandOption{
|
||||||
|
{
|
||||||
|
Type: discordgo.ApplicationCommandOptionString,
|
||||||
|
Name: "repo_type",
|
||||||
|
Description: "The type of repo",
|
||||||
|
Required: true,
|
||||||
|
Choices: []*discordgo.ApplicationCommandOptionChoice{
|
||||||
|
{
|
||||||
|
Name: "Unity project repo",
|
||||||
|
Value: projectRepo,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "XCode build repo",
|
||||||
|
Value: buildRepo,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: discordgo.ApplicationCommandOptionString,
|
||||||
|
Name: "repo_name",
|
||||||
|
Description: "Type the repository's name",
|
||||||
|
Required: false,
|
||||||
|
MinLength: &repoNameMinLength,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||||
|
var result string
|
||||||
|
// Access options in the order provided by the user.
|
||||||
|
options := i.ApplicationCommandData().Options
|
||||||
|
|
||||||
|
// Or convert the slice into a map
|
||||||
|
optionMap := make(map[string]*discordgo.ApplicationCommandInteractionDataOption, len(options))
|
||||||
|
for _, opt := range options {
|
||||||
|
optionMap[opt.Name] = opt
|
||||||
|
}
|
||||||
|
|
||||||
|
var str string = ""
|
||||||
|
|
||||||
|
project, err := h.controller.GetProjectByChannelID(context.TODO(), i.ChannelID)
|
||||||
|
if err != nil {
|
||||||
|
result = fmt.Sprintf("unable to retrieve project from db, error: %v", err)
|
||||||
|
} else {
|
||||||
|
var suffix string
|
||||||
|
if option, ok := optionMap["repo_type"]; ok {
|
||||||
|
switch option.Value {
|
||||||
|
case projectRepo:
|
||||||
|
suffix = ""
|
||||||
|
case buildRepo:
|
||||||
|
suffix = "-build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if project == nil {
|
||||||
|
if option, ok := optionMap["repo_name"]; ok {
|
||||||
|
str = option.StringValue()
|
||||||
|
} else {
|
||||||
|
str = ""
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
str = project.ShortName
|
||||||
|
}
|
||||||
|
|
||||||
|
if str == "" {
|
||||||
|
result = "Ты, либо в проекте репо создавай, либо имя напиши, блет!"
|
||||||
|
} else {
|
||||||
|
str = str + suffix
|
||||||
|
|
||||||
|
// var g *domain.Git
|
||||||
|
|
||||||
|
g, err := h.controller.IGit.CreateRepo(str)
|
||||||
|
if err != nil {
|
||||||
|
result = fmt.Sprintf("error while repo creation: %v", err)
|
||||||
|
} else {
|
||||||
|
result = "🚀 " + g.HtmlUrl + " was created"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := &discordgo.InteractionResponse{
|
||||||
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||||
|
Data: &discordgo.InteractionResponseData{
|
||||||
|
Content: result,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
s.InteractionRespond(i.Interaction, resp)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"ticket-pimp/internal/domain"
|
||||||
|
|
||||||
|
"github.com/bwmarrin/discordgo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h *router) CreateTicketHandler(repoNameMinLength int) route {
|
||||||
|
return route{
|
||||||
|
Command: discordgo.ApplicationCommand{
|
||||||
|
Name: "project",
|
||||||
|
Description: "Create new development ticket",
|
||||||
|
Options: []*discordgo.ApplicationCommandOption{
|
||||||
|
{
|
||||||
|
Type: discordgo.ApplicationCommandOptionString,
|
||||||
|
Name: "project_name",
|
||||||
|
Description: "Temporary project name",
|
||||||
|
Required: true,
|
||||||
|
MinLength: &repoNameMinLength,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||||
|
var result string
|
||||||
|
// Access options in the order provided by the user.
|
||||||
|
options := i.ApplicationCommandData().Options
|
||||||
|
|
||||||
|
// Or convert the slice into a map
|
||||||
|
optionMap := make(map[string]*discordgo.ApplicationCommandInteractionDataOption, len(options))
|
||||||
|
for _, opt := range options {
|
||||||
|
optionMap[opt.Name] = opt
|
||||||
|
}
|
||||||
|
|
||||||
|
if option, ok := optionMap["project_name"]; ok {
|
||||||
|
dchan, err := s.GuildChannelCreate(i.GuildID, option.StringValue(), discordgo.ChannelTypeGuildText)
|
||||||
|
if err != nil {
|
||||||
|
result = fmt.Sprintf("chan creation problem: %v\n", err)
|
||||||
|
} else {
|
||||||
|
p, err := h.controller.ProjectCreate(context.TODO(), domain.Project{
|
||||||
|
ChannelID: dchan.ID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
result = fmt.Sprintf("unable to create project: %v\n", err)
|
||||||
|
} else {
|
||||||
|
edit := discordgo.ChannelEdit{
|
||||||
|
Name: p.ShortName,
|
||||||
|
ParentID: "1150719794853716028",
|
||||||
|
}
|
||||||
|
|
||||||
|
dchan, err = s.ChannelEdit(dchan.ID, &edit)
|
||||||
|
if err != nil {
|
||||||
|
result = fmt.Sprintf("channel created, but unable to edit: %v\n", err)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_, err = s.ChannelMessageSend(dchan.ID, "Hello!")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("message send problem: %v\n", err)
|
||||||
|
}
|
||||||
|
result = dchan.ID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||||
|
// Ignore type for now, they will be discussed in "responses"
|
||||||
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||||||
|
Data: &discordgo.InteractionResponseData{
|
||||||
|
Content: result,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,7 @@
|
||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"ticket-pimp/internal/controller"
|
"ticket-pimp/internal/controller"
|
||||||
"ticket-pimp/internal/domain"
|
|
||||||
|
|
||||||
"github.com/bwmarrin/discordgo"
|
"github.com/bwmarrin/discordgo"
|
||||||
)
|
)
|
||||||
|
|
@ -21,10 +17,10 @@ func InitRouter(wc controller.WorkflowController) *router {
|
||||||
var r router
|
var r router
|
||||||
r.Routes = append(
|
r.Routes = append(
|
||||||
r.Routes,
|
r.Routes,
|
||||||
// r.CreateRepoHandler(3),
|
r.CreateRepoHandler(3),
|
||||||
r.CreateFolderHandler(3),
|
r.CreateFolderHandler(3),
|
||||||
r.Ping(),
|
r.Ping(),
|
||||||
// r.CreateTicketHandler(3),
|
r.CreateTicketHandler(3),
|
||||||
)
|
)
|
||||||
r.controller = wc
|
r.controller = wc
|
||||||
|
|
||||||
|
|
@ -35,284 +31,3 @@ type route struct {
|
||||||
Command discordgo.ApplicationCommand
|
Command discordgo.ApplicationCommand
|
||||||
Handler func(s *discordgo.Session, i *discordgo.InteractionCreate)
|
Handler func(s *discordgo.Session, i *discordgo.InteractionCreate)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *router) Ping() route {
|
|
||||||
return route{
|
|
||||||
Command: discordgo.ApplicationCommand{
|
|
||||||
Name: "ping",
|
|
||||||
Description: "pongs in a reply",
|
|
||||||
},
|
|
||||||
Handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
||||||
log.Println("ok, I'm here..")
|
|
||||||
|
|
||||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
||||||
Type: discordgo.InteractionResponseDeferredMessageUpdate,
|
|
||||||
Data: &discordgo.InteractionResponseData{
|
|
||||||
Content: "`pong`",
|
|
||||||
Title: "Pong reply",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *router) CreateFolderHandler(nameMinLenght int) route {
|
|
||||||
const (
|
|
||||||
nameOption string = "folder_name"
|
|
||||||
)
|
|
||||||
return route{
|
|
||||||
Command: discordgo.ApplicationCommand{
|
|
||||||
Name: "folder",
|
|
||||||
Description: "Command for cloud folder creation",
|
|
||||||
Options: []*discordgo.ApplicationCommandOption{
|
|
||||||
{
|
|
||||||
Type: discordgo.ApplicationCommandOptionString,
|
|
||||||
Name: nameOption,
|
|
||||||
Description: "Type the folder's name",
|
|
||||||
Required: false,
|
|
||||||
MinLength: &nameMinLenght,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
||||||
var result string
|
|
||||||
|
|
||||||
resp := discordgo.InteractionResponse{
|
|
||||||
|
|
||||||
Type: discordgo.InteractionResponseUpdateMessage,
|
|
||||||
Data: &discordgo.InteractionResponseData{
|
|
||||||
Content: "Folder is going to be created..",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
err := s.InteractionRespond(i.Interaction, &resp)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
options := i.ApplicationCommandData().Options
|
|
||||||
|
|
||||||
optionMap := make(map[string]*discordgo.ApplicationCommandInteractionDataOption, len(options))
|
|
||||||
for _, opt := range options {
|
|
||||||
optionMap[opt.Name] = opt
|
|
||||||
}
|
|
||||||
|
|
||||||
var str string = ""
|
|
||||||
|
|
||||||
project, err := h.controller.GetProjectByChannelID(context.TODO(), i.ChannelID)
|
|
||||||
if err != nil {
|
|
||||||
result = fmt.Sprintf("unable to retrieve project from db, error: %v", err)
|
|
||||||
} else {
|
|
||||||
if project == nil {
|
|
||||||
if option, ok := optionMap[nameOption]; ok {
|
|
||||||
str = option.StringValue()
|
|
||||||
} else {
|
|
||||||
str = ""
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
str = project.ShortName
|
|
||||||
}
|
|
||||||
|
|
||||||
if str == "" {
|
|
||||||
result = "Ты, либо в проекте директорию создавай, либо имя напиши, блет!"
|
|
||||||
} else {
|
|
||||||
|
|
||||||
f, err := h.controller.ICloud.CreateFolder(str)
|
|
||||||
if err != nil {
|
|
||||||
result = fmt.Sprintf("error while cloud folder creation: %v", err)
|
|
||||||
} else {
|
|
||||||
result = fmt.Sprint(f.PrivateURL)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// resp = discordgo.InteractionResponse{
|
|
||||||
// // Ignore type for now, they will be discussed in "responses"
|
|
||||||
// Type: discordgo.InteractionResponseUpdateMessage,
|
|
||||||
// Data: &discordgo.InteractionResponseData{
|
|
||||||
// Content: result,
|
|
||||||
// Title: "📂 Folder was created",
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
|
|
||||||
webhookEdit := discordgo.WebhookEdit{
|
|
||||||
Content: &result,
|
|
||||||
}
|
|
||||||
s.InteractionResponseEdit(i.Interaction, &webhookEdit)
|
|
||||||
|
|
||||||
// discerr := s.InteractionRespond(i.Interaction, &resp)
|
|
||||||
// if discerr != nil {
|
|
||||||
// log.Println(discerr)
|
|
||||||
// }
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *router) CreateRepoHandler(repoNameMinLength int) route {
|
|
||||||
const (
|
|
||||||
projectRepo = "project_repo"
|
|
||||||
buildRepo = "build_repo"
|
|
||||||
)
|
|
||||||
|
|
||||||
return route{
|
|
||||||
Command: discordgo.ApplicationCommand{
|
|
||||||
Name: "repo",
|
|
||||||
Description: "Command for repository creation",
|
|
||||||
Options: []*discordgo.ApplicationCommandOption{
|
|
||||||
{
|
|
||||||
Type: discordgo.ApplicationCommandOptionString,
|
|
||||||
Name: "repo_type",
|
|
||||||
Description: "The type of repo",
|
|
||||||
Required: true,
|
|
||||||
Choices: []*discordgo.ApplicationCommandOptionChoice{
|
|
||||||
{
|
|
||||||
Name: "Unity project repo",
|
|
||||||
Value: projectRepo,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "XCode build repo",
|
|
||||||
Value: buildRepo,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: discordgo.ApplicationCommandOptionString,
|
|
||||||
Name: "repo_name",
|
|
||||||
Description: "Type the repository's name",
|
|
||||||
Required: false,
|
|
||||||
MinLength: &repoNameMinLength,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
||||||
var result string
|
|
||||||
// Access options in the order provided by the user.
|
|
||||||
options := i.ApplicationCommandData().Options
|
|
||||||
|
|
||||||
// Or convert the slice into a map
|
|
||||||
optionMap := make(map[string]*discordgo.ApplicationCommandInteractionDataOption, len(options))
|
|
||||||
for _, opt := range options {
|
|
||||||
optionMap[opt.Name] = opt
|
|
||||||
}
|
|
||||||
|
|
||||||
var str string = ""
|
|
||||||
|
|
||||||
project, err := h.controller.GetProjectByChannelID(context.TODO(), i.ChannelID)
|
|
||||||
if err != nil {
|
|
||||||
result = fmt.Sprintf("unable to retrieve project from db, error: %v", err)
|
|
||||||
} else {
|
|
||||||
var suffix string
|
|
||||||
if option, ok := optionMap["repo_type"]; ok {
|
|
||||||
switch option.Value {
|
|
||||||
case projectRepo:
|
|
||||||
suffix = ""
|
|
||||||
case buildRepo:
|
|
||||||
suffix = "-build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if project == nil {
|
|
||||||
if option, ok := optionMap["repo_name"]; ok {
|
|
||||||
str = option.StringValue()
|
|
||||||
} else {
|
|
||||||
str = ""
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
str = project.ShortName
|
|
||||||
}
|
|
||||||
|
|
||||||
if str == "" {
|
|
||||||
result = "Ты, либо в проекте репо создавай, либо имя напиши, блет!"
|
|
||||||
} else {
|
|
||||||
str = str + suffix
|
|
||||||
|
|
||||||
// var g *domain.Git
|
|
||||||
|
|
||||||
g, err := h.controller.IGit.CreateRepo(str)
|
|
||||||
if err != nil {
|
|
||||||
result = fmt.Sprintf("error while repo creation: %v", err)
|
|
||||||
} else {
|
|
||||||
result = "🚀 " + g.HtmlUrl + " was created"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resp := &discordgo.InteractionResponse{
|
|
||||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
||||||
Data: &discordgo.InteractionResponseData{
|
|
||||||
Content: result,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
s.InteractionRespond(i.Interaction, resp)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *router) CreateTicketHandler(repoNameMinLength int) route {
|
|
||||||
return route{
|
|
||||||
Command: discordgo.ApplicationCommand{
|
|
||||||
Name: "project",
|
|
||||||
Description: "Create new development ticket",
|
|
||||||
Options: []*discordgo.ApplicationCommandOption{
|
|
||||||
{
|
|
||||||
Type: discordgo.ApplicationCommandOptionString,
|
|
||||||
Name: "project_name",
|
|
||||||
Description: "Temporary project name",
|
|
||||||
Required: true,
|
|
||||||
MinLength: &repoNameMinLength,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Handler: func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|
||||||
var result string
|
|
||||||
// Access options in the order provided by the user.
|
|
||||||
options := i.ApplicationCommandData().Options
|
|
||||||
|
|
||||||
// Or convert the slice into a map
|
|
||||||
optionMap := make(map[string]*discordgo.ApplicationCommandInteractionDataOption, len(options))
|
|
||||||
for _, opt := range options {
|
|
||||||
optionMap[opt.Name] = opt
|
|
||||||
}
|
|
||||||
|
|
||||||
if option, ok := optionMap["project_name"]; ok {
|
|
||||||
dchan, err := s.GuildChannelCreate(i.GuildID, option.StringValue(), discordgo.ChannelTypeGuildText)
|
|
||||||
if err != nil {
|
|
||||||
result = fmt.Sprintf("chan creation problem: %v\n", err)
|
|
||||||
} else {
|
|
||||||
p, err := h.controller.ProjectCreate(context.TODO(), domain.Project{
|
|
||||||
ChannelID: dchan.ID,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
result = fmt.Sprintf("unable to create project: %v\n", err)
|
|
||||||
} else {
|
|
||||||
edit := discordgo.ChannelEdit{
|
|
||||||
Name: p.ShortName,
|
|
||||||
ParentID: "1150719794853716028",
|
|
||||||
}
|
|
||||||
|
|
||||||
dchan, err = s.ChannelEdit(dchan.ID, &edit)
|
|
||||||
if err != nil {
|
|
||||||
result = fmt.Sprintf("channel created, but unable to edit: %v\n", err)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
_, err = s.ChannelMessageSend(dchan.ID, "Hello!")
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("message send problem: %v\n", err)
|
|
||||||
}
|
|
||||||
result = dchan.ID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
|
||||||
// Ignore type for now, they will be discussed in "responses"
|
|
||||||
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
|
||||||
Data: &discordgo.InteractionResponseData{
|
|
||||||
Content: result,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,8 @@ func (wc *WorkflowController) FullProjectInit(name, key, id string) (string, err
|
||||||
|
|
||||||
go func(ref **domain.Folder) {
|
go func(ref **domain.Folder) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
*ref, _ = wc.ICloud.CreateFolder(appKey)
|
|
||||||
|
*ref = wc.ICloud.CreateFolder(appKey).Folder
|
||||||
}(&cloud)
|
}(&cloud)
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package helpers
|
||||||
|
|
||||||
|
type ErrorMessage struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GitNaming(input string) string {
|
func ValidNaming(input string) string {
|
||||||
// Remove leading and trailing whitespace
|
// Remove leading and trailing whitespace
|
||||||
input = strings.TrimSpace(input)
|
input = strings.TrimSpace(input)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ var tests = []test{
|
||||||
func TestGitNaming(t *testing.T) {
|
func TestGitNaming(t *testing.T) {
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
if output := GitNaming(test.arg); output != test.expected {
|
if output := ValidNaming(test.arg); output != test.expected {
|
||||||
t.Errorf("Output %q not equal to expected %q", output, test.expected)
|
t.Errorf("Output %q not equal to expected %q", output, test.expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@ package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"ticket-pimp/internal/domain"
|
"ticket-pimp/internal/domain"
|
||||||
"ticket-pimp/internal/helpers"
|
"ticket-pimp/internal/helpers"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -14,7 +16,7 @@ type Cloud struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ICloud interface {
|
type ICloud interface {
|
||||||
CreateFolder(name string) (*domain.Folder, error)
|
CreateFolder(name string) Response
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCloud(conf domain.CloudConfig) *Cloud {
|
func NewCloud(conf domain.CloudConfig) *Cloud {
|
||||||
|
|
@ -32,40 +34,76 @@ func NewCloud(conf domain.CloudConfig) *Cloud {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cloud) CreateFolder(name string) (*domain.Folder, error) {
|
type Response struct {
|
||||||
|
Folder *domain.Folder
|
||||||
|
ErrMessage error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cloud) CreateFolder(name string) Response {
|
||||||
|
var R Response
|
||||||
|
|
||||||
rootDir := c.Config.RootDir
|
rootDir := c.Config.RootDir
|
||||||
user := c.Config.User
|
user := c.Config.User
|
||||||
|
|
||||||
davPath := "/remote.php/dav/files/"
|
davPath := "/remote.php/dav/files/"
|
||||||
parentPath := "/apps/files/?dir="
|
parentPath := "/apps/files/?dir="
|
||||||
|
|
||||||
name = helpers.GitNaming(name)
|
name = helpers.ValidNaming(name)
|
||||||
|
|
||||||
cloud := domain.Folder{
|
R.Folder = &domain.Folder{
|
||||||
Title: name,
|
Title: name,
|
||||||
PrivateURL: "",
|
PrivateURL: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cloud := domain.Folder{
|
||||||
|
// Title: name,
|
||||||
|
// PrivateURL: "",
|
||||||
|
// }
|
||||||
|
|
||||||
requestPath := davPath + user + rootDir + name
|
requestPath := davPath + user + rootDir + name
|
||||||
|
|
||||||
cloud.PathTo = parentPath + rootDir + name
|
R.Folder.PathTo = parentPath + rootDir + name
|
||||||
|
|
||||||
resp, _ := c.R().
|
var errMessage helpers.ErrorMessage
|
||||||
|
|
||||||
|
resp, err := c.R().
|
||||||
|
SetErrorResult(&errMessage).
|
||||||
Send("MKCOL", requestPath)
|
Send("MKCOL", requestPath)
|
||||||
|
|
||||||
|
if err != nil { // Error handling.
|
||||||
|
log.Println("error:", err)
|
||||||
|
|
||||||
|
// Херовая обработка ошибки:
|
||||||
|
// error while cloud folder creation: bad response, raw content:
|
||||||
|
// <?xml version="1.0" encoding="utf-8"?>
|
||||||
|
// <d:error xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
|
||||||
|
// <s:exception>Sabre\DAV\Exception\MethodNotAllowed</s:exception>
|
||||||
|
// <s:message>The resource you tried to create already exists</s:message>
|
||||||
|
// </d:error>
|
||||||
|
if strings.Contains(err.Error(), "already exists") {
|
||||||
|
R.Folder.PrivateURL = c.BaseURL + R.Folder.PathTo
|
||||||
|
R.ErrMessage = err
|
||||||
|
// Try to set short URL to the d entity
|
||||||
|
if err := c.setPrivateURL(requestPath, R.Folder); err != nil {
|
||||||
|
R.ErrMessage = err
|
||||||
|
return R
|
||||||
|
}
|
||||||
|
return R
|
||||||
|
}
|
||||||
|
return R
|
||||||
|
}
|
||||||
|
|
||||||
if resp.IsSuccessState() {
|
if resp.IsSuccessState() {
|
||||||
// Set stupid URL to the d entity
|
// Set stupid URL to the d entity
|
||||||
cloud.PrivateURL = c.BaseURL + cloud.PathTo
|
R.Folder.PrivateURL = c.BaseURL + R.Folder.PathTo
|
||||||
|
|
||||||
// Try to set short URL to the d entity
|
// Try to set short URL to the d entity
|
||||||
if err := c.setPrivateURL(requestPath, &cloud); err != nil {
|
if err := c.setPrivateURL(requestPath, R.Folder); err != nil {
|
||||||
return &cloud, err
|
return R
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
fmt.Println(resp.Status)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &cloud, nil
|
return R
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cloud) setPrivateURL(requestPath string, cloud *domain.Folder) error {
|
func (c *Cloud) setPrivateURL(requestPath string, cloud *domain.Folder) error {
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ type gitCreateRequest struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gb *Git) newRepo(name string) (*domain.Git, error) {
|
func (gb *Git) newRepo(name string) (*domain.Git, error) {
|
||||||
name = helpers.GitNaming(name)
|
name = helpers.ValidNaming(name)
|
||||||
|
|
||||||
payload := gitCreateRequest{
|
payload := gitCreateRequest{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,10 @@ func (h *Handler) NewFolderHandler(ctx context.Context, mu *tgb.MessageUpdate) e
|
||||||
return errors.New("empty command provided")
|
return errors.New("empty command provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
cloud, err := h.cloud.CreateFolder(str)
|
resp := h.cloud.CreateFolder(str)
|
||||||
|
|
||||||
if err != nil {
|
if resp.ErrMessage != nil {
|
||||||
answer := errorAnswer(err.Error())
|
answer := errorAnswer(resp.ErrMessage.Error())
|
||||||
h.LogMessage(ctx, mu, answer)
|
h.LogMessage(ctx, mu, answer)
|
||||||
return mu.Answer(answer).ParseMode(tg.HTML).DoVoid(ctx)
|
return mu.Answer(answer).ParseMode(tg.HTML).DoVoid(ctx)
|
||||||
}
|
}
|
||||||
|
|
@ -28,7 +28,7 @@ func (h *Handler) NewFolderHandler(ctx context.Context, mu *tgb.MessageUpdate) e
|
||||||
answer := tg.HTML.Text(
|
answer := tg.HTML.Text(
|
||||||
tg.HTML.Line(
|
tg.HTML.Line(
|
||||||
"✨ Shiny folder",
|
"✨ Shiny folder",
|
||||||
tg.HTML.Link(cloud.Title, cloud.PrivateURL),
|
tg.HTML.Link(resp.Folder.Title, resp.Folder.PrivateURL),
|
||||||
"has been created!",
|
"has been created!",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ func Run(ctx context.Context, opts TelegramOptions) error {
|
||||||
// Message(h.NewFolderHandler, tgb.TextHasPrefix("/folder")).
|
// Message(h.NewFolderHandler, tgb.TextHasPrefix("/folder")).
|
||||||
Message(h.FarmTaskHandler, tgb.TextHasPrefix("/task"))
|
Message(h.FarmTaskHandler, tgb.TextHasPrefix("/task"))
|
||||||
|
|
||||||
|
log.Print("Success init. Start poller.")
|
||||||
return tgb.NewPoller(
|
return tgb.NewPoller(
|
||||||
router,
|
router,
|
||||||
client,
|
client,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue