Compare commits
No commits in common. "3af1726c1d7ace70548c9c59d945b67fc4f9bc47" and "2be4b1dfd426c09a5d2b7bae894a3fa76a10d5f5" have entirely different histories.
3af1726c1d
...
2be4b1dfd4
|
|
@ -0,0 +1,31 @@
|
||||||
|
name: Build and Publish Docker Container
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
|
||||||
|
- name: Login to GitHub Container Registry
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ secrets.GITHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: ghcr.io/${{ github.repository }}/my-docker-container:latest
|
||||||
|
|
@ -16,11 +16,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// minLength int = 3
|
minLength int = 3
|
||||||
// repoType string = "repo_type"
|
repoType string = "repo_type"
|
||||||
// projectRepo string = "project_repo"
|
projectRepo string = "project_repo"
|
||||||
// buildRepo string = "build_repo"
|
buildRepo string = "build_repo"
|
||||||
// nameOption string = "name"
|
nameOption string = "name"
|
||||||
tagsPreset = [3]discordgo.ForumTag{
|
tagsPreset = [3]discordgo.ForumTag{
|
||||||
{
|
{
|
||||||
Name: "В работе",
|
Name: "В работе",
|
||||||
|
|
@ -38,89 +38,88 @@ var (
|
||||||
EmojiName: "🚧",
|
EmojiName: "🚧",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
commands = []discordgo.ApplicationCommand{
|
||||||
// commands = []discordgo.ApplicationCommand{
|
{
|
||||||
// {
|
Name: "ping",
|
||||||
// Name: "ping",
|
Description: "pongs in a reply",
|
||||||
// Description: "pongs in a reply",
|
},
|
||||||
// },
|
{
|
||||||
// {
|
Name: "coda_ticket",
|
||||||
// Name: "coda_ticket",
|
Description: "Creates ticket in Coda.io w/ provided info",
|
||||||
// Description: "Creates ticket in Coda.io w/ provided info",
|
},
|
||||||
// },
|
{
|
||||||
// {
|
Name: "init_project",
|
||||||
// Name: "init_project",
|
Description: "Connect project with Coda ID",
|
||||||
// Description: "Connect project with Coda ID",
|
Options: []*discordgo.ApplicationCommandOption{
|
||||||
// Options: []*discordgo.ApplicationCommandOption{
|
{
|
||||||
// {
|
Type: discordgo.ApplicationCommandOptionString,
|
||||||
// Type: discordgo.ApplicationCommandOptionString,
|
Name: "key",
|
||||||
// Name: "key",
|
Description: "Project's key from Coda.io",
|
||||||
// Description: "Project's key from Coda.io",
|
Required: true,
|
||||||
// Required: true,
|
MinLength: &minLength,
|
||||||
// MinLength: &minLength,
|
},
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
// },
|
{
|
||||||
// {
|
Name: "project",
|
||||||
// Name: "project",
|
Description: "Create new development ticket",
|
||||||
// Description: "Create new development ticket",
|
Options: []*discordgo.ApplicationCommandOption{
|
||||||
// Options: []*discordgo.ApplicationCommandOption{
|
{
|
||||||
// {
|
Type: discordgo.ApplicationCommandOptionString,
|
||||||
// Type: discordgo.ApplicationCommandOptionString,
|
Name: "project_name",
|
||||||
// Name: "project_name",
|
Description: "Temporary project name",
|
||||||
// Description: "Temporary project name",
|
Required: true,
|
||||||
// Required: true,
|
MinLength: &minLength,
|
||||||
// MinLength: &minLength,
|
},
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
// },
|
{
|
||||||
// {
|
Name: "info",
|
||||||
// Name: "info",
|
Description: "Get project's info",
|
||||||
// Description: "Get project's info",
|
},
|
||||||
// },
|
{
|
||||||
// {
|
Name: "repo",
|
||||||
// Name: "repo",
|
Description: "Creates repository of selected type. Name used for projects channels only",
|
||||||
// Description: "Creates repository of selected type. Name used for projects channels only",
|
Options: []*discordgo.ApplicationCommandOption{
|
||||||
// Options: []*discordgo.ApplicationCommandOption{
|
{
|
||||||
// {
|
Type: discordgo.ApplicationCommandOptionString,
|
||||||
// Type: discordgo.ApplicationCommandOptionString,
|
Name: repoType,
|
||||||
// Name: repoType,
|
Description: "The type of repo",
|
||||||
// Description: "The type of repo",
|
Required: true,
|
||||||
// Required: true,
|
Choices: []*discordgo.ApplicationCommandOptionChoice{
|
||||||
// Choices: []*discordgo.ApplicationCommandOptionChoice{
|
{
|
||||||
// {
|
Name: "Unity project repo",
|
||||||
// Name: "Unity project repo",
|
Value: projectRepo,
|
||||||
// Value: projectRepo,
|
},
|
||||||
// },
|
{
|
||||||
// {
|
Name: "XCode build repo",
|
||||||
// Name: "XCode build repo",
|
Value: buildRepo,
|
||||||
// Value: buildRepo,
|
},
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
// },
|
{
|
||||||
// {
|
Type: discordgo.ApplicationCommandOptionString,
|
||||||
// Type: discordgo.ApplicationCommandOptionString,
|
Name: nameOption,
|
||||||
// Name: nameOption,
|
Description: "Type the repository's name",
|
||||||
// Description: "Type the repository's name",
|
Required: false,
|
||||||
// Required: false,
|
MinLength: &minLength,
|
||||||
// MinLength: &minLength,
|
},
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
// },
|
{
|
||||||
// {
|
Name: "folder",
|
||||||
// Name: "folder",
|
Description: "Command for cloud folder creation",
|
||||||
// Description: "Command for cloud folder creation",
|
Options: []*discordgo.ApplicationCommandOption{
|
||||||
// Options: []*discordgo.ApplicationCommandOption{
|
{
|
||||||
// {
|
Type: discordgo.ApplicationCommandOptionString,
|
||||||
// Type: discordgo.ApplicationCommandOptionString,
|
Name: nameOption,
|
||||||
// Name: nameOption,
|
Description: "Type the folder's name",
|
||||||
// Description: "Type the folder's name",
|
Required: false,
|
||||||
// Required: false,
|
MinLength: &minLength,
|
||||||
// MinLength: &minLength,
|
},
|
||||||
// },
|
},
|
||||||
// },
|
},
|
||||||
// },
|
}
|
||||||
// }
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func initBotWith(token string) *discordgo.Session {
|
func initBotWith(token string) *discordgo.Session {
|
||||||
|
|
@ -196,43 +195,20 @@ func updateForum(conf *domain.Config, s *discordgo.Session) ([]discordgo.ForumTa
|
||||||
return dchan.AvailableTags, nil
|
return dchan.AvailableTags, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// commandRegistration
|
func commandRegistration(s *discordgo.Session, commands []discordgo.ApplicationCommand) []*discordgo.ApplicationCommand {
|
||||||
// unused, cause method was deprecated;
|
log.Println("Adding commands...")
|
||||||
// func commandRegistration(s *discordgo.Session, commands []discordgo.ApplicationCommand) []*discordgo.ApplicationCommand {
|
var cmds []*discordgo.ApplicationCommand
|
||||||
// oldCommands, err := s.ApplicationCommands(s.State.User.ID, s.State.Application.GuildID)
|
for _, cmd := range commands {
|
||||||
// if err != nil {
|
cmd, err := s.ApplicationCommandCreate(s.State.User.ID, "", &cmd)
|
||||||
// log.Panicf("Cannot get old commands: %v", err)
|
if err != nil {
|
||||||
// }
|
log.Panicf("Cannot create '%v' command: %v", cmd.Name, err)
|
||||||
|
}
|
||||||
|
cmds = append(cmds, cmd)
|
||||||
|
log.Println(cmd.Name + " command added")
|
||||||
|
}
|
||||||
|
return cmds
|
||||||
|
}
|
||||||
|
|
||||||
// var removedCommands []string
|
|
||||||
// for _, cmd := range oldCommands {
|
|
||||||
// err := s.ApplicationCommandDelete(s.State.User.ID, s.State.Application.GuildID, cmd.ID)
|
|
||||||
// if err != nil {
|
|
||||||
// log.Printf("commands removed: %v", removedCommands)
|
|
||||||
// log.Panicf("removing old comands failed with %s command, err: %v", cmd.Name, err)
|
|
||||||
// }
|
|
||||||
// removedCommands = append(removedCommands, cmd.Name)
|
|
||||||
// }
|
|
||||||
// log.Printf("commands removed: %v", removedCommands)
|
|
||||||
|
|
||||||
// log.Println("Adding commands...")
|
|
||||||
// var cmds []*discordgo.ApplicationCommand
|
|
||||||
// for _, cmd := range commands {
|
|
||||||
// cmd, err := s.ApplicationCommandCreate(s.State.User.ID, "", &cmd)
|
|
||||||
// if err != nil {
|
|
||||||
// log.Panicf("Cannot create '%v' command: %v", cmd.Name, err)
|
|
||||||
// }
|
|
||||||
// cmds = append(cmds, cmd)
|
|
||||||
// log.Println(cmd.Name + " command added")
|
|
||||||
// }
|
|
||||||
// return cmds
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Run - метод
|
|
||||||
//
|
|
||||||
// 1. Инициализирует бота Discord, создаёт некоторое подобие роутера
|
|
||||||
// 2. Объявляет доступные роутинги
|
|
||||||
// 3. Объявляет доступные для роутов хэндлеры
|
|
||||||
func Run(conf *domain.Config, opts DiscordOptions) error {
|
func Run(conf *domain.Config, opts DiscordOptions) error {
|
||||||
|
|
||||||
// bot init
|
// bot init
|
||||||
|
|
@ -247,25 +223,23 @@ func Run(conf *domain.Config, opts DiscordOptions) error {
|
||||||
|
|
||||||
r := discord_router.NewApp(s)
|
r := discord_router.NewApp(s)
|
||||||
|
|
||||||
// Depretated
|
var commonMw = []discord_router.Middleware{
|
||||||
// var commonMw = []discord_router.Middleware{
|
h.WithInitialResponse,
|
||||||
// h.WithInitialResponse,
|
h.RejectPM,
|
||||||
// h.RejectPM,
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// Depretated
|
// Handle commands
|
||||||
// r.Use(commonMw...).
|
r.
|
||||||
// Route("ping", h.Ping).
|
Route("ping", r.Wrapped(h.Ping, commonMw...)).
|
||||||
// Route("project", h.CreateProject).
|
Route("project", r.Wrapped(h.CreateProject, commonMw...)).
|
||||||
// Route("info", h.ProjectInfo).
|
Route("info", r.Wrapped(h.ProjectInfo, commonMw...)).
|
||||||
// Route("repo", h.CreateGit).
|
Route("repo", r.Wrapped(h.CreateGit, commonMw...)).
|
||||||
// Route("folder", h.CreateFolder).
|
Route("folder", r.Wrapped(h.CreateFolder, commonMw...)).
|
||||||
// Route("init_project", h.InitChannelAsProject).
|
Route("init_project", r.Wrapped(h.InitChannelAsProject, commonMw...)).
|
||||||
// Route("coda_ticket", h.CreateCoda)
|
Route("coda_ticket", r.Wrapped(h.CreateCoda, commonMw...))
|
||||||
|
|
||||||
// and components
|
// Handle components
|
||||||
r.
|
r.
|
||||||
/*Use().*/ // Combining into group duplicates replies
|
|
||||||
Route("task_start", h.HandleTaskButtons).
|
Route("task_start", h.HandleTaskButtons).
|
||||||
Route("task_close", h.HandleTaskButtons)
|
Route("task_close", h.HandleTaskButtons)
|
||||||
|
|
||||||
|
|
@ -290,7 +264,7 @@ func Run(conf *domain.Config, opts DiscordOptions) error {
|
||||||
h.SetAvailableTags(tags)
|
h.SetAvailableTags(tags)
|
||||||
|
|
||||||
// commands registration
|
// commands registration
|
||||||
// cmds := commandRegistration(s, commands)
|
cmds := commandRegistration(s, commands)
|
||||||
|
|
||||||
// gracefull shutdown
|
// gracefull shutdown
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
@ -299,12 +273,12 @@ func Run(conf *domain.Config, opts DiscordOptions) error {
|
||||||
<-stop
|
<-stop
|
||||||
log.Println("Graceful shutdown")
|
log.Println("Graceful shutdown")
|
||||||
|
|
||||||
// log.Println("Removing commands...")
|
log.Println("Removing commands...")
|
||||||
// for _, h := range cmds {
|
for _, h := range cmds {
|
||||||
// err := s.ApplicationCommandDelete(s.State.User.ID, "", h.ID)
|
err := s.ApplicationCommandDelete(s.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)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"ticket-pimp/adapters"
|
"ticket-pimp/adapters"
|
||||||
router "ticket-pimp/client/discord/discord_router"
|
"ticket-pimp/client/discord/discord_router"
|
||||||
"ticket-pimp/internal/controller"
|
"ticket-pimp/internal/controller"
|
||||||
"ticket-pimp/internal/domain"
|
"ticket-pimp/internal/domain"
|
||||||
"ticket-pimp/internal/helpers"
|
"ticket-pimp/internal/helpers"
|
||||||
|
|
@ -32,7 +32,7 @@ func New(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) RejectPM(f router.HandlerFunc) router.HandlerFunc {
|
func (h *Handler) RejectPM(f discord_router.HandlerFunc) discord_router.HandlerFunc {
|
||||||
return func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
return func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||||
|
|
||||||
dchan, err := s.Channel(i.ChannelID)
|
dchan, err := s.Channel(i.ChannelID)
|
||||||
|
|
@ -75,7 +75,7 @@ func respondWithReject(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Моментальный ответ для избежания столкновения с протуханием токена
|
// Моментальный ответ для избежания столкновения с протуханием токена
|
||||||
func (h *Handler) WithInitialResponse(f router.HandlerFunc) router.HandlerFunc {
|
func (h *Handler) WithInitialResponse(f discord_router.HandlerFunc) discord_router.HandlerFunc {
|
||||||
return func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
return func(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||||
|
|
||||||
initialResponse := discordgo.InteractionResponse{
|
initialResponse := discordgo.InteractionResponse{
|
||||||
|
|
@ -119,9 +119,10 @@ func (h *Handler) Ping(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListenPosts
|
// ListenPosts
|
||||||
//
|
/*
|
||||||
// ..listens to new posts in specific channel
|
..listens to new posts in specific channel
|
||||||
// to act them like a task
|
to act them like a task
|
||||||
|
*/
|
||||||
func (h *Handler) ListenPosts(s *discordgo.Session, th *discordgo.ThreadCreate) {
|
func (h *Handler) ListenPosts(s *discordgo.Session, th *discordgo.ThreadCreate) {
|
||||||
|
|
||||||
// Check if thread starter is not a bot, and thread started at the tasks channel;
|
// Check if thread starter is not a bot, and thread started at the tasks channel;
|
||||||
|
|
@ -132,12 +133,6 @@ func (h *Handler) ListenPosts(s *discordgo.Session, th *discordgo.ThreadCreate)
|
||||||
// Get all messages from the channel:
|
// Get all messages from the channel:
|
||||||
msgs, _ := s.ChannelMessages(th.ID, 1, "", "", "")
|
msgs, _ := s.ChannelMessages(th.ID, 1, "", "", "")
|
||||||
|
|
||||||
if len(msgs) == 0 {
|
|
||||||
log.Println("msgs are empty")
|
|
||||||
s.ChannelMessageSend(th.ID, "чет пошло не так, пингани @naudachu плиз")
|
|
||||||
return
|
|
||||||
|
|
||||||
}
|
|
||||||
// Take the first one:
|
// Take the first one:
|
||||||
msg, _ := s.ChannelMessage(th.ID, msgs[0].ID)
|
msg, _ := s.ChannelMessage(th.ID, msgs[0].ID)
|
||||||
|
|
||||||
|
|
@ -183,24 +178,12 @@ func (h *Handler) ListenPosts(s *discordgo.Session, th *discordgo.ThreadCreate)
|
||||||
Label: "Start",
|
Label: "Start",
|
||||||
Style: discordgo.SuccessButton,
|
Style: discordgo.SuccessButton,
|
||||||
Disabled: false,
|
Disabled: false,
|
||||||
Emoji: discordgo.ComponentEmoji{
|
|
||||||
Name: "🚀",
|
|
||||||
ID: "",
|
|
||||||
Animated: false,
|
|
||||||
},
|
|
||||||
URL: "",
|
|
||||||
CustomID: "task_start",
|
CustomID: "task_start",
|
||||||
},
|
},
|
||||||
discordgo.Button{
|
discordgo.Button{
|
||||||
Label: "Close",
|
Label: "Close",
|
||||||
Style: discordgo.DangerButton,
|
Style: discordgo.DangerButton,
|
||||||
Disabled: true,
|
Disabled: true,
|
||||||
Emoji: discordgo.ComponentEmoji{
|
|
||||||
Name: "🍀",
|
|
||||||
ID: "",
|
|
||||||
Animated: false,
|
|
||||||
},
|
|
||||||
URL: "",
|
|
||||||
CustomID: "task_close",
|
CustomID: "task_close",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -208,7 +191,7 @@ func (h *Handler) ListenPosts(s *discordgo.Session, th *discordgo.ThreadCreate)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("th start message edition is not complete: %v", err) // todo return error. Error causes panics into next method;
|
log.Printf("th start message edition is not complete: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = h.controller.UpdateTasksMessageID(context.TODO(), taskMessage.ID, t.ID)
|
err = h.controller.UpdateTasksMessageID(context.TODO(), taskMessage.ID, t.ID)
|
||||||
|
|
@ -295,12 +278,6 @@ func (h *Handler) HandleTaskButtons(s *discordgo.Session, i *discordgo.Interacti
|
||||||
Label: "Close",
|
Label: "Close",
|
||||||
Style: discordgo.DangerButton,
|
Style: discordgo.DangerButton,
|
||||||
Disabled: doneButtonIsDisabled,
|
Disabled: doneButtonIsDisabled,
|
||||||
Emoji: discordgo.ComponentEmoji{
|
|
||||||
Name: "🍀",
|
|
||||||
ID: "",
|
|
||||||
Animated: false,
|
|
||||||
},
|
|
||||||
URL: "",
|
|
||||||
CustomID: "task_close",
|
CustomID: "task_close",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -318,9 +295,10 @@ func (h *Handler) HandleTaskButtons(s *discordgo.Session, i *discordgo.Interacti
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateFolder
|
// CreateFolder
|
||||||
//
|
/*
|
||||||
// - creates project's cloud folder;
|
- creates project's cloud folder;
|
||||||
// - writed folder link to db;
|
- writed folder link to db;
|
||||||
|
*/
|
||||||
func (h *Handler) CreateFolder(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
func (h *Handler) CreateFolder(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||||
const (
|
const (
|
||||||
nameOption string = "folder_name"
|
nameOption string = "folder_name"
|
||||||
|
|
@ -351,14 +329,14 @@ func (h *Handler) CreateFolder(s *discordgo.Session, i *discordgo.InteractionCre
|
||||||
// Creating request:
|
// Creating request:
|
||||||
var req controller.FolderRequest
|
var req controller.FolderRequest
|
||||||
name, insertedValueNotNil := optionMap[nameOption]
|
name, insertedValueNotNil := optionMap[nameOption]
|
||||||
currentChannel, err := s.Channel(i.ChannelID)
|
dchan, err := s.Channel(i.ChannelID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error while identifying channel: %v", err)
|
log.Printf("error while identifying channel: %v", err)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if currentChannel.ParentID == h.conf.IsProjectChannel {
|
if dchan.ParentID == h.conf.IsProjectChannel {
|
||||||
req.ChannelID = currentChannel.ID
|
req.ChannelID = dchan.ID
|
||||||
if insertedValueNotNil {
|
if insertedValueNotNil {
|
||||||
req.InsertedName = name.StringValue()
|
req.InsertedName = name.StringValue()
|
||||||
}
|
}
|
||||||
|
|
@ -611,16 +589,10 @@ func (h *Handler) CreateProject(s *discordgo.Session, i *discordgo.InteractionCr
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
parent, err := s.Channel(h.conf.IsProjectChannel)
|
// Edit created channel:
|
||||||
if err != nil {
|
|
||||||
log.Printf("get project as channel object failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Edit created channel (new key needed, so use to make edit after creation)
|
|
||||||
edit := discordgo.ChannelEdit{
|
edit := discordgo.ChannelEdit{
|
||||||
Name: p.Key + "-" + helpers.Cut(projectTitle),
|
Name: p.Key + "-" + helpers.Cut(projectTitle),
|
||||||
ParentID: h.conf.IsProjectChannel,
|
ParentID: h.conf.IsProjectChannel,
|
||||||
PermissionOverwrites: parent.PermissionOverwrites,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dchan, err = s.ChannelEdit(dchan.ID, &edit)
|
dchan, err = s.ChannelEdit(dchan.ID, &edit)
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ func (re *RouteEntry) Match(i *discordgo.InteractionCreate) bool {
|
||||||
type Router struct {
|
type Router struct {
|
||||||
session *discordgo.Session
|
session *discordgo.Session
|
||||||
routes []RouteEntry
|
routes []RouteEntry
|
||||||
group []Group
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewApp(s *discordgo.Session) *Router {
|
func NewApp(s *discordgo.Session) *Router {
|
||||||
|
|
@ -53,49 +52,23 @@ func (r *Router) Serve(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||||
e.Handler(s, i)
|
e.Handler(s, i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//[ ] Is there something like 404?!
|
||||||
for _, g := range r.group {
|
|
||||||
for _, e := range g.routes {
|
|
||||||
ok := e.Match(i)
|
|
||||||
if ok {
|
|
||||||
if len(g.middleware) < 1 {
|
|
||||||
e.Handler(s, i)
|
|
||||||
}
|
|
||||||
|
|
||||||
wrapped := e.Handler
|
|
||||||
|
|
||||||
// loop in reverse to preserve middleware order
|
|
||||||
for i := len(g.middleware) - 1; i >= 0; i-- {
|
|
||||||
wrapped = g.middleware[i](wrapped)
|
|
||||||
}
|
|
||||||
wrapped(s, i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Middleware func(HandlerFunc) HandlerFunc
|
type Middleware func(HandlerFunc) HandlerFunc
|
||||||
|
|
||||||
type Group struct {
|
func (r *Router) Wrapped(f HandlerFunc, m ...Middleware) HandlerFunc {
|
||||||
routes []RouteEntry
|
|
||||||
middleware []Middleware
|
if len(m) < 1 {
|
||||||
}
|
return f
|
||||||
|
}
|
||||||
func (r *Router) Use(m ...Middleware) *Group {
|
|
||||||
|
wrapped := f
|
||||||
r.group = append(r.group, Group{
|
|
||||||
routes: []RouteEntry{},
|
// loop in reverse to preserve middleware order
|
||||||
middleware: m,
|
for i := len(m) - 1; i >= 0; i-- {
|
||||||
})
|
wrapped = m[i](wrapped)
|
||||||
|
}
|
||||||
return &r.group[len(r.group)-1]
|
|
||||||
}
|
return wrapped
|
||||||
|
|
||||||
func (g *Group) Route(cmd string, handlerFunc HandlerFunc) *Group {
|
|
||||||
|
|
||||||
g.routes = append(g.routes, RouteEntry{
|
|
||||||
CommandName: cmd,
|
|
||||||
Handler: handlerFunc,
|
|
||||||
})
|
|
||||||
return g
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"ticket-pimp/internal/domain"
|
"ticket-pimp/internal/domain"
|
||||||
)
|
)
|
||||||
|
|
@ -14,10 +13,6 @@ func (wc *WorkflowController) CreateCoda(guildID string, chanID string) (string,
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if p == nil {
|
|
||||||
return "", errors.New("project wasn't found in the db")
|
|
||||||
}
|
|
||||||
|
|
||||||
requestResult, err := wc.ICoda.CreateApp(domain.CodaApplication{
|
requestResult, err := wc.ICoda.CreateApp(domain.CodaApplication{
|
||||||
ID: p.Key,
|
ID: p.Key,
|
||||||
Summary: p.Name,
|
Summary: p.Name,
|
||||||
|
|
@ -28,4 +23,5 @@ func (wc *WorkflowController) CreateCoda(guildID string, chanID string) (string,
|
||||||
})
|
})
|
||||||
|
|
||||||
return requestResult, err
|
return requestResult, err
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,6 @@ import (
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Get - *not used*
|
|
||||||
//
|
|
||||||
// Достаёт запись из таблицы config
|
|
||||||
// config - ключ приложений и номер последнего созданного приложения (// todo или следующего?)
|
|
||||||
func (wc *WorkflowController) Get(ctx context.Context) (*domain.ApplicationConfig, error) {
|
func (wc *WorkflowController) Get(ctx context.Context) (*domain.ApplicationConfig, error) {
|
||||||
c, err := wc.q.GetConfig(ctx)
|
c, err := wc.q.GetConfig(ctx)
|
||||||
return &domain.ApplicationConfig{
|
return &domain.ApplicationConfig{
|
||||||
|
|
@ -55,7 +51,7 @@ func (wc *WorkflowController) ProjectCreate(ctx context.Context, project domain.
|
||||||
// Set ID from the DB raw:
|
// Set ID from the DB raw:
|
||||||
project.ID = string(appconfig.TicketID.Int32)
|
project.ID = string(appconfig.TicketID.Int32)
|
||||||
|
|
||||||
_, err = qtx.CreateTicket(ctx, db.CreateTicketParams{
|
projectRow, err := qtx.CreateTicket(ctx, db.CreateTicketParams{
|
||||||
Key: pgtype.Text{String: project.Key, Valid: true},
|
Key: pgtype.Text{String: project.Key, Valid: true},
|
||||||
Channelid: pgtype.Text{String: project.ChannelID, Valid: true},
|
Channelid: pgtype.Text{String: project.ChannelID, Valid: true},
|
||||||
Title: pgtype.Text{String: project.Name, Valid: true},
|
Title: pgtype.Text{String: project.Name, Valid: true},
|
||||||
|
|
@ -65,6 +61,7 @@ func (wc *WorkflowController) ProjectCreate(ctx context.Context, project domain.
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
tx.Commit(ctx)
|
tx.Commit(ctx)
|
||||||
|
fmt.Println(projectRow)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &project, nil
|
return &project, nil
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// WriteTaskToDB
|
// WriteTaskToDB
|
||||||
//
|
/*
|
||||||
// Makes an SQL query to create new tasks row from domain.Task entity
|
Makes an SQL query to create new tasks row from domain.Task entity
|
||||||
// - Creator field: telegram nickname or Discord's Mention();
|
- Creator field: telegram nickname or Discord's Mention();
|
||||||
// - Creator link (tg ID) in telegram case;
|
- Creator link (tg ID) in telegram case;
|
||||||
// - Description from telegram/discord message bodies;
|
- Description from telegram/discord message bodies;
|
||||||
|
*/
|
||||||
func (wc *WorkflowController) WriteTaskToDB(t *domain.Task) (*domain.Task, error) {
|
func (wc *WorkflowController) WriteTaskToDB(t *domain.Task) (*domain.Task, error) {
|
||||||
dbtask, err := wc.q.InsertTask(context.TODO(), db.InsertTaskParams{
|
dbtask, err := wc.q.InsertTask(context.TODO(), db.InsertTaskParams{
|
||||||
Creator: pgtype.Text{String: t.Creator, Valid: true},
|
Creator: pgtype.Text{String: t.Creator, Valid: true},
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,21 @@ func (c *Coda) CreateApp(task domain.CodaApplication) (string, error) {
|
||||||
return "", fmt.Errorf("unexpected coda response: %s", whResponse.ReqID)
|
return "", fmt.Errorf("unexpected coda response: %s", whResponse.ReqID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// arr := strings.Split(whResponse.ReqID, sep)
|
||||||
|
// if arr[0] == "mutate" {
|
||||||
|
// mutate = arr[1]
|
||||||
|
// }
|
||||||
|
|
||||||
|
// mutateResponse, err := c.R().
|
||||||
|
// SetContentType("application/json").
|
||||||
|
// SetBearerAuthToken(c.Config.Develop).
|
||||||
|
// Get(fmt.Sprintf("/mutationStatus/%s", mutate))
|
||||||
|
|
||||||
|
// if err != nil {
|
||||||
|
// return "", fmt.Errorf("unable to get coda mutate result: %s", mutate)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// _ = mutateResponse
|
||||||
return whResponse.ReqID, nil
|
return whResponse.ReqID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
12
readme.md
12
readme.md
|
|
@ -1,21 +1,15 @@
|
||||||
# Сборка:
|
# Сборка:
|
||||||
Подготовка контейнера проекта:
|
Подготовка контейнера проекта:
|
||||||
1. Поменять в коде файл окружения на '.env'
|
1. Поменять в коде файл окружения на '.env'
|
||||||
2. Собрать контейнер: `docker build -t naudachu/pimp-containerized:latest --pull .`
|
2. Собрать контейнер: `docker build -t naudachu/ticket-pimp:latest --pull .`
|
||||||
3. Затолкать контейнер в docker hub: `docker push naudachu/pimp-containerized:latest` (надо залогинится мб `docker login -u naudachu --password-stdin`)
|
3. Затолкать контейнер в docker hub: `docker push naudachu/ticket-pimp:latest`
|
||||||
|
|
||||||
# Запуск контейнера на сервере:
|
# Запуск контейнера на сервере:
|
||||||
1. Вытягиваем новый образ: `scp ./compose.yaml root@serverhost:~/compose.yaml`
|
1. Вытягиваем новый образ: `scp ./compose.yaml root@serverhost:~/compose.yaml`
|
||||||
2. Запуск контейнера: `docker-compose up -d`
|
2. Запуск контейнера: `docker-compose up -d`
|
||||||
|
|
||||||
## Обновление кода контейнера:
|
|
||||||
1. Осуществить сборку и отправку контейнера в докерхаб
|
|
||||||
2. Зайти на боевую машину по ssh
|
|
||||||
3. Выполнить `docker pull naudachu/pimp-containerized:latest`
|
|
||||||
4. Выполнить `docker-compose up -d`
|
|
||||||
5. Подчистить старый образ через `docker rmi {image_id}`, предварительно посмотрев список образов `docker images`
|
|
||||||
|
|
||||||
# Разработка:
|
# Разработка:
|
||||||
|
|
||||||
## Запуск вспомогательного контейнера с базой:
|
## Запуск вспомогательного контейнера с базой:
|
||||||
`docker-compose up -d`
|
`docker-compose up -d`
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue