Create pagetree from API request
This commit is contained in:
parent
60fd356d4c
commit
82e36eacc1
7
go.mod
Normal file
7
go.mod
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
module confluence-pagetree
|
||||||
|
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
require github.com/alexflint/go-arg v1.4.3
|
||||||
|
|
||||||
|
require github.com/alexflint/go-scalar v1.1.0 // indirect
|
16
go.sum
Normal file
16
go.sum
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
github.com/alexflint/go-arg v1.4.3 h1:9rwwEBpMXfKQKceuZfYcwuc/7YY7tWJbFsgG5cAU/uo=
|
||||||
|
github.com/alexflint/go-arg v1.4.3/go.mod h1:3PZ/wp/8HuqRZMUUgu7I+e1qcpUbvmS258mRXkFH4IA=
|
||||||
|
github.com/alexflint/go-scalar v1.1.0 h1:aaAouLLzI9TChcPXotr6gUhq+Scr8rl0P9P4PnltbhM=
|
||||||
|
github.com/alexflint/go-scalar v1.1.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
190
main.go
Normal file
190
main.go
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/alexflint/go-arg"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NodeData struct {
|
||||||
|
id string
|
||||||
|
title string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Node struct {
|
||||||
|
children []*Node
|
||||||
|
data NodeData
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n Node) printChildren(level int) {
|
||||||
|
log.Printf("%v%v", strings.Repeat("\t", level), n.data.title)
|
||||||
|
// leaf note
|
||||||
|
if len(n.children) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, child := range n.children {
|
||||||
|
child.printChildren(level + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) getChildWithID(id string) (node *Node, hasChild bool) {
|
||||||
|
for _, c := range n.children {
|
||||||
|
if c.data.id == id {
|
||||||
|
return c, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
empty := Node{}
|
||||||
|
return &empty, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) addChild(child *Node) {
|
||||||
|
n.children = append(n.children, child)
|
||||||
|
}
|
||||||
|
|
||||||
|
type spaceResult struct {
|
||||||
|
Results []struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Ancestors []struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
MacroRenderedOutput struct {
|
||||||
|
} `json:"macroRenderedOutput"`
|
||||||
|
Extensions struct {
|
||||||
|
Position int `json:"position"`
|
||||||
|
} `json:"extensions"`
|
||||||
|
Expandable struct {
|
||||||
|
Container string `json:"container"`
|
||||||
|
Metadata string `json:"metadata"`
|
||||||
|
Restrictions string `json:"restrictions"`
|
||||||
|
History string `json:"history"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
Descendants string `json:"descendants"`
|
||||||
|
Space string `json:"space"`
|
||||||
|
ChildTypes string `json:"childTypes"`
|
||||||
|
Operations string `json:"operations"`
|
||||||
|
SchedulePublishDate string `json:"schedulePublishDate"`
|
||||||
|
Children string `json:"children"`
|
||||||
|
Ancestors string `json:"ancestors"`
|
||||||
|
} `json:"_expandable"`
|
||||||
|
Links struct {
|
||||||
|
Self string `json:"self"`
|
||||||
|
Tinyui string `json:"tinyui"`
|
||||||
|
Editui string `json:"editui"`
|
||||||
|
Webui string `json:"webui"`
|
||||||
|
} `json:"_links"`
|
||||||
|
} `json:"ancestors"`
|
||||||
|
MacroRenderedOutput struct {
|
||||||
|
} `json:"macroRenderedOutput"`
|
||||||
|
Extensions struct {
|
||||||
|
Position int `json:"position"`
|
||||||
|
} `json:"extensions"`
|
||||||
|
Expandable struct {
|
||||||
|
ChildTypes string `json:"childTypes"`
|
||||||
|
Container string `json:"container"`
|
||||||
|
Metadata string `json:"metadata"`
|
||||||
|
Operations string `json:"operations"`
|
||||||
|
SchedulePublishDate string `json:"schedulePublishDate"`
|
||||||
|
Children string `json:"children"`
|
||||||
|
Restrictions string `json:"restrictions"`
|
||||||
|
History string `json:"history"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
Descendants string `json:"descendants"`
|
||||||
|
Space string `json:"space"`
|
||||||
|
} `json:"_expandable"`
|
||||||
|
Links struct {
|
||||||
|
Self string `json:"self"`
|
||||||
|
Tinyui string `json:"tinyui"`
|
||||||
|
Editui string `json:"editui"`
|
||||||
|
Webui string `json:"webui"`
|
||||||
|
} `json:"_links"`
|
||||||
|
} `json:"results"`
|
||||||
|
Start int `json:"start"`
|
||||||
|
Limit int `json:"limit"`
|
||||||
|
Size int `json:"size"`
|
||||||
|
Links struct {
|
||||||
|
Base string `json:"base"`
|
||||||
|
Context string `json:"context"`
|
||||||
|
Next string `json:"next"`
|
||||||
|
Self string `json:"self"`
|
||||||
|
} `json:"_links"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSpaceChildren(url, user, token string) spaceResult {
|
||||||
|
b64Auth := base64.StdEncoding.EncodeToString([]byte(user + ":" + token))
|
||||||
|
client := &http.Client{}
|
||||||
|
req, err := http.NewRequest(http.MethodGet, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
req.Header.Add("Authorization", "Basic "+b64Auth)
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
log.Fatalf("Error fetching url: %v, status code: %v", url, resp.StatusCode)
|
||||||
|
}
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
var result spaceResult
|
||||||
|
json.Unmarshal(body, &result)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func createPageTree(s *spaceResult) {
|
||||||
|
var parent *Node
|
||||||
|
root := Node{data: NodeData{title: "root"}}
|
||||||
|
for _, page := range s.Results {
|
||||||
|
parent = &root
|
||||||
|
// ignore the root node
|
||||||
|
if len(page.Ancestors) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// create branches from ancestors
|
||||||
|
for i, ancestor := range page.Ancestors {
|
||||||
|
// skip root node
|
||||||
|
if i == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
node, hasChild := parent.getChildWithID(ancestor.ID)
|
||||||
|
if hasChild {
|
||||||
|
parent = node
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
n := Node{data: NodeData{id: ancestor.ID, title: ancestor.Title}}
|
||||||
|
parent.addChild(&n)
|
||||||
|
parent = &n
|
||||||
|
}
|
||||||
|
// create leaf node
|
||||||
|
n := Node{data: NodeData{id: page.ID, title: page.Title}}
|
||||||
|
parent.addChild(&n)
|
||||||
|
}
|
||||||
|
root.printChildren(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var args struct {
|
||||||
|
Baseurl string `arg:"required" help:"Base URL of the Confluence instance (required)"`
|
||||||
|
Spacekey string `arg:"required" help:"Spacekey to export (required)"`
|
||||||
|
User string `arg:"required" help:"User used for authentication (required)"`
|
||||||
|
Token string `arg:"required" help:"Token used for authentication (required)"`
|
||||||
|
}
|
||||||
|
arg.MustParse(&args)
|
||||||
|
url := args.Baseurl + "/wiki/rest/api/space/" + args.Spacekey + "/content/page?expand=ancestors&limit=9999"
|
||||||
|
result := getSpaceChildren(url, args.User, args.Token)
|
||||||
|
createPageTree(&result)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user