- fixed all issues w/ servises;
- attached docker files w/ owncloud, gitbucket;
This commit is contained in:
parent
dc6109844f
commit
92d30623da
|
|
@ -1,46 +1,211 @@
|
||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/csv"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
d "ticket-pimp/bot/domain"
|
"strings"
|
||||||
"ticket-pimp/bot/ext"
|
"sync"
|
||||||
|
"ticket-pimp/internal/domain"
|
||||||
|
"ticket-pimp/internal/services"
|
||||||
|
|
||||||
|
"github.com/imroc/req/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WorkflowController struct {
|
type WorkflowController struct {
|
||||||
iGit ext.IGit
|
iGit services.IGit
|
||||||
iCloud ext.ICloud
|
iCloud services.ICloud
|
||||||
iYouTrack ext.IYouTrack
|
iYouTrack services.IYouTrack
|
||||||
additionalYT ext.IYouTrack
|
additionalYT services.IYouTrack
|
||||||
iCoda ext.ICoda
|
iCoda services.ICoda
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWorkflowController(
|
func NewWorkflowController(
|
||||||
gitBaseURL,
|
git services.IGit,
|
||||||
gitToken,
|
cloud services.ICloud,
|
||||||
cloudBaseURL,
|
devyt services.IYouTrack,
|
||||||
cloudAuthUser,
|
farmyt services.IYouTrack,
|
||||||
cloudAuthPass,
|
coda services.ICoda,
|
||||||
ytBaseURL,
|
|
||||||
ytToken,
|
|
||||||
addYTURL,
|
|
||||||
addYTToken string,
|
|
||||||
) *WorkflowController {
|
) *WorkflowController {
|
||||||
return &WorkflowController{
|
return &WorkflowController{
|
||||||
iGit: ext.NewGit(gitBaseURL, gitToken),
|
iGit: git,
|
||||||
iCloud: ext.NewCloud(cloudBaseURL, cloudAuthUser, cloudAuthPass),
|
iCloud: cloud,
|
||||||
iYouTrack: ext.NewYT(ytBaseURL, ytToken),
|
iYouTrack: devyt,
|
||||||
additionalYT: ext.NewYT(addYTURL, addYTToken),
|
additionalYT: farmyt,
|
||||||
iCoda: ext.NewCodaClient(),
|
iCoda: coda,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type IWorkflowController interface {
|
type IWorkflowController interface {
|
||||||
Workflow(name string) (string, error)
|
Workflow(name string) (string, error)
|
||||||
CreateRepo(name string) (*d.Git, error)
|
|
||||||
CreateFolder(name string) (*d.Folder, error)
|
|
||||||
|
|
||||||
NewTask(summ, desc, c, cLink string) *Task
|
NewTask(summ, desc, c, cLink string) *Task
|
||||||
CreateTask(t *Task) (*Task, error)
|
CreateTask(t *Task) (*Task, error)
|
||||||
|
|
||||||
ThrowConversions(f io.ReadCloser, appID string, token string) *d.ConversionLog
|
ThrowConversions(f io.ReadCloser, appID string, token string) *domain.ConversionLog
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wc *WorkflowController) ThrowConversions(f io.ReadCloser, appID string, token string) *domain.ConversionLog {
|
||||||
|
c := req.C().
|
||||||
|
SetBaseURL("https://graph.facebook.com/v15.0/").
|
||||||
|
DevMode()
|
||||||
|
|
||||||
|
const currency = "USD"
|
||||||
|
|
||||||
|
r := csv.NewReader(f)
|
||||||
|
|
||||||
|
conversionLog := domain.ConversionLog{}
|
||||||
|
|
||||||
|
for {
|
||||||
|
record, err := r.Read()
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
advertiser := strings.Split(record[0], ";")[0]
|
||||||
|
|
||||||
|
params := map[string]string{
|
||||||
|
"advertiser_id": advertiser,
|
||||||
|
"event": "CUSTOM_APP_EVENTS",
|
||||||
|
"application_tracking_enabled": "1",
|
||||||
|
"advertiser_tracking_enabled": "1",
|
||||||
|
"custom_events": `[{"_eventName":"fb_mobile_purchase"}]`,
|
||||||
|
}
|
||||||
|
|
||||||
|
res, _ := c.R().
|
||||||
|
SetQueryString(token).
|
||||||
|
SetQueryParams(params).
|
||||||
|
Post(appID + "/activities")
|
||||||
|
|
||||||
|
if res.Err != nil {
|
||||||
|
conversionLog.Advertiser = append(conversionLog.Advertiser, advertiser)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return &conversionLog
|
||||||
|
}
|
||||||
|
|
||||||
|
type Task struct {
|
||||||
|
Summary string
|
||||||
|
Description string
|
||||||
|
Creator string
|
||||||
|
CreatorLink string
|
||||||
|
|
||||||
|
Key string
|
||||||
|
URL string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wc *WorkflowController) NewTask(summ, desc, c, cLink string) *Task {
|
||||||
|
return &Task{
|
||||||
|
Summary: summ,
|
||||||
|
Description: desc,
|
||||||
|
Creator: c,
|
||||||
|
CreatorLink: cLink,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wc *WorkflowController) CreateTask(t *Task) (*Task, error) {
|
||||||
|
|
||||||
|
yt := wc.additionalYT
|
||||||
|
|
||||||
|
projectID, err := yt.GetProjectIDByName("E")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Description += fmt.Sprintf("\n\n Created by: [%s](%s)", t.Creator, t.CreatorLink)
|
||||||
|
|
||||||
|
issue, err := yt.CreateIssue(projectID, t.Creator+" | "+t.Summary, t.Description)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Key = issue.Key
|
||||||
|
t.URL = fmt.Sprintf("https://mobmarlerino.youtrack.cloud/issue/%s", issue.Key)
|
||||||
|
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wc *WorkflowController) Workflow(name string) (string, error) {
|
||||||
|
// coda := wc.iCoda
|
||||||
|
|
||||||
|
yt := wc.iYouTrack
|
||||||
|
|
||||||
|
projectID, err := yt.GetProjectIDByName("tst")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an issue at the available project with the provided name
|
||||||
|
issue, err := yt.CreateIssue(projectID, name, "")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if issue != nil {
|
||||||
|
var (
|
||||||
|
git, gitBuild *domain.Git
|
||||||
|
cloud *domain.Folder
|
||||||
|
)
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(3)
|
||||||
|
|
||||||
|
go func(ref **domain.Git) {
|
||||||
|
defer wg.Done()
|
||||||
|
*ref, _ = wc.iGit.CreateRepo(issue.Key)
|
||||||
|
}(&git)
|
||||||
|
|
||||||
|
go func(ref **domain.Git) {
|
||||||
|
defer wg.Done()
|
||||||
|
*ref, _ = wc.iGit.CreateRepo(issue.Key + "-build")
|
||||||
|
}(&gitBuild)
|
||||||
|
|
||||||
|
go func(ref **domain.Folder) {
|
||||||
|
defer wg.Done()
|
||||||
|
*ref, _ = wc.iCloud.CreateFolder(issue.Key + " - " + issue.Summary)
|
||||||
|
}(&cloud)
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
var gitResult, gitBuildResult, cloudResult string
|
||||||
|
|
||||||
|
if git == nil {
|
||||||
|
gitResult = "cannot create git"
|
||||||
|
} else {
|
||||||
|
gitResult = git.HtmlUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
if gitBuild == nil {
|
||||||
|
gitBuildResult = "cannot create git"
|
||||||
|
} else {
|
||||||
|
gitBuildResult = fmt.Sprintf("ssh://%s/%s.git", gitBuild.SshUrl, gitBuild.FullName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cloud == nil {
|
||||||
|
cloudResult = "cannot create folder"
|
||||||
|
} else {
|
||||||
|
cloudResult = cloud.PrivateURL
|
||||||
|
}
|
||||||
|
|
||||||
|
wc.iCoda.CreateTask(domain.CodaIssue{
|
||||||
|
ID: issue.Key,
|
||||||
|
Summary: strings.TrimSpace(name),
|
||||||
|
Git: gitResult,
|
||||||
|
GitBuild: gitBuildResult,
|
||||||
|
Folder: cloudResult,
|
||||||
|
})
|
||||||
|
|
||||||
|
yt.UpdateIssue(
|
||||||
|
issue,
|
||||||
|
cloudResult,
|
||||||
|
gitResult,
|
||||||
|
gitBuildResult,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return issue.Key, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
package controller
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/csv"
|
|
||||||
"io"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/imroc/req/v3"
|
|
||||||
|
|
||||||
d "ticket-pimp/bot/domain"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (wc *WorkflowController) ThrowConversions(f io.ReadCloser, appID string, token string) *d.ConversionLog {
|
|
||||||
c := req.C().
|
|
||||||
SetBaseURL("https://graph.facebook.com/v15.0/").
|
|
||||||
DevMode()
|
|
||||||
|
|
||||||
const currency = "USD"
|
|
||||||
|
|
||||||
r := csv.NewReader(f)
|
|
||||||
|
|
||||||
conversionLog := d.ConversionLog{}
|
|
||||||
|
|
||||||
for {
|
|
||||||
record, err := r.Read()
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
advertiser := strings.Split(record[0], ";")[0]
|
|
||||||
|
|
||||||
params := map[string]string{
|
|
||||||
"advertiser_id": advertiser,
|
|
||||||
"event": "CUSTOM_APP_EVENTS",
|
|
||||||
"application_tracking_enabled": "1",
|
|
||||||
"advertiser_tracking_enabled": "1",
|
|
||||||
"custom_events": `[{"_eventName":"fb_mobile_purchase"}]`,
|
|
||||||
}
|
|
||||||
|
|
||||||
res, _ := c.R().
|
|
||||||
SetQueryString(token).
|
|
||||||
SetQueryParams(params).
|
|
||||||
Post(appID + "/activities")
|
|
||||||
|
|
||||||
if res.Err != nil {
|
|
||||||
conversionLog.Advertiser = append(conversionLog.Advertiser, advertiser)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return &conversionLog
|
|
||||||
}
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
function myFunction() {
|
|
||||||
var sheet = SpreadsheetApp.getActiveSheet();
|
|
||||||
var data = sheet.getDataRange().getValues();
|
|
||||||
var a1 = data[1][1];
|
|
||||||
var a2 = ''
|
|
||||||
var a3 = data[1][2];
|
|
||||||
var reqUrl = data[1][3];
|
|
||||||
var startarray = data[1][4]
|
|
||||||
|
|
||||||
var regCount = 0;
|
|
||||||
var depCount = 0;
|
|
||||||
// reqUrl = 'https://graph.facebook.com/v15.0/841990173617973/activities?event=CUSTOM_APP_EVENTS&application_tracking_enabled=1&advertiser_tracking_enabled=1&advertiser_id=0a42bbee-c049-4180-ae3f-ce76ff33556e&841990173617973%7Cnjqit85G_uma0voikeP6eJvBiQk&custom_events=[%7B%22_eventName%22:%22fb_mobile_purchase%22%7D]'
|
|
||||||
reqUrl = reqUrl.replace('A1', a1)
|
|
||||||
reqUrl = reqUrl.replace('A3', a3)
|
|
||||||
Logger.log("urll " + reqUrl)
|
|
||||||
Logger.log("urll " + encodeURI(reqUrl).toString())
|
|
||||||
|
|
||||||
for (var i = startarray; i < data.length; i++) {
|
|
||||||
a2 = data[i][0]
|
|
||||||
reqUrl = reqUrl.replace('A2', a2)
|
|
||||||
|
|
||||||
var params = {
|
|
||||||
"method": 'post'
|
|
||||||
}
|
|
||||||
var response = UrlFetchApp.fetch(encodeURI(reqUrl), params);
|
|
||||||
Logger.log(i + " " + response.getContentText() + ' ' + response.getResponseCode());
|
|
||||||
depCount++;
|
|
||||||
|
|
||||||
}
|
|
||||||
Logger.log('Reg Count= ' + regCount);
|
|
||||||
Logger.log('Dep Count= ' + depCount);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
package controller
|
|
||||||
|
|
||||||
import d "ticket-pimp/bot/domain"
|
|
||||||
|
|
||||||
func (wc *WorkflowController) CreateFolder(name string) (*d.Folder, error) {
|
|
||||||
|
|
||||||
//Create ownCloud folder w/ iCloud interface;
|
|
||||||
cloud, err := wc.iCloud.CreateFolder(name)
|
|
||||||
if cloud == nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return cloud, err
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
package controller
|
|
||||||
|
|
||||||
import d "ticket-pimp/bot/domain"
|
|
||||||
|
|
||||||
func (wc *WorkflowController) CreateRepo(name string) (*d.Git, error) {
|
|
||||||
//Create git repository with iGit interface;
|
|
||||||
repo, err := wc.iGit.NewRepo(name)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
//Set 'apps' as collaborator to created repository;
|
|
||||||
_, err = wc.iGit.AppsAsCollaboratorTo(repo)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return repo, nil
|
|
||||||
}
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
package controller
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
type Task struct {
|
|
||||||
Summary string
|
|
||||||
Description string
|
|
||||||
Creator string
|
|
||||||
CreatorLink string
|
|
||||||
|
|
||||||
Key string
|
|
||||||
URL string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wc *WorkflowController) NewTask(summ, desc, c, cLink string) *Task {
|
|
||||||
return &Task{
|
|
||||||
Summary: summ,
|
|
||||||
Description: desc,
|
|
||||||
Creator: c,
|
|
||||||
CreatorLink: cLink,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wc *WorkflowController) CreateTask(t *Task) (*Task, error) {
|
|
||||||
|
|
||||||
yt := wc.additionalYT
|
|
||||||
|
|
||||||
projectID, err := yt.GetProjectIDByName("E")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Description += fmt.Sprintf("\n\n Created by: [%s](%s)", t.Creator, t.CreatorLink)
|
|
||||||
|
|
||||||
issue, err := yt.CreateIssue(projectID, t.Creator+" | "+t.Summary, t.Description)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Key = issue.Key
|
|
||||||
t.URL = fmt.Sprintf("https://mobmarlerino.youtrack.cloud/issue/%s", issue.Key)
|
|
||||||
|
|
||||||
return t, nil
|
|
||||||
}
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
package controller
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
"ticket-pimp/bot/domain"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (wc *WorkflowController) Workflow(name string) (string, error) {
|
|
||||||
coda := wc.iCoda
|
|
||||||
|
|
||||||
yt := wc.iYouTrack
|
|
||||||
|
|
||||||
projectID, err := yt.GetProjectIDByName("APP")
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an issue at the available project with the provided name
|
|
||||||
issue, err := yt.CreateIssue(projectID, name, "")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if issue != nil {
|
|
||||||
var (
|
|
||||||
git, gitBuild *domain.Git
|
|
||||||
cloud *domain.Folder
|
|
||||||
)
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
wg.Add(3)
|
|
||||||
|
|
||||||
go func(ref **domain.Git) {
|
|
||||||
defer wg.Done()
|
|
||||||
*ref, _ = wc.CreateRepo(issue.Key)
|
|
||||||
}(&git)
|
|
||||||
|
|
||||||
go func(ref **domain.Git) {
|
|
||||||
defer wg.Done()
|
|
||||||
*ref, _ = wc.CreateRepo(issue.Key + "-build")
|
|
||||||
}(&gitBuild)
|
|
||||||
|
|
||||||
go func(ref **domain.Folder) {
|
|
||||||
defer wg.Done()
|
|
||||||
*ref, _ = wc.CreateFolder(issue.Key + " - " + issue.Summary)
|
|
||||||
}(&cloud)
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
|
|
||||||
taskDraft := domain.CodaIssue{
|
|
||||||
ID: issue.ID,
|
|
||||||
Summary: name,
|
|
||||||
URL: "",
|
|
||||||
Git: git.HtmlUrl,
|
|
||||||
GitBuild: fmt.Sprintf("ssh://%s/%s.git", gitBuild.SshUrl, gitBuild.FullName),
|
|
||||||
Folder: cloud.PrivateURL,
|
|
||||||
}
|
|
||||||
|
|
||||||
coda.CreateTask(taskDraft)
|
|
||||||
|
|
||||||
yt.UpdateIssue(
|
|
||||||
issue,
|
|
||||||
cloud.PrivateURL,
|
|
||||||
git.HtmlUrl,
|
|
||||||
fmt.Sprintf("ssh://%s/%s.git", gitBuild.SshUrl, gitBuild.FullName))
|
|
||||||
}
|
|
||||||
return issue.Key, nil
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
package domain
|
|
||||||
|
|
||||||
type Folder struct {
|
|
||||||
Title string // k
|
|
||||||
PathTo string // /temp/k
|
|
||||||
PrivateURL string // http://domain/apps/files/?dir=/temp/k OR http://domain/f/3333
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
package domain
|
|
||||||
|
|
||||||
type CodaIssue struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Summary string `json:"summary"`
|
|
||||||
URL string `json:"url"`
|
|
||||||
Git string `json:"git"`
|
|
||||||
GitBuild string `json:"git-build"`
|
|
||||||
Folder string `json:"folder"`
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
package domain
|
|
||||||
|
|
||||||
type ConversionLog struct {
|
|
||||||
Advertiser []string
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
package domain
|
|
||||||
|
|
||||||
type Git struct {
|
|
||||||
Name string `json:"name"` // "poop"
|
|
||||||
FullName string `json:"full_name"` // "developer/poop"
|
|
||||||
Private bool `json:"private"`
|
|
||||||
Url string `json:"url"` // "http://localhost:8081/api/v3/repos/developer/poop"
|
|
||||||
CloneUrl string `json:"clone_url"` // "http://localhost:8081/git/developer/poop.git"
|
|
||||||
HtmlUrl string `json:"Html_url"` // "http://localhost:8081/developer/poop"
|
|
||||||
SshUrl string `json:"ssh_url"` // ?!
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
package domain
|
|
||||||
|
|
||||||
type Task struct {
|
|
||||||
Description string
|
|
||||||
URL string
|
|
||||||
}
|
|
||||||
|
|
@ -7,7 +7,8 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
"ticket-pimp/bot/controller"
|
"ticket-pimp/bot/controller"
|
||||||
d "ticket-pimp/bot/domain"
|
"ticket-pimp/internal/domain"
|
||||||
|
"ticket-pimp/internal/services"
|
||||||
|
|
||||||
"github.com/mr-linch/go-tg"
|
"github.com/mr-linch/go-tg"
|
||||||
"github.com/mr-linch/go-tg/tgb"
|
"github.com/mr-linch/go-tg/tgb"
|
||||||
|
|
@ -15,21 +16,22 @@ import (
|
||||||
|
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
workflow controller.IWorkflowController
|
workflow controller.IWorkflowController
|
||||||
|
git services.IGit
|
||||||
|
cloud services.ICloud
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(gitBaseURL, gitToken, cloudBaseURL, cloudAuthUser, cloudAuthPass, ytBaseURL, ytToken, addYTURL, addYTToken string) *Handler {
|
func NewHandler(
|
||||||
|
git services.IGit,
|
||||||
|
cloud services.ICloud,
|
||||||
|
devyt services.IYouTrack,
|
||||||
|
farmyt services.IYouTrack,
|
||||||
|
coda services.ICoda,
|
||||||
|
) *Handler {
|
||||||
|
|
||||||
return &Handler{
|
return &Handler{
|
||||||
workflow: controller.NewWorkflowController(
|
workflow: controller.NewWorkflowController(git, cloud, devyt, farmyt, coda),
|
||||||
gitBaseURL,
|
git: git,
|
||||||
gitToken,
|
cloud: cloud,
|
||||||
cloudBaseURL,
|
|
||||||
cloudAuthUser,
|
|
||||||
cloudAuthPass,
|
|
||||||
ytBaseURL,
|
|
||||||
ytToken,
|
|
||||||
addYTURL,
|
|
||||||
addYTToken,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,12 +48,12 @@ type git struct {
|
||||||
ssh string
|
ssh string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newGit(d *d.Git) *git {
|
func newGit(domain *domain.Git) *git {
|
||||||
return &git{
|
return &git{
|
||||||
name: d.Name,
|
name: domain.Name,
|
||||||
url: d.HtmlUrl,
|
url: domain.HtmlUrl,
|
||||||
git: d.CloneUrl,
|
git: domain.CloneUrl,
|
||||||
ssh: fmt.Sprintf("ssh://%s/%s.git", d.SshUrl, d.FullName),
|
ssh: fmt.Sprintf("ssh://%s/%s.git", domain.SshUrl, domain.FullName),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,8 +76,9 @@ func (h *Handler) NewRepoHandler(ctx context.Context, mu *tgb.MessageUpdate) err
|
||||||
return errors.New("empty command provided")
|
return errors.New("empty command provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
var g *d.Git
|
var g *domain.Git
|
||||||
g, err := h.workflow.CreateRepo(str)
|
|
||||||
|
g, err := h.git.CreateRepo(str)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return mu.Answer(errorAnswer(err.Error())).ParseMode(tg.HTML).DoVoid(ctx)
|
return mu.Answer(errorAnswer(err.Error())).ParseMode(tg.HTML).DoVoid(ctx)
|
||||||
|
|
@ -94,7 +97,7 @@ 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.workflow.CreateFolder(str)
|
cloud, err := h.cloud.CreateFolder(str)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return mu.Answer(errorAnswer(err.Error())).ParseMode(tg.HTML).DoVoid(ctx)
|
return mu.Answer(errorAnswer(err.Error())).ParseMode(tg.HTML).DoVoid(ctx)
|
||||||
|
|
@ -121,7 +124,7 @@ func errorAnswer(errorMsg string) string {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) NewTicketHandler(ctx context.Context, mu *tgb.MessageUpdate) error {
|
func (h *Handler) DevelopmentTaskHandler(ctx context.Context, mu *tgb.MessageUpdate) error {
|
||||||
|
|
||||||
str := strings.Replace(mu.Text, "/new", "", 1)
|
str := strings.Replace(mu.Text, "/new", "", 1)
|
||||||
|
|
||||||
|
|
@ -148,7 +151,7 @@ func newTicketAnswer(name string) string {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) NewTaskHandler(ctx context.Context, mu *tgb.MessageUpdate) error {
|
func (h *Handler) FarmTaskHandler(ctx context.Context, mu *tgb.MessageUpdate) error {
|
||||||
|
|
||||||
taskText := strings.TrimSpace(strings.Replace(mu.Text, "/task", "", 1))
|
taskText := strings.TrimSpace(strings.Replace(mu.Text, "/task", "", 1))
|
||||||
words := strings.Split(taskText, " ")
|
words := strings.Split(taskText, " ")
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
"ticket-pimp/bot/domain"
|
"ticket-pimp/internal/domain"
|
||||||
)
|
)
|
||||||
|
|
||||||
type test struct {
|
type test struct {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
CODA_TOKEN = 'f54477f0-98ca-4285-844f-9fa2ef34475d'
|
||||||
|
CODA_DOC = 'Ic3IZpQ3Wk'
|
||||||
|
CODA_TOKEN1 = "0d5a6853-8bb1-4208-9014-318094f5b21c"
|
||||||
|
|
||||||
|
CLOUD_BASE_URL = 'http://localhost:8080'
|
||||||
|
CLOUD_USER = 'admin'
|
||||||
|
CLOUD_PASS = 'admin'
|
||||||
|
|
||||||
|
ROOTDIR = "/temp/"
|
||||||
|
|
||||||
|
GIT_BASE_URL = 'http://localhost:8081/api/v3'
|
||||||
|
GIT_TOKEN = '2dc2f4f8e938ff914d2a9e006b22e63a3b8e5561'
|
||||||
|
GIT_USER = 'developer'
|
||||||
|
|
||||||
|
YT_URL = 'https://marlerino.youtrack.cloud/api'
|
||||||
|
YT_TOKEN = 'perm:bmF1ZGFjaHU=.NTYtMQ==.4TVHQx65u4EKnCGjadeMB1NMAmSHSL'
|
||||||
|
|
||||||
|
YT_ADDITIONAL_URL = 'https://mobmarlerino.youtrack.cloud/api'
|
||||||
|
YT_ADDITIONAL_TOKEN = 'perm:cm9vdA==.NDktMA==.iANVnkmP4DiyFrAeaSD6SyCrEiGQzc'
|
||||||
|
|
||||||
|
TG_API = '6002875059:AAFp1ZR9Y68oaqSL6vTNQdhrVgcM_yHouCY'
|
||||||
|
|
||||||
|
DB_LINK = "host=localhost user=postgres password=postgres dbname=pimp port=5432 sslmode=disable"
|
||||||
29
cmd/main.go
29
cmd/main.go
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
"ticket-pimp/bot/handler"
|
"ticket-pimp/bot/handler"
|
||||||
|
"ticket-pimp/internal/services"
|
||||||
|
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
"github.com/mr-linch/go-tg"
|
"github.com/mr-linch/go-tg"
|
||||||
|
|
@ -16,7 +17,7 @@ import (
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log.Print("started")
|
log.Print("started")
|
||||||
env(".env")
|
env("dev.env")
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
ctx, cancel := signal.NotifyContext(ctx, os.Interrupt, os.Kill, syscall.SIGTERM)
|
ctx, cancel := signal.NotifyContext(ctx, os.Interrupt, os.Kill, syscall.SIGTERM)
|
||||||
|
|
@ -46,24 +47,44 @@ func runBot(ctx context.Context) error {
|
||||||
|
|
||||||
client := tg.New(os.Getenv("TG_API"))
|
client := tg.New(os.Getenv("TG_API"))
|
||||||
|
|
||||||
h := handler.NewHandler(
|
gitService := services.NewGit(
|
||||||
os.Getenv("GIT_BASE_URL"),
|
os.Getenv("GIT_BASE_URL"),
|
||||||
os.Getenv("GIT_TOKEN"),
|
os.Getenv("GIT_TOKEN"),
|
||||||
|
)
|
||||||
|
|
||||||
|
cloudService := services.NewCloud(
|
||||||
os.Getenv("CLOUD_BASE_URL"),
|
os.Getenv("CLOUD_BASE_URL"),
|
||||||
os.Getenv("CLOUD_USER"),
|
os.Getenv("CLOUD_USER"),
|
||||||
os.Getenv("CLOUD_PASS"),
|
os.Getenv("CLOUD_PASS"),
|
||||||
|
)
|
||||||
|
|
||||||
|
devYouTrackService := services.NewYT(
|
||||||
os.Getenv("YT_URL"),
|
os.Getenv("YT_URL"),
|
||||||
os.Getenv("YT_TOKEN"),
|
os.Getenv("YT_TOKEN"),
|
||||||
|
)
|
||||||
|
|
||||||
|
farmYouTrackService := services.NewYT(
|
||||||
os.Getenv("YT_ADDITIONAL_URL"),
|
os.Getenv("YT_ADDITIONAL_URL"),
|
||||||
os.Getenv("YT_ADDITIONAL_TOKEN"),
|
os.Getenv("YT_ADDITIONAL_TOKEN"),
|
||||||
)
|
)
|
||||||
|
coda := services.NewCodaClient(
|
||||||
|
os.Getenv("CODA_TOKEN1"),
|
||||||
|
)
|
||||||
|
|
||||||
|
h := handler.NewHandler(
|
||||||
|
gitService,
|
||||||
|
cloudService,
|
||||||
|
devYouTrackService,
|
||||||
|
farmYouTrackService,
|
||||||
|
coda,
|
||||||
|
)
|
||||||
|
|
||||||
router := tgb.NewRouter().
|
router := tgb.NewRouter().
|
||||||
Message(h.NewTicketHandler, tgb.TextHasPrefix("/new")).
|
Message(h.DevelopmentTaskHandler, tgb.TextHasPrefix("/new")).
|
||||||
Message(h.PingHandler, tgb.Command("ping")).
|
Message(h.PingHandler, tgb.Command("ping")).
|
||||||
Message(h.NewRepoHandler, tgb.TextHasPrefix("/repo")).
|
Message(h.NewRepoHandler, tgb.TextHasPrefix("/repo")).
|
||||||
Message(h.NewFolderHandler, tgb.TextHasPrefix("/folder")).
|
Message(h.NewFolderHandler, tgb.TextHasPrefix("/folder")).
|
||||||
Message(h.NewTaskHandler, tgb.TextHasPrefix("/task")).
|
Message(h.FarmTaskHandler, tgb.TextHasPrefix("/task")).
|
||||||
Message(h.NewConversion, tgb.TextHasPrefix("/conversion"))
|
Message(h.NewConversion, tgb.TextHasPrefix("/conversion"))
|
||||||
|
|
||||||
return tgb.NewPoller(
|
return tgb.NewPoller(
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ COPY . .
|
||||||
RUN apk add git
|
RUN apk add git
|
||||||
# Static build required so that we can safely copy the binary over.
|
# Static build required so that we can safely copy the binary over.
|
||||||
# `-tags timetzdata` embeds zone info from the "time/tzdata" package.
|
# `-tags timetzdata` embeds zone info from the "time/tzdata" package.
|
||||||
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:
|
# the test program:
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
FROM adoptopenjdk/openjdk11-openj9
|
||||||
|
|
||||||
|
ARG GITBUCKET_HOME
|
||||||
|
|
||||||
|
# create home
|
||||||
|
RUN mkdir -p $GITBUCKET_HOME
|
||||||
|
|
||||||
|
# mark volumes
|
||||||
|
VOLUME $GITBUCKET_HOME/repositories
|
||||||
|
VOLUME $GITBUCKET_HOME/data
|
||||||
|
VOLUME $GITBUCKET_HOME/gist
|
||||||
|
VOLUME $GITBUCKET_HOME/plugins
|
||||||
|
|
||||||
|
# Port for web page and Port for SSH access to git repository (Optional)
|
||||||
|
EXPOSE 8080 8443 29418
|
||||||
|
|
||||||
|
COPY server-WIN-DOMAIN-CA.cer /
|
||||||
|
COPY SSLPoke.java /
|
||||||
|
|
||||||
|
# ADD https://github.com/gitbucket/gitbucket/releases/download/4.38.4/gitbucket.war $GITBUCKET_HOME/gitbucket.war
|
||||||
|
COPY gitbucket.war $GITBUCKET_HOME
|
||||||
|
|
||||||
|
RUN keytool -importcert -file /server-WIN-DOMAIN-CA.cer -alias "server-WIN-DOMAIN-CA" -cacerts -storepass changeit -noprompt
|
||||||
|
|
||||||
|
# set environment
|
||||||
|
WORKDIR $GITBUCKET_HOME
|
||||||
|
|
||||||
|
CMD ["sh", "-c", "java $JAVA_OPTS -jar $GITBUCKET_HOME/gitbucket.war"]
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
import javax.net.ssl.SSLParameters;
|
||||||
|
import javax.net.ssl.SSLSocket;
|
||||||
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
/** Establish a SSL connection to a host and port, writes a byte and
|
||||||
|
* prints the response. See
|
||||||
|
* http://confluence.atlassian.com/display/JIRA/Connecting+to+SSL+services
|
||||||
|
*/
|
||||||
|
public class SSLPoke {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
if (args.length != 2) {
|
||||||
|
System.out.println("Usage: "+SSLPoke.class.getName()+" <host> <port>");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
|
||||||
|
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(args[0], Integer.parseInt(args[1]));
|
||||||
|
|
||||||
|
SSLParameters sslparams = new SSLParameters();
|
||||||
|
sslparams.setEndpointIdentificationAlgorithm("HTTPS");
|
||||||
|
sslsocket.setSSLParameters(sslparams);
|
||||||
|
|
||||||
|
InputStream in = sslsocket.getInputStream();
|
||||||
|
OutputStream out = sslsocket.getOutputStream();
|
||||||
|
|
||||||
|
// Write a test byte to get a reaction :)
|
||||||
|
out.write(1);
|
||||||
|
|
||||||
|
while (in.available() > 0) {
|
||||||
|
System.out.print(in.read());
|
||||||
|
}
|
||||||
|
System.out.println("Successfully connected");
|
||||||
|
|
||||||
|
} catch (Exception exception) {
|
||||||
|
exception.printStackTrace();
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
version: "3"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mysql:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
services:
|
||||||
|
gitbucket:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
args:
|
||||||
|
GITBUCKET_HOME: /mnt/gitbucket
|
||||||
|
container_name: gitbucket_server
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- ${HTTP_PORT}:8080
|
||||||
|
- ${HTTPS_PORT}:8443
|
||||||
|
# Optional for SSH:
|
||||||
|
- ${SSH_PORT}:29418
|
||||||
|
depends_on:
|
||||||
|
mariadb:
|
||||||
|
condition: service_healthy
|
||||||
|
environment:
|
||||||
|
- JAVA_OPTS=-Dcom.sun.net.ssl.checkRevocation=false -Dcom.sun.security.enableAIAcaIssuers=true -Docsp.enable=fase -Dtrust_all_cert=true -Djdk.tls.client.protocols=TLSv1.2 -Dcom.sun.net.ssl.enableECC=false
|
||||||
|
- GITBUCKET_HOME=/mnt/gitbucket
|
||||||
|
- GITBUCKET_CONNECTORS=http
|
||||||
|
- GITBUCKET_HOST=0.0.0.0
|
||||||
|
- GITBUCKET_PORT=8080
|
||||||
|
- GITBUCKET_SECUREPORT=8443
|
||||||
|
- GITBUCKET_REDIRECTHTTPS=false
|
||||||
|
- GITBUCKET_PREFIX=/
|
||||||
|
- GITBUCKET_MAXFILESIZE=4294967296
|
||||||
|
- GITBUCKET_UPLOADTIMEOUT=120000
|
||||||
|
- GITBUCKET_JETTYIDLETIMEOUT=600000
|
||||||
|
- GITBUCKET_DB_URL=jdbc:mariadb://mariadb/gitbucket?useUnicode=true&characterEncoding=utf8
|
||||||
|
- GITBUCKET_DB_USER=gitbucket
|
||||||
|
- GITBUCKET_DB_PASSWORD=gitbucket
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "/usr/bin/healthcheck"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 5
|
||||||
|
volumes:
|
||||||
|
- ../disks/disk1/gitbucket_data/repositories/:/mnt/gitbucket/repositories/
|
||||||
|
- ../disks/disk1/gitbucket_data/data/:/mnt/gitbucket/data/
|
||||||
|
- ../disks/disk1/gitbucket_data/gist/:/mnt/gitbucket/gist/
|
||||||
|
- ../disks/disk1/gitbucket_data/plugins/:/mnt/gitbucket/plugins/
|
||||||
|
|
||||||
|
mariadb:
|
||||||
|
image: mariadb:10.6
|
||||||
|
container_name: gitbucket_mariadb
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- ${DB_PORT}:3306
|
||||||
|
environment:
|
||||||
|
- MYSQL_ROOT_PASSWORD=gitbucket
|
||||||
|
- MYSQL_USER=gitbucket
|
||||||
|
- MYSQL_PASSWORD=gitbucket
|
||||||
|
- MYSQL_DATABASE=gitbucket
|
||||||
|
command: ["--max-allowed-packet=128M", "--innodb-log-file-size=64M"]
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "mysqladmin", "ping", "-u", "root", "--password=gitbucket"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
volumes:
|
||||||
|
- mysql:/var/lib/mysql
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,22 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDuTCCAqGgAwIBAgIQcZXcA798CYtB1LtewpzPijANBgkqhkiG9w0BAQsFADBu
|
||||||
|
MRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxHjAcBgoJkiaJk/IsZAEZFg5tYXJsZXJp
|
||||||
|
bm9ncm91cDEWMBQGCgmSJomT8ixkARkWBnNlcnZlcjEdMBsGA1UEAxMUc2VydmVy
|
||||||
|
LVdJTi1ET01BSU4tQ0EwIBcNMjIwODE1MTI1NTM3WhgPMjEyMjA4MTUxMzA1Mzda
|
||||||
|
MG4xFTATBgoJkiaJk/IsZAEZFgVsb2NhbDEeMBwGCgmSJomT8ixkARkWDm1hcmxl
|
||||||
|
cmlub2dyb3VwMRYwFAYKCZImiZPyLGQBGRYGc2VydmVyMR0wGwYDVQQDExRzZXJ2
|
||||||
|
ZXItV0lOLURPTUFJTi1DQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||||
|
AMBJwWymu7Csp+y8EMiPNo5drsQE58+enNCk13OIemQON5LZwY++BnvIrHvnaCof
|
||||||
|
Cdb9U2QyWV+Iehv/lNXcBkT6dJCTxUVmn6rXMmwNnBJmGuy0D6APIEPVBO3S7+/R
|
||||||
|
E4az8ikpVezbqAw/LiSyVMEQFaAEK8RlleBScLw9gpXmcWKljCrO/z+2wO1EGI3z
|
||||||
|
a1+qFLynQLeyusRj6rvo0U4RTyXdKaA++Ojhx3DV1NopHoSJ7CqXR728ubWK0fvY
|
||||||
|
0JGMg2ijS1cle7yC96+9ZSjdtktI/9M+8SG/tbpXcpW1bzGM0wCWOos1hLehks7V
|
||||||
|
c1pBEuVGSKSdtyF/FK2C7YUCAwEAAaNRME8wCwYDVR0PBAQDAgGGMA8GA1UdEwEB
|
||||||
|
/wQFMAMBAf8wHQYDVR0OBBYEFL+/yzfaRM/Rcrc9oYEzZf3STypqMBAGCSsGAQQB
|
||||||
|
gjcVAQQDAgEAMA0GCSqGSIb3DQEBCwUAA4IBAQA7j2n9ZeKDwbmWCM2P1F9+6EZ8
|
||||||
|
+RZ+PEdxqs3aDo6S0Ckr/iopHA9PoexKGVEQN6bzaYxb0XTEbpJ89oI299weJF+W
|
||||||
|
63zID/lpEzsaSlTWpuj8KBudVoKsJmwJK2akQ2T3MmSiz7drtFOyh5wl9vhoi2cv
|
||||||
|
H3xhpqOYgh6iRwfwXMLo2YyS4vG6UZtq1GnU/drwVb1gHCoMdz7sFIdxlaw85Ub+
|
||||||
|
dlicykBNu60dbvM/iI0qSG25PerjEoOWZAglrPWpsQ0Zy+ChV0lWSp6FIYHjT3Rj
|
||||||
|
3TUo18LwIUKyorRErOTO4vgYHpqaA/RkAfl0C3cUujMw9eAp1fyd9FH0UcDo
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
version: "3"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mysql:
|
||||||
|
driver: local
|
||||||
|
redis:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
services:
|
||||||
|
owncloud:
|
||||||
|
image: owncloud/server:${OWNCLOUD_VERSION}
|
||||||
|
container_name: owncloud_server
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- ${HTTP_PORT}:8080
|
||||||
|
depends_on:
|
||||||
|
- mariadb
|
||||||
|
- redis
|
||||||
|
environment:
|
||||||
|
- OWNCLOUD_DOMAIN=${OWNCLOUD_DOMAIN}
|
||||||
|
- OWNCLOUD_TRUSTED_DOMAINS=${OWNCLOUD_TRUSTED_DOMAINS}
|
||||||
|
- OWNCLOUD_DB_TYPE=mysql
|
||||||
|
- OWNCLOUD_DB_NAME=owncloud
|
||||||
|
- OWNCLOUD_DB_USERNAME=owncloud
|
||||||
|
- OWNCLOUD_DB_PASSWORD=owncloud
|
||||||
|
- OWNCLOUD_DB_HOST=mariadb
|
||||||
|
- OWNCLOUD_ADMIN_USERNAME=${ADMIN_USERNAME}
|
||||||
|
- OWNCLOUD_ADMIN_PASSWORD=${ADMIN_PASSWORD}
|
||||||
|
- OWNCLOUD_MYSQL_UTF8MB4=true
|
||||||
|
- OWNCLOUD_REDIS_ENABLED=true
|
||||||
|
- OWNCLOUD_REDIS_HOST=redis
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "/usr/bin/healthcheck"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 5
|
||||||
|
volumes:
|
||||||
|
- ../disks/disk1/owncloud_data/:/mnt/data
|
||||||
|
- ../disks/:/mnt/disks
|
||||||
|
|
||||||
|
mariadb:
|
||||||
|
image: mariadb:10.6 # minimum required ownCloud version is 10.9
|
||||||
|
container_name: owncloud_mariadb
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- ${DB_PORT}:3306
|
||||||
|
environment:
|
||||||
|
- MYSQL_ROOT_PASSWORD=owncloud
|
||||||
|
- MYSQL_USER=owncloud
|
||||||
|
- MYSQL_PASSWORD=owncloud
|
||||||
|
- MYSQL_DATABASE=owncloud
|
||||||
|
command: ["--max-allowed-packet=128M", "--innodb-log-file-size=64M"]
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "mysqladmin", "ping", "-u", "root", "--password=owncloud"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
volumes:
|
||||||
|
- mysql:/var/lib/mysql
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:6
|
||||||
|
container_name: owncloud_redis
|
||||||
|
restart: always
|
||||||
|
command: ["--databases", "1"]
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
volumes:
|
||||||
|
- redis:/data
|
||||||
|
|
@ -2,6 +2,40 @@ package domain
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
|
type Folder struct {
|
||||||
|
Title string // k
|
||||||
|
PathTo string // /temp/k
|
||||||
|
PrivateURL string // http://domain/apps/files/?dir=/temp/k OR http://domain/f/3333
|
||||||
|
}
|
||||||
|
|
||||||
|
type CodaIssue struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Summary string `json:"summary"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Git string `json:"git"`
|
||||||
|
GitBuild string `json:"git-build"`
|
||||||
|
Folder string `json:"folder"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConversionLog struct {
|
||||||
|
Advertiser []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Git struct {
|
||||||
|
Name string `json:"name"` // "poop"
|
||||||
|
FullName string `json:"full_name"` // "developer/poop"
|
||||||
|
Private bool `json:"private"`
|
||||||
|
Url string `json:"url"` // "http://localhost:8081/api/v3/repos/developer/poop"
|
||||||
|
CloneUrl string `json:"clone_url"` // "http://localhost:8081/git/developer/poop.git"
|
||||||
|
HtmlUrl string `json:"Html_url"` // "http://localhost:8081/developer/poop"
|
||||||
|
SshUrl string `json:"ssh_url"` // ?!
|
||||||
|
}
|
||||||
|
|
||||||
|
type Task struct {
|
||||||
|
Description string
|
||||||
|
URL string
|
||||||
|
}
|
||||||
|
|
||||||
type Project struct {
|
type Project struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
ShortName string `json:"shortName"`
|
ShortName string `json:"shortName"`
|
||||||
|
|
@ -12,23 +46,6 @@ type ProjectID struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find needed project.ID in the project's list
|
|
||||||
func (plist *ProjectsList) FindProjectByName(searchName string) (string, error) {
|
|
||||||
|
|
||||||
projectID := ""
|
|
||||||
|
|
||||||
for _, elem := range plist.Projects {
|
|
||||||
if elem.ShortName == searchName {
|
|
||||||
projectID = elem.ID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if projectID == "" {
|
|
||||||
return "", fmt.Errorf("project %s doesn't exist", searchName)
|
|
||||||
}
|
|
||||||
return projectID, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type IssueCreateRequest struct {
|
type IssueCreateRequest struct {
|
||||||
ProjectID ProjectID `json:"project"`
|
ProjectID ProjectID `json:"project"`
|
||||||
Key string `json:"idReadable"`
|
Key string `json:"idReadable"`
|
||||||
|
|
@ -53,3 +70,20 @@ type CustomField struct {
|
||||||
type ProjectsList struct {
|
type ProjectsList struct {
|
||||||
Projects []Project
|
Projects []Project
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find needed project.ID in the project's list
|
||||||
|
func (plist *ProjectsList) FindProjectByName(searchName string) (string, error) {
|
||||||
|
|
||||||
|
projectID := ""
|
||||||
|
|
||||||
|
for _, elem := range plist.Projects {
|
||||||
|
if elem.ShortName == searchName {
|
||||||
|
projectID = elem.ID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if projectID == "" {
|
||||||
|
return "", fmt.Errorf("project %s doesn't exist", searchName)
|
||||||
|
}
|
||||||
|
return projectID, nil
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ext
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -6,12 +6,12 @@ import (
|
||||||
"github.com/imroc/req/v3"
|
"github.com/imroc/req/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Client struct {
|
type CommonClient struct {
|
||||||
*req.Client
|
*req.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient() *Client {
|
func NewClient() *CommonClient {
|
||||||
return &Client{req.C().
|
return &CommonClient{req.C().
|
||||||
OnAfterResponse(func(client *req.Client, resp *req.Response) error {
|
OnAfterResponse(func(client *req.Client, resp *req.Response) error {
|
||||||
if resp.Err != nil {
|
if resp.Err != nil {
|
||||||
if dump := resp.Dump(); dump != "" {
|
if dump := resp.Dump(); dump != "" {
|
||||||
|
|
@ -1,21 +1,20 @@
|
||||||
package ext
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
d "ticket-pimp/bot/domain"
|
"ticket-pimp/internal/domain"
|
||||||
"ticket-pimp/bot/helpers"
|
"ticket-pimp/internal/helpers"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Cloud struct {
|
type Cloud struct {
|
||||||
*Client
|
*CommonClient
|
||||||
}
|
}
|
||||||
|
|
||||||
type ICloud interface {
|
type ICloud interface {
|
||||||
CreateFolder(name string) (*d.Folder, error)
|
CreateFolder(name string) (*domain.Folder, error)
|
||||||
ShareToExternals(cloud *d.Folder) (*d.Folder, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCloud(base, user, pass string) *Cloud {
|
func NewCloud(base, user, pass string) *Cloud {
|
||||||
|
|
@ -26,13 +25,13 @@ func NewCloud(base, user, pass string) *Cloud {
|
||||||
SetBaseURL(base)
|
SetBaseURL(base)
|
||||||
|
|
||||||
return &Cloud{
|
return &Cloud{
|
||||||
Client: &Client{
|
CommonClient: &CommonClient{
|
||||||
client,
|
client,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cloud) CreateFolder(name string) (*d.Folder, error) {
|
func (c *Cloud) CreateFolder(name string) (*domain.Folder, error) {
|
||||||
rootDir := os.Getenv("ROOTDIR")
|
rootDir := os.Getenv("ROOTDIR")
|
||||||
user := os.Getenv("CLOUD_USER")
|
user := os.Getenv("CLOUD_USER")
|
||||||
|
|
||||||
|
|
@ -41,7 +40,7 @@ func (c *Cloud) CreateFolder(name string) (*d.Folder, error) {
|
||||||
|
|
||||||
name = helpers.GitNaming(name)
|
name = helpers.GitNaming(name)
|
||||||
|
|
||||||
cloud := d.Folder{
|
cloud := domain.Folder{
|
||||||
Title: name,
|
Title: name,
|
||||||
PrivateURL: "",
|
PrivateURL: "",
|
||||||
}
|
}
|
||||||
|
|
@ -61,12 +60,14 @@ func (c *Cloud) CreateFolder(name string) (*d.Folder, error) {
|
||||||
if err := c.setPrivateURL(requestPath, &cloud); err != nil {
|
if err := c.setPrivateURL(requestPath, &cloud); err != nil {
|
||||||
return &cloud, err
|
return &cloud, err
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println(resp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &cloud, nil
|
return &cloud, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cloud) setPrivateURL(requestPath string, cloud *d.Folder) error {
|
func (c *Cloud) setPrivateURL(requestPath string, cloud *domain.Folder) error {
|
||||||
|
|
||||||
payload := []byte(`<?xml version="1.0"?><a:propfind xmlns:a="DAV:" xmlns:oc="http://owncloud.org/ns"><a:prop><oc:fileid/></a:prop></a:propfind>`)
|
payload := []byte(`<?xml version="1.0"?><a:propfind xmlns:a="DAV:" xmlns:oc="http://owncloud.org/ns"><a:prop><oc:fileid/></a:prop></a:propfind>`)
|
||||||
|
|
||||||
|
|
@ -97,7 +98,3 @@ func (c *Cloud) setPrivateURL(requestPath string, cloud *d.Folder) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cloud) ShareToExternals(cloud *d.Folder) (*d.Folder, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
package ext
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"ticket-pimp/bot/domain"
|
"ticket-pimp/internal/domain"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Coda struct {
|
type Coda struct {
|
||||||
*Client
|
*CommonClient
|
||||||
}
|
}
|
||||||
|
|
||||||
type ICoda interface {
|
type ICoda interface {
|
||||||
|
|
@ -16,15 +16,15 @@ type ICoda interface {
|
||||||
CreateTask(task domain.CodaIssue)
|
CreateTask(task domain.CodaIssue)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCodaClient() *Coda {
|
func NewCodaClient(token string) *Coda {
|
||||||
|
|
||||||
client := NewClient().
|
client := NewClient().
|
||||||
SetTimeout(5 * time.Second).
|
SetTimeout(5 * time.Second).
|
||||||
SetCommonBearerAuthToken("0d5a6853-8bb1-4208-9014-318094f5b21c").
|
SetCommonBearerAuthToken(token).
|
||||||
SetBaseURL("https://coda.io/apis/v1")
|
SetBaseURL("https://coda.io/apis/v1")
|
||||||
|
|
||||||
return &Coda{
|
return &Coda{
|
||||||
Client: &Client{
|
CommonClient: &CommonClient{
|
||||||
client,
|
client,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -48,7 +48,6 @@ func (c *Coda) ListDocs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Print(resp)
|
log.Print(resp)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Coda) CreateTask(task domain.CodaIssue) {
|
func (c *Coda) CreateTask(task domain.CodaIssue) {
|
||||||
|
|
@ -1,20 +1,19 @@
|
||||||
package ext
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"ticket-pimp/bot/domain"
|
"ticket-pimp/internal/domain"
|
||||||
"ticket-pimp/bot/helpers"
|
"ticket-pimp/internal/helpers"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Git struct {
|
type Git struct {
|
||||||
*Client
|
*CommonClient
|
||||||
}
|
}
|
||||||
|
|
||||||
type IGit interface {
|
type IGit interface {
|
||||||
NewRepo(string) (*domain.Git, error)
|
CreateRepo(name string) (*domain.Git, error)
|
||||||
AppsAsCollaboratorTo(*domain.Git) (*domain.Git, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGit(base, token string) *Git {
|
func NewGit(base, token string) *Git {
|
||||||
|
|
@ -31,10 +30,26 @@ func NewGit(base, token string) *Git {
|
||||||
SetBaseURL(base)
|
SetBaseURL(base)
|
||||||
|
|
||||||
return &Git{
|
return &Git{
|
||||||
Client: &Client{client},
|
CommonClient: &CommonClient{client},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gb *Git) CreateRepo(name string) (*domain.Git, error) {
|
||||||
|
//Create git repository with iGit interface;
|
||||||
|
repo, err := gb.newRepo(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set 'apps' as collaborator to created repository;
|
||||||
|
_, err = gb.defaultGroupAsCollaborator(repo)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return repo, nil
|
||||||
|
}
|
||||||
|
|
||||||
type request struct {
|
type request struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Private bool `json:"private"`
|
Private bool `json:"private"`
|
||||||
|
|
@ -44,7 +59,7 @@ type permissionRequest struct {
|
||||||
Perm string `json:"permission"`
|
Perm string `json:"permission"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gb *Git) NewRepo(name string) (*domain.Git, error) {
|
func (gb *Git) newRepo(name string) (*domain.Git, error) {
|
||||||
name = helpers.GitNaming(name)
|
name = helpers.GitNaming(name)
|
||||||
|
|
||||||
payload := request{
|
payload := request{
|
||||||
|
|
@ -61,14 +76,14 @@ func (gb *Git) NewRepo(name string) (*domain.Git, error) {
|
||||||
Post("/user/repos")
|
Post("/user/repos")
|
||||||
|
|
||||||
if resp.Err != nil {
|
if resp.Err != nil {
|
||||||
log.Print(resp.Err)
|
log.Print(resp.Status)
|
||||||
return nil, resp.Err
|
return nil, resp.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &git, nil
|
return &git, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gb *Git) AppsAsCollaboratorTo(git *domain.Git) (*domain.Git, error) {
|
func (gb *Git) defaultGroupAsCollaborator(git *domain.Git) (*domain.Git, error) {
|
||||||
|
|
||||||
payload := permissionRequest{
|
payload := permissionRequest{
|
||||||
Perm: "admin",
|
Perm: "admin",
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
package ext
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
d "ticket-pimp/bot/domain"
|
"ticket-pimp/internal/domain"
|
||||||
|
|
||||||
"github.com/imroc/req/v3"
|
"github.com/imroc/req/v3"
|
||||||
)
|
)
|
||||||
|
|
@ -16,8 +16,8 @@ type youtrack struct {
|
||||||
|
|
||||||
type IYouTrack interface {
|
type IYouTrack interface {
|
||||||
GetProjectIDByName(searchName string) (string, error)
|
GetProjectIDByName(searchName string) (string, error)
|
||||||
CreateIssue(projectID, name, description string) (*d.IssueCreateRequest, error)
|
CreateIssue(projectID, name, description string) (*domain.IssueCreateRequest, error)
|
||||||
UpdateIssue(issue *d.IssueCreateRequest, folder, git, gitBuild string) (*d.IssueUpdateRequest, error)
|
UpdateIssue(issue *domain.IssueCreateRequest, folder, git, gitBuild string) (*domain.IssueUpdateRequest, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewYT(base, token string) *youtrack {
|
func NewYT(base, token string) *youtrack {
|
||||||
|
|
@ -39,9 +39,9 @@ func NewYT(base, token string) *youtrack {
|
||||||
|
|
||||||
// GetProjects
|
// GetProjects
|
||||||
// provides an array of existing projects;
|
// provides an array of existing projects;
|
||||||
func (yt *youtrack) getProjects() (*d.ProjectsList, error) {
|
func (yt *youtrack) getProjects() (*domain.ProjectsList, error) {
|
||||||
|
|
||||||
var projects d.ProjectsList
|
var projects domain.ProjectsList
|
||||||
|
|
||||||
resp, _ := yt.R().
|
resp, _ := yt.R().
|
||||||
EnableDump().
|
EnableDump().
|
||||||
|
|
@ -76,11 +76,11 @@ func (yt *youtrack) GetProjectIDByName(searchName string) (string, error) {
|
||||||
|
|
||||||
// CreateIssue
|
// CreateIssue
|
||||||
// example: newIssue := yt.CreateIssue("0-2", "Summary", "Description");
|
// example: newIssue := yt.CreateIssue("0-2", "Summary", "Description");
|
||||||
func (yt *youtrack) CreateIssue(projectID, name string, description string) (*d.IssueCreateRequest, error) {
|
func (yt *youtrack) CreateIssue(projectID, name string, description string) (*domain.IssueCreateRequest, error) {
|
||||||
|
|
||||||
// Create an issue with the provided:, Project ID, Name, Description;
|
// Create an issue with the provided:, Project ID, Name, Description;
|
||||||
issue := d.IssueCreateRequest{
|
issue := domain.IssueCreateRequest{
|
||||||
ProjectID: d.ProjectID{
|
ProjectID: domain.ProjectID{
|
||||||
ID: projectID, //"id":"0-2"
|
ID: projectID, //"id":"0-2"
|
||||||
},
|
},
|
||||||
Summary: name,
|
Summary: name,
|
||||||
|
|
@ -102,11 +102,11 @@ func (yt *youtrack) CreateIssue(projectID, name string, description string) (*d.
|
||||||
return &issue, nil
|
return &issue, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (yt *youtrack) UpdateIssue(issue *d.IssueCreateRequest, folder, git, gitBuild string) (*d.IssueUpdateRequest, error) {
|
func (yt *youtrack) UpdateIssue(issue *domain.IssueCreateRequest, folder, git, gitBuild string) (*domain.IssueUpdateRequest, error) {
|
||||||
// Set Folder, Git, GitBuild to the Issue:
|
// Set Folder, Git, GitBuild to the Issue:
|
||||||
update := d.IssueUpdateRequest{
|
update := domain.IssueUpdateRequest{
|
||||||
IssueCreateRequest: *issue,
|
IssueCreateRequest: *issue,
|
||||||
CustomFields: []d.CustomField{
|
CustomFields: []domain.CustomField{
|
||||||
{
|
{
|
||||||
Name: "Директория графики",
|
Name: "Директория графики",
|
||||||
Type: "SimpleIssueCustomField",
|
Type: "SimpleIssueCustomField",
|
||||||
Loading…
Reference in New Issue