Confluence server REST API update page removes all macros?

allecti February 10, 2019

Hi,

I need to convert about 100 pages, their Page Properties is not in right format. I managed to convert table in Page Properties and table is updated to back page with REST API.

However, after page has been updated there is no macro's anymore. Page properties, Page tree and Expand macro's are gone.

What could be the reason for this? Wrong value in body': { 'storage': { 'representation': 'storage' ?

 

2 answers

1 accepted

0 votes
Answer accepted
Tobias Anstett _K15t_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
February 10, 2019

Hi @allecti,

Have you checked that the macros are still part of the storage format you send to the server?

Can you please add your REST request and some example payload, so I can have a closer look at it?

Best, Tobias

allecti February 11, 2019

This is what I get originally:

{u'status': u'current', u'body': {u'_expandable': {u'export_view': u'', u'styled_view': u'', u'editor': u'', u'anonymous_export_view': u'', u'view': u''}, u'storage': {u'_expandable': {u'content': u'/rest/api/content/68335322'}, u'representation': u'storage', u'value': u'<p class="auto-cursor-target"><br /></p><ac:structured-macro ac:name="details" ac:schema-version="1" ac:macro-id="12aaf1ce-2b17-443c-8bae-ed3bb63adae4"><ac:rich-text-body><p class="auto-cursor-target"><br /></p><table class="wrapped fixed-table"><colgroup><col style="width: 166.0px;" /><col style="width: 132.0px;" /><col style="width: 65.0px;" /><col style="width: 159.0px;" /></colgroup><tbody><tr><th>Status</th><td><div class="content-wrapper"><p><ac:structured-macro ac:name="status" ac:schema-version="1" ac:macro-id="23bda9ed-398e-4543-b38f-b2136db1a9dc"><ac:parameter ac:name="colour">Yellow</ac:parameter><ac:parameter ac:name="title">Draft</ac:parameter></ac:structured-macro></p></div></td><td class="highlight-grey" data-highlight-colour="grey"><div class="content-wrapper"><p><strong>Rev</strong></p></div></td><td><div class="content-wrapper"><p>0.3</p></div></td></tr><tr><th class="highlight-grey" colspan="1" data-highlight-colour="grey">Range of validity</th><td colspan="3"><div class="content-wrapper"><p>general</p></div></td></tr><tr><th colspan="1">Period of validity</th><td colspan="1"><br /></td><td colspan="1" style="text-align: center;">-</td><td colspan="1"><br /></td></tr><tr><th colspan="1">Owner</th><td colspan="3"><ac:link><ri:user ri:userkey="ff808181604b387d0160e550b6320008" /></ac:link></td></tr></tbody>

 

Python function to read data:

def read_data_storage(auth, page_id): 
url
= '{base}/{page_id}?expand=body.storage,macro'.format(base=BASE_URL, page_id=page_id)
r
= requests.get( url, auth=auth, headers={'Content-Type': 'application/json', 'USER-AGENT': USER_AGENT} )
r.raise_for_status()
return r

After read I will do

json_text = read_data_storage(auth, options.pageid).text
json2
= json.loads(json_text)
html_storage_txt = json2['body']['storage']['value']

 data = html_storage_text.encode('utf-8')

<p class="auto-cursor-target"><br /></p>
<ac:structured-macro ac:name="details" ac:schema-version="1" ac:macro-id="12aaf1ce-2b17-443c-8bae-ed3bb63adae4">
<ac:rich-text-body>
<p class="auto-cursor-target"><br /></p><table class="wrapped fixed-table">

I am using lxml to modify. 

tree = lxml.html.fromstring(data)

..... update 1st table content ....

html_string = lxml.html.tostring(tree, pretty_print=True)

<div>
<p class="auto-cursor-target"><br></p>
<structured-macro ac:name="details" ac:schema-version="1" ac:macro-id="12aaf1ce-2b17-443c-8bae-ed3bb63adae4"><rich-text-body><p class="auto-cursor-target"><br></p>
<table class="wrapped fixed-table">

write_data_storage(auth, html_string, options.pageid)

 def write_data_storage(auth, html, page_id, title = None): 
info
= get_page_info(auth, page_id)
ver = int(info['version']['number']) + 1
ancestors = get_page_ancestors(auth, page_id)
anc = ancestors[-1]
del anc['_links']
del anc['_expandable']
del anc['extensions']
if title is not None: info['title'] = title
data = { 'id': str(page_id), 'type': 'page', 'title': info['title'],
'version': {'number': ver}, 'ancestors': [anc],
'body': { 'storage':
{
'representation': 'storage',
'value': str(html),
}

}

}

data = json.dumps(data)
url = '{base}/{page_id}'.format(base=BASE_URL, page_id=page_id)
our_headers = {'Content-Type': 'application/json', 'USER-AGENT': USER_AGENT}
r = requests.put( url, data=data, auth=auth, headers=our_headers )
r.raise_for_status()
print "Wrote '%s' version %d" % (info['title'], ver) print "URL: %s%d" % (VIEW_URL, page_id)
return ""

 

Actually I have been playing it around now a while, trying to find out if storage / view representation matters. Now I get 400 error, need to figure out that.

Before I managed to update page but macro's were dropped out.

it would be nice to get even hints if I am doing something totally wrong. 

Tobias Anstett _K15t_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
February 11, 2019

Hi @allecti,

The following request works for me:

{
"id":"65658",
"type":"page",
"title":"new page",
"space":{"key":"TEST"},
"body": {
"storage": {
"value": "<p>This is the updated text for the new page</p>",
"representation":"storage"
}
},
"version":{"number": 44}
}

The major difference in my request is that I do not use the ancestors parameter and have a space parameter set.

Furthermore I would have a closer look into any html encode/decode operations.

The best is to try the requests in Postman or the Confluence Rest API browser first.

Best, Tobias

allecti February 11, 2019

Thanks Tobias!

Yes, it is something to do now with encode/decode operations. My code works if I will use original data I got from Postman and I just update table part of that -> everything is just like it should be. 

Like Tobias Anstett _K15t_ likes this
Sandeep Jawalkar December 4, 2020

@allecti  hi,

can you share any code how u update table without encode 

0 votes
allecti February 25, 2019

Actually found out that it is better to use request.content instead of request.text that seems to convert data and specially encoding it to string.

Everything started to work ok when I changed:

json_text = read_data_storage(auth, options.pageid).text

to 

json_text = read_data_storage(auth, options.pageid).content

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events