Merge pull request #6 from naudachu/refactoring-august

- fixed all issues w/ servises;
This commit is contained in:
naudachu 2023-09-01 19:04:13 +05:00 committed by GitHub
commit 232f009c49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 604 additions and 391 deletions

View File

@ -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
} }

View File

@ -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
}

View File

@ -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);
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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"`
}

View File

@ -1,5 +0,0 @@
package domain
type ConversionLog struct {
Advertiser []string
}

View File

@ -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"` // ?!
}

View File

@ -1,6 +0,0 @@
package domain
type Task struct {
Description string
URL string
}

View File

@ -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, " ")

View File

@ -2,7 +2,7 @@ package handler
import ( import (
"testing" "testing"
"ticket-pimp/bot/domain" "ticket-pimp/internal/domain"
) )
type test struct { type test struct {

23
cmd/dev.env Normal file
View File

@ -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"

View File

@ -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(

View File

@ -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:

View File

@ -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"]

View File

@ -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);
}
}
}

View File

@ -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.

View File

@ -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-----

View File

@ -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

View File

@ -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
}

View File

@ -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 != "" {

View File

@ -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
}

View File

@ -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) {

View File

@ -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",

View File

@ -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",