Add Type metadata header to enable support for Confluence Blog Posts

This commit is contained in:
David Laing 2021-03-31 17:49:01 +01:00
parent 12510a1208
commit 07aa3700eb
7 changed files with 52 additions and 21 deletions

View File

@ -44,6 +44,13 @@ Also, optional following headers are supported:
reading; reading;
* plain: content will fill all page; * plain: content will fill all page;
```markdown
<!-- Type: (page|blogpost) -->
```
* (default) page: normal Confluence page - defaults to this if omitted
* blogpost: [Blog post](https://confluence.atlassian.com/doc/blog-posts-834222533.html) in `Space`. Cannot have `Parent`(s)
Mark supports Go templates, which can be included into article by using path Mark supports Go templates, which can be included into article by using path
to the template relative to current working dir, e.g.: to the template relative to current working dir, e.g.:

View File

@ -191,16 +191,18 @@ func main() {
if err != nil { if err != nil {
log.Fatalf( log.Fatalf(
karma.Describe("title", meta.Title).Reason(err), karma.Describe("title", meta.Title).Reason(err),
"unable to resolve page", "unable to resolve %s",
meta.Type,
) )
} }
if page == nil { if page == nil {
page, err = api.CreatePage(meta.Space, parent, meta.Title, ``) page, err = api.CreatePage(meta.Space, meta.Type, parent, meta.Title, ``)
if err != nil { if err != nil {
log.Fatalf( log.Fatalf(
err, err,
"can't create page %q", "can't create %s %q",
meta.Type,
meta.Title, meta.Title,
) )
} }

View File

@ -33,6 +33,7 @@ type API struct {
type PageInfo struct { type PageInfo struct {
ID string `json:"id"` ID string `json:"id"`
Title string `json:"title"` Title string `json:"title"`
Type string `json:"type"`
Version struct { Version struct {
Number int64 `json:"number"` Number int64 `json:"number"`
@ -95,7 +96,7 @@ func NewAPI(baseURL string, username string, password string) *API {
} }
func (api *API) FindRootPage(space string) (*PageInfo, error) { func (api *API) FindRootPage(space string) (*PageInfo, error) {
page, err := api.FindPage(space, ``) page, err := api.FindPage(space, ``, "page")
if err != nil { if err != nil {
return nil, karma.Format( return nil, karma.Format(
err, err,
@ -121,7 +122,7 @@ func (api *API) FindRootPage(space string) (*PageInfo, error) {
}, nil }, nil
} }
func (api *API) FindPage(space string, title string) (*PageInfo, error) { func (api *API) FindPage(space string, title string, pageType string) (*PageInfo, error) {
result := struct { result := struct {
Results []PageInfo `json:"results"` Results []PageInfo `json:"results"`
}{} }{}
@ -129,6 +130,7 @@ func (api *API) FindPage(space string, title string) (*PageInfo, error) {
payload := map[string]string{ payload := map[string]string{
"spaceKey": space, "spaceKey": space,
"expand": "ancestors,version", "expand": "ancestors,version",
"type": pageType,
} }
if title != "" { if title != "" {
@ -388,12 +390,13 @@ func (api *API) GetPageByID(pageID string) (*PageInfo, error) {
func (api *API) CreatePage( func (api *API) CreatePage(
space string, space string,
pageType string,
parent *PageInfo, parent *PageInfo,
title string, title string,
body string, body string,
) (*PageInfo, error) { ) (*PageInfo, error) {
payload := map[string]interface{}{ payload := map[string]interface{}{
"type": "page", "type": pageType,
"title": title, "title": title,
"space": map[string]interface{}{ "space": map[string]interface{}{
"key": space, "key": space,
@ -437,7 +440,9 @@ func (api *API) UpdatePage(
page *PageInfo, newContent string, minorEdit bool, newLabels []string, page *PageInfo, newContent string, minorEdit bool, newLabels []string,
) error { ) error {
nextPageVersion := page.Version.Number + 1 nextPageVersion := page.Version.Number + 1
oldAncestors := []map[string]interface{}{}
if page.Type != "blogpost" {
if len(page.Ancestors) == 0 { if len(page.Ancestors) == 0 {
return fmt.Errorf( return fmt.Errorf(
"page %q info does not contain any information about parents", "page %q info does not contain any information about parents",
@ -446,9 +451,10 @@ func (api *API) UpdatePage(
} }
// picking only the last one, which is required by confluence // picking only the last one, which is required by confluence
oldAncestors := []map[string]interface{}{ oldAncestors = []map[string]interface{}{
{"id": page.Ancestors[len(page.Ancestors)-1].Id}, {"id": page.Ancestors[len(page.Ancestors)-1].Id},
} }
}
labels := []map[string]interface{}{} labels := []map[string]interface{}{}
for _, label := range newLabels { for _, label := range newLabels {
@ -463,7 +469,7 @@ func (api *API) UpdatePage(
payload := map[string]interface{}{ payload := map[string]interface{}{
"id": page.ID, "id": page.ID,
"type": "page", "type": page.Type,
"title": page.Title, "title": page.Title,
"version": map[string]interface{}{ "version": map[string]interface{}{
"number": nextPageVersion, "number": nextPageVersion,

View File

@ -20,7 +20,7 @@ func EnsureAncestry(
rest := ancestry rest := ancestry
for i, title := range ancestry { for i, title := range ancestry {
page, err := api.FindPage(space, title) page, err := api.FindPage(space, title, "page")
if err != nil { if err != nil {
return nil, karma.Format( return nil, karma.Format(
err, err,
@ -66,7 +66,7 @@ func EnsureAncestry(
if !dryRun { if !dryRun {
for _, title := range rest { for _, title := range rest {
page, err := api.CreatePage(space, parent, title, ``) page, err := api.CreatePage(space, "page", parent, title, ``)
if err != nil { if err != nil {
return nil, karma.Format( return nil, karma.Format(
err, err,
@ -95,7 +95,7 @@ func ValidateAncestry(
space string, space string,
ancestry []string, ancestry []string,
) (*confluence.PageInfo, error) { ) (*confluence.PageInfo, error) {
page, err := api.FindPage(space, ancestry[len(ancestry)-1]) page, err := api.FindPage(space, ancestry[len(ancestry)-1], "page")
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -163,7 +163,7 @@ func getConfluenceLink(api *confluence.API, space, title string) (string, error)
url.QueryEscape(title), url.QueryEscape(title),
) )
page, err := api.FindPage(space, title) page, err := api.FindPage(space, title, "page")
if err != nil { if err != nil {
return "", karma.Format(err, "api: find page") return "", karma.Format(err, "api: find page")
} }

View File

@ -13,7 +13,7 @@ func ResolvePage(
api *confluence.API, api *confluence.API,
meta *Meta, meta *Meta,
) (*confluence.PageInfo, *confluence.PageInfo, error) { ) (*confluence.PageInfo, *confluence.PageInfo, error) {
page, err := api.FindPage(meta.Space, meta.Title) page, err := api.FindPage(meta.Space, meta.Title, meta.Type)
if err != nil { if err != nil {
return nil, nil, karma.Format( return nil, nil, karma.Format(
err, err,
@ -22,6 +22,16 @@ func ResolvePage(
) )
} }
if meta.Type == "blogpost" {
log.Infof(
nil,
"Blog post will be stored as: %s",
meta.Title,
)
return nil, page, nil
}
ancestry := meta.Parents ancestry := meta.Parents
if page != nil { if page != nil {
ancestry = append(ancestry, page.Title) ancestry = append(ancestry, page.Title)

View File

@ -13,6 +13,7 @@ import (
const ( const (
HeaderParent = `Parent` HeaderParent = `Parent`
HeaderSpace = `Space` HeaderSpace = `Space`
HeaderType = `Type`
HeaderTitle = `Title` HeaderTitle = `Title`
HeaderLayout = `Layout` HeaderLayout = `Layout`
HeaderAttachment = `Attachment` HeaderAttachment = `Attachment`
@ -23,6 +24,7 @@ const (
type Meta struct { type Meta struct {
Parents []string Parents []string
Space string Space string
Type string
Title string Title string
Layout string Layout string
Attachments map[string]string Attachments map[string]string
@ -67,6 +69,7 @@ func ExtractMeta(data []byte) (*Meta, []byte, error) {
if meta == nil { if meta == nil {
meta = &Meta{} meta = &Meta{}
meta.Type = "page" //Default if not specified
meta.Attachments = make(map[string]string) meta.Attachments = make(map[string]string)
} }
@ -84,6 +87,9 @@ func ExtractMeta(data []byte) (*Meta, []byte, error) {
case HeaderSpace: case HeaderSpace:
meta.Space = strings.TrimSpace(value) meta.Space = strings.TrimSpace(value)
case HeaderType:
meta.Type = strings.TrimSpace(value)
case HeaderTitle: case HeaderTitle:
meta.Title = strings.TrimSpace(value) meta.Title = strings.TrimSpace(value)