Change label management to rely on independent rest calls

This commit is contained in:
Camiel de Vleeschauwer 2024-06-11 22:57:31 +12:00 committed by Manuel Rüger
parent d168ec8b14
commit 4a3a69b997
3 changed files with 135 additions and 12 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@
.idea/ .idea/
/mark.test /mark.test
/profile.cov /profile.cov
.vscode

65
main.go
View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"slices"
"strings" "strings"
"time" "time"
@ -522,6 +523,8 @@ func processFile(
log.Fatal(err) log.Fatal(err)
} }
updateLabels(err, api, target, meta)
if cCtx.Bool("edit-lock") { if cCtx.Bool("edit-lock") {
log.Infof( log.Infof(
nil, nil,
@ -539,6 +542,68 @@ func processFile(
return target return target
} }
func updateLabels(api *confluence.API, target *confluence.PageInfo, meta *mark.Meta) {
labelInfo, err := api.GetPageLabels(target, "global")
if err != nil {
log.Fatal(err)
}
log.Debug("Page Labels:")
log.Debug(labelInfo.Labels)
log.Debug("Meta Labels:")
log.Debug(meta.Labels)
delLabels := determineLabelsToRemove(labelInfo, meta)
log.Debug("Del Labels:")
log.Debug(delLabels)
addLabels := determineLabelsToAdd(meta, labelInfo)
log.Debug("Add Labels:")
log.Debug(addLabels)
if len(addLabels) > 0 {
_, err = api.AddPageLabels(target, addLabels)
if err != nil {
log.Fatal(err)
}
}
for _, label := range delLabels {
_, err = api.DeletePageLabel(target, label)
if err != nil {
log.Fatal(err)
}
}
}
// Page has label but label not in Metadata
func determineLabelsToRemove(labelInfo *confluence.LabelInfo, meta *mark.Meta) []string {
var labels []string
for _, label := range labelInfo.Labels {
if !slices.ContainsFunc(meta.Labels, func(metaLabel string) bool {
return strings.ToLower(metaLabel) == strings.ToLower(label.Name)
}) {
labels = append(labels, label.Name)
}
}
return labels
}
// Metadata has label but Page does not have it
func determineLabelsToAdd(meta *mark.Meta, labelInfo *confluence.LabelInfo) []string {
var labels []string
for _, metaLabel := range meta.Labels {
if !slices.ContainsFunc(labelInfo.Labels, func(label confluence.Label) bool {
return strings.ToLower(label.Name) == strings.ToLower(metaLabel)
}) {
labels = append(labels, metaLabel)
}
}
return labels
}
func configFilePath() string { func configFilePath() string {
fp, err := os.UserConfigDir() fp, err := os.UserConfigDir()
if err != nil { if err != nil {

View File

@ -73,6 +73,15 @@ type AttachmentInfo struct {
} `json:"_links"` } `json:"_links"`
} }
type Label struct {
ID string `json:"id"`
Prefix string `json:"prefix"`
Name string `json:"name"`
}
type LabelInfo struct {
Labels []Label `json:"results"`
Size int `json:"number"`
}
type form struct { type form struct {
buffer io.Reader buffer io.Reader
writer *multipart.Writer writer *multipart.Writer
@ -514,17 +523,6 @@ func (api *API) UpdatePage(page *PageInfo, newContent string, minorEdit bool, ve
} }
} }
labels := []map[string]interface{}{}
for _, label := range newLabels {
if label != "" {
item := map[string]interface{}{
"prexix": "global",
"name": label,
}
labels = append(labels, item)
}
}
payload := map[string]interface{}{ payload := map[string]interface{}{
"id": page.ID, "id": page.ID,
"type": page.Type, "type": page.Type,
@ -542,7 +540,6 @@ func (api *API) UpdatePage(page *PageInfo, newContent string, minorEdit bool, ve
}, },
}, },
"metadata": map[string]interface{}{ "metadata": map[string]interface{}{
"labels": labels,
// Fix to set full-width as has changed on Confluence APIs again. // Fix to set full-width as has changed on Confluence APIs again.
// https://jira.atlassian.com/browse/CONFCLOUD-65447 // https://jira.atlassian.com/browse/CONFCLOUD-65447
// //
@ -570,6 +567,66 @@ func (api *API) UpdatePage(page *PageInfo, newContent string, minorEdit bool, ve
return nil return nil
} }
func (api *API) AddPageLabels(page *PageInfo, newLabels []string) (*LabelInfo, error) {
labels := []map[string]interface{}{}
for _, label := range newLabels {
if label != "" {
item := map[string]interface{}{
"prefix": "global",
"name": label,
}
labels = append(labels, item)
}
}
payload := labels
request, err := api.rest.Res(
"content/"+page.ID+"/label", &LabelInfo{},
).Post(payload)
if err != nil {
return nil, err
}
if request.Raw.StatusCode != http.StatusOK {
return nil, newErrorStatusNotOK(request)
}
return request.Response.(*LabelInfo), nil
}
func (api *API) DeletePageLabel(page *PageInfo, label string) (*LabelInfo, error) {
request, err := api.rest.Res(
"content/"+page.ID+"/label/"+label, &LabelInfo{},
).Delete()
if err != nil {
return nil, err
}
if request.Raw.StatusCode != http.StatusOK {
return nil, newErrorStatusNotOK(request)
}
return request.Response.(*LabelInfo), nil
}
func (api *API) GetPageLabels(page *PageInfo, prefix string) (*LabelInfo, error) {
request, err := api.rest.Res(
"content/"+page.ID+"/label", &LabelInfo{},
).Get(map[string]string{"prefix": prefix})
if err != nil {
return nil, err
}
if request.Raw.StatusCode != http.StatusOK {
return nil, newErrorStatusNotOK(request)
}
return request.Response.(*LabelInfo), nil
}
func (api *API) GetUserByName(name string) (*User, error) { func (api *API) GetUserByName(name string) (*User, error) {
var response struct { var response struct {
Results []struct { Results []struct {