diff --git a/cmd/fileid.xml b/cmd/fileid.xml new file mode 100644 index 0000000..c0478a2 --- /dev/null +++ b/cmd/fileid.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/controller/controller.go b/controller/controller.go index 0e66f3f..0faba9d 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -3,6 +3,7 @@ package controller import ( "fmt" "sync" + d "ticket-pimp/domain" "ticket-pimp/ext" ) @@ -15,7 +16,7 @@ type WorkflowController struct { type IWorkflowController interface { Workflow(name string) (string, error) CreateRepo(name string, param uint) (string, error) - CreateFolder(name string) (string, string, error) + CreateFolder(name string) (*d.Cloud, error) } func NewWorkflowController( @@ -51,7 +52,8 @@ func (wc *WorkflowController) Workflow(name string) (string, error) { if issue != nil { var ( - git, gitBuild, folder string + git, gitBuild string + cloud *d.Cloud ) var wg sync.WaitGroup @@ -67,14 +69,14 @@ func (wc *WorkflowController) Workflow(name string) (string, error) { gitBuild, _ = wc.CreateRepo(issue.Key+"-build", 1) }() - go func() { + go func(ref **d.Cloud) { defer wg.Done() - _, folder, _ = wc.CreateFolder(issue.Key + " - " + issue.Summary) - }() + *ref, _ = wc.CreateFolder(issue.Key + " - " + issue.Summary) + }(&cloud) wg.Wait() - yt.UpdateIssue(issue, folder, git, gitBuild) + yt.UpdateIssue(issue, cloud.FolderURL, git, gitBuild) } return issue.Key, nil } @@ -101,13 +103,17 @@ func (wc *WorkflowController) CreateRepo(name string, param uint) (string, error return "", err } -func (wc *WorkflowController) CreateFolder(name string) (string, string, error) { +func (wc *WorkflowController) CreateFolder(name string) (*d.Cloud, error) { //Create ownCloud folder w/ iCloud interface; cloud, err := wc.iCloud.CreateFolder(name) if cloud == nil { - return "", "", err + return cloud, err } - return cloud.FolderName, cloud.FolderPath, err + /* [ ] Experimental call: + wc.iCloud.ShareToExternals(cloud) + */ + + return cloud, err } diff --git a/domain/cloud.go b/domain/cloud.go new file mode 100644 index 0000000..729b48f --- /dev/null +++ b/domain/cloud.go @@ -0,0 +1,8 @@ +package domain + +type Cloud struct { + FolderName string // "k" + FolderPath string // "/temp/k" + FolderURL string // "http://82.151.222.22:7000/apps/files/?dir=/temp/k" + PublicURL string +} diff --git a/domain/youtrack.go b/domain/youtrack.go new file mode 100644 index 0000000..6f47f2a --- /dev/null +++ b/domain/youtrack.go @@ -0,0 +1,32 @@ +package domain + +type Project struct { + ID string `json:"id"` + ShortName string `json:"shortName"` + Name string `json:"name"` +} + +type ProjectID struct { + ID string `json:"id"` +} + +type IssueCreateRequest struct { + ProjectID ProjectID `json:"project"` + Key string `json:"idReadable"` + ID string `json:"id"` + Summary string `json:"summary"` + Description string `json:"description"` +} + +// [ ] try `,omitempty` to remove extra struct; + +type IssueUpdateRequest struct { + IssueCreateRequest + CustomFields []CustomField `json:"customFields"` +} + +type CustomField struct { + Name string `json:"name"` + Type string `json:"$type"` + Value string `json:"value"` +} diff --git a/ext/cloud.go b/ext/cloud.go index 834d817..b93fa11 100644 --- a/ext/cloud.go +++ b/ext/cloud.go @@ -1,20 +1,23 @@ package ext import ( + "encoding/xml" + "fmt" + "io/ioutil" + "log" "os" + "ticket-pimp/domain" "ticket-pimp/helpers" "time" ) type Cloud struct { - //[ ] out in separate domain struct - FolderName string - FolderPath string *Client } type ICloud interface { - CreateFolder(name string) (*Cloud, error) + CreateFolder(name string) (*domain.Cloud, error) + ShareToExternals(cloud *domain.Cloud) (*domain.Cloud, error) } func NewCloud(base, user, pass string) *Cloud { @@ -25,32 +28,88 @@ func NewCloud(base, user, pass string) *Cloud { SetBaseURL(base) return &Cloud{ - FolderName: "", - FolderPath: "", Client: &Client{ client, }, } } -func (c *Cloud) CreateFolder(name string) (*Cloud, error) { +func (c *Cloud) CreateFolder(name string) (*domain.Cloud, error) { + rootDir := os.Getenv("ROOTDIR") name = helpers.GitNaming(name) - cloud := Cloud{ + cloud := domain.Cloud{ FolderName: name, - FolderPath: "", + FolderURL: "", } - pathName := os.Getenv("HOMEPATH") + name + requestPath := os.Getenv("HOMEPATH") + rootDir + name + cloud.FolderPath = os.Getenv("FOLDER_PATH") + rootDir + name resp, err := c.R(). - Send("MKCOL", pathName) + Send("MKCOL", requestPath) if resp.IsSuccessState() { - cloud.FolderPath = c.BaseURL + os.Getenv("FOLDER_PATH") + name + + cloud.FolderURL = c.BaseURL + cloud.FolderPath + + /* + type ResponseObj struct { + Multistatus struct { + Response struct { + Href struct { + Propstat struct { + Prop struct { + FileID int `json:"oc:fileid"` + } `json:"d:prop"` + } `json:"d:propstat"` + } `json:"d:href"` + } `json:"d:response"` + } `json:"d:multistatus"` + }*/ + + type ResponseObj struct { + XMLName xml.Name `xml:"d:multistatus"` + Multistatus struct { + XMLName xml.Name `xml:"d:multistatus"` + Response struct { + Href struct { + Propstat struct { + Prop struct { + FileID string `xml:"oc:fileid"` + } `xml:"d:prop"` + } `xml:"d:propstat"` + } `xml:"d:href"` + } `xml:"d:response"` + } `xml:"d:multistatus"` + } + + xmlFile, err := ioutil.ReadFile("./fileid.xml") + + if err != nil { + fmt.Println(err) + return nil, err // fix this return; + } + + var id ResponseObj + + resp, _ := c.R(). + SetBody(xmlFile). + Send("PROPFIND", os.Getenv("HOMEPATH")+os.Getenv("ROOTDIR")+cloud.FolderName) + + xmlEncodingErr := resp.UnmarshalXml(&id) + if xmlEncodingErr != nil { + log.Print(err) + } + + log.Print(resp) } return &cloud, err } + +func (c *Cloud) ShareToExternals(cloud *domain.Cloud) (*domain.Cloud, error) { + return nil, nil +} diff --git a/ext/git.go b/ext/git.go index a798ada..1fadb40 100644 --- a/ext/git.go +++ b/ext/git.go @@ -10,7 +10,6 @@ import ( type Git struct { *Client - *domain.Git } type IGit interface { @@ -33,15 +32,6 @@ func NewGit(base, token string) *Git { return &Git{ Client: &Client{client}, - Git: &domain.Git{ - Name: "", - FullName: "", - Private: true, - Url: "", - CloneUrl: "", - HtmlUrl: "", - SshUrl: "", - }, } } @@ -63,6 +53,7 @@ func (gb *Git) NewRepo(name string) (*domain.Git, error) { } var git domain.Git + git.Private = true resp, err := gb.R(). SetBody(&payload). @@ -77,6 +68,7 @@ func (gb *Git) NewRepo(name string) (*domain.Git, error) { } func (gb *Git) AppsAsCollaboratorTo(git *domain.Git) (*domain.Git, error) { + payloadPermission := permissionRequest{ Perm: "admin", } diff --git a/ext/yt.go b/ext/yt.go index 7f54fb9..0f4af58 100644 --- a/ext/yt.go +++ b/ext/yt.go @@ -5,6 +5,8 @@ import ( "log" "time" + d "ticket-pimp/domain" + "github.com/imroc/req/v3" ) @@ -13,9 +15,9 @@ type youtrack struct { } type IYouTrack interface { - GetProjects() ([]Project, error) - CreateIssue(projectID, name string) (*IssueCreateRequest, error) - UpdateIssue(issue *IssueCreateRequest, folder, git, gitBuild string) (*IssueUpdateRequest, error) + GetProjects() ([]d.Project, error) + CreateIssue(projectID, name string) (*d.IssueCreateRequest, error) + UpdateIssue(issue *d.IssueCreateRequest, folder, git, gitBuild string) (*d.IssueUpdateRequest, error) } func NewYT(base, token string) *youtrack { @@ -35,17 +37,11 @@ func NewYT(base, token string) *youtrack { } } -type Project struct { - ID string `json:"id"` - ShortName string `json:"shortName"` - Name string `json:"name"` -} - // GetProjects // provides an array of existing projects; -func (yt *youtrack) GetProjects() ([]Project, error) { +func (yt *youtrack) GetProjects() ([]d.Project, error) { - var projects []Project + var projects []d.Project _, err := yt.R(). EnableDump(). @@ -61,25 +57,13 @@ func (yt *youtrack) GetProjects() ([]Project, error) { return projects, nil } -type ProjectID struct { - ID string `json:"id"` -} - -type IssueCreateRequest struct { - ProjectID ProjectID `json:"project"` - Key string `json:"idReadable"` - ID string `json:"id"` - Summary string `json:"summary"` - Description string `json:"description"` -} - // CreateIssue // example: newIssue := yt.CreateIssue("0-2", "Summary", "Description"); -func (yt *youtrack) CreateIssue(projectID, name string) (*IssueCreateRequest, error) { +func (yt *youtrack) CreateIssue(projectID, name string) (*d.IssueCreateRequest, error) { // Create an issue with the provided:, Project ID, Name, Description; - issue := IssueCreateRequest{ - ProjectID: ProjectID{ + issue := d.IssueCreateRequest{ + ProjectID: d.ProjectID{ ID: projectID, //"id":"0-2" }, Summary: name, @@ -101,26 +85,11 @@ func (yt *youtrack) CreateIssue(projectID, name string) (*IssueCreateRequest, er return &issue, nil } -type IssueUpdateRequest struct { - IssueCreateRequest - CustomFields []CustomField `json:"customFields"` -} - -type CustomFields struct { - List []CustomField `json:"customFields"` -} - -type CustomField struct { - Name string `json:"name"` - Type string `json:"$type"` - Value string `json:"value"` -} - -func (yt *youtrack) UpdateIssue(issue *IssueCreateRequest, folder, git, gitBuild string) (*IssueUpdateRequest, error) { +func (yt *youtrack) UpdateIssue(issue *d.IssueCreateRequest, folder, git, gitBuild string) (*d.IssueUpdateRequest, error) { // Set Folder, Git, GitBuild to the Issue: - update := IssueUpdateRequest{ + update := d.IssueUpdateRequest{ IssueCreateRequest: *issue, - CustomFields: []CustomField{ + CustomFields: []d.CustomField{ { Name: "Директория графики", Type: "SimpleIssueCustomField", diff --git a/go.mod b/go.mod index 8b44822..9a3ff88 100644 --- a/go.mod +++ b/go.mod @@ -19,6 +19,7 @@ require ( github.com/quic-go/qtls-go1-19 v0.3.2 // indirect github.com/quic-go/qtls-go1-20 v0.2.2 // indirect github.com/quic-go/quic-go v0.35.1 // indirect + github.com/studio-b12/gowebdav v0.0.0-20230203202212-3282f94193f2 // indirect github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce // indirect golang.org/x/crypto v0.9.0 // indirect golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect diff --git a/go.sum b/go.sum index 9db009a..8242e11 100644 --- a/go.sum +++ b/go.sum @@ -38,6 +38,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/studio-b12/gowebdav v0.0.0-20230203202212-3282f94193f2 h1:VsBj3UD2xyAOu7kJw6O/2jjG2UXLFoBzihqDU9Ofg9M= +github.com/studio-b12/gowebdav v0.0.0-20230203202212-3282f94193f2/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE= github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce h1:fb190+cK2Xz/dvi9Hv8eCYJYvIGUTN2/KLq1pT6CjEc= github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= diff --git a/handler/handler.go b/handler/handler.go index f134246..32e8975 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -17,7 +17,14 @@ type Handler struct { func NewHandler(gitBaseURL, gitToken, cloudBaseURL, cloudAuthUser, cloudAuthPass, ytBaseURL, ytToken string) *Handler { return &Handler{ - workflow: controller.NewWorkflowController(gitBaseURL, gitToken, cloudBaseURL, cloudAuthUser, cloudAuthPass, ytBaseURL, ytToken), + workflow: controller.NewWorkflowController( + gitBaseURL, + gitToken, + cloudBaseURL, + cloudAuthUser, + cloudAuthPass, + ytBaseURL, + ytToken), } } @@ -52,15 +59,6 @@ func (h *Handler) NewRepoHandler(ctx context.Context, mu *tgb.MessageUpdate) err return mu.Answer(newRepoAnswer(repoStr)).ParseMode(tg.HTML).DoVoid(ctx) } -func newFolderAnswer(name string) string { - return tg.HTML.Text( - tg.HTML.Line( - "Folder ", - name, - "has been created!", - ), - ) -} func (h *Handler) NewFolderHandler(ctx context.Context, mu *tgb.MessageUpdate) error { str := strings.Replace(mu.Text, "/folder", "", 1) @@ -69,13 +67,23 @@ func (h *Handler) NewFolderHandler(ctx context.Context, mu *tgb.MessageUpdate) e return errors.New("empty command provided") } - nameStr, _, err := h.workflow.CreateFolder(str) + cloud, err := h.workflow.CreateFolder(str) if err != nil { return mu.Answer(errorAnswer(err.Error())).ParseMode(tg.HTML).DoVoid(ctx) } - return mu.Answer(newFolderAnswer(nameStr)).ParseMode(tg.HTML).DoVoid(ctx) + answer := tg.HTML.Text( + tg.HTML.Line( + "✨ Shiny folder", + tg.HTML.Link(cloud.FolderName, cloud.FolderURL), + "has been created!", + ), + ) + + return mu.Answer(answer). + ParseMode(tg.HTML). + DoVoid(ctx) } func errorAnswer(errorMsg string) string { diff --git a/helpers/helpers_test.go b/helpers/helpers_test.go index bf22d06..3e877a4 100644 --- a/helpers/helpers_test.go +++ b/helpers/helpers_test.go @@ -1,6 +1,8 @@ package helpers -import "testing" +import ( + "testing" +) type test struct { arg, expected string diff --git a/helpers/xml_test.go b/helpers/xml_test.go new file mode 100644 index 0000000..7efcd37 --- /dev/null +++ b/helpers/xml_test.go @@ -0,0 +1,59 @@ +package helpers + +import ( + "encoding/xml" + "fmt" + "log" + "testing" +) + +/* + + + + + /remote.php/dav/files/naudachu/temp/id/ + + + 33225 + + HTTP/1.1 200 OK + + + + +*/ + +type MultistatusObj struct { + XMLName xml.Name `xml:"multistatus"` + Multistatus struct { + ResponseObj + } +} + +type ResponseObj struct { + XMLName xml.Name `xml:"response"` + Response struct { + Content string `xml:",chardata"` + } +} + +const ( + EXAMPLE = "\n/remote.php/dav/files/naudachu/temp/id/33225HTTP/1.1 200 OK\n" +) + +func GetFileID(str string) string { + + var multi MultistatusObj + err := xml.Unmarshal([]byte(str), &multi) + if err != nil { + fmt.Print(err) + } + return multi.Multistatus.Response.Content +} + +func TestGetFileID(t *testing.T) { + str := GetFileID(EXAMPLE) + log.Print(str) + +}