Confluence 4.0, finding pages that have "content with incompatible upgraded macros"
Asked by Gavin Fowler:

Hi

I have (finally?) upgraded our production instance of confluence to version 4.0. I have one question that wasn't identified during our non production testing which is this:

I can see from the confluence administration console landing page, under "completed tasks" there is a task named: "Update content with incompatible upgraded macros". If I drill into this task, confluence reports:
> Confluence has detected that there are **115 pages** with macros that are not yet Confluence 4+ compatible. To ensure backwards compatibility, these macros are still being rendered as wiki markup when editing your pages.

I randomly found one macro that indeed had been encapsulated in a confluence 4 "wiki markup" macro. However, it would be really useful to know how i can find all 115 pages/instances being reported so i can review and take judgement on next step actions.

So in short **my question is**: what method(s) are available to me that will help me find all these 115 pages/instances being reported by confluence.

Many thanks


Answers:
author: Sergey Svishchev
body: Instead of grovelling the database, use search engine! :-)

```
macroName:unmigrated-wiki-markup* OR macroName:unmigrated-inline-wiki-markup*
```


author: William Schneider
body: If you are able to view the log output for confluence, you could set com.atlassian.confluence.content.render.xhtml.migration to ALL under \<BASE URL\>/admin/viewlog4j.action and then run the migration from \<BASE URL\>/admin/unmigratedwikicontent.action . The log will show you the page title, which is then somewhat easy to search for though Confluence. If you still have the old log files from when you first upgraded to 4.0, it includes the page ID along with the macro error, which is more useful for quick access to the page.

Alternatively, the following python script will iterate over EVERY space and check ALL pages for \<div class="error\> in them, and output the page ID in the terminal. As a warning, this may likely take some time, and may be somewhat intensive. Once you have the page ID's, you can visit the pages at \<BASE URL\>/pages/viewpage.action?pageId=\<ID\>

```
#!/usr/bin/env pythonimport xmlrpclibimport getpassimport sysCONFLUENCE_URL='http://example.wiki.edu/rpc/xmlrpc'CONFLUENCE_LOGIN=raw_input('Confluence Username: ')CONFLUENCE_PASSWORD=getpass.getpass('Confluence Password: ')client = xmlrpclib.Server(CONFLUENCE_URL,verbose=0)
authToken=client.confluence2.login(CONFLUENCE_LOGIN,CONFLUENCE_PASSWORD)spaces=client.confluence2.getSpaces(authToken)for space in spaces:  spacePages=client.confluence2.getPages(authToken,space['key'])  for page in spacePages:      pageId=page['id']      renderedPage=client.confluence2.renderContent(authToken,space['key'],pageId,'',{'style':'clean'})      if renderedPage.find('<div class="error">') > 0:          print page['id']client.confluence2.logout(authToken)
```

edit: Created a ruby version of the script also, in case ruby is preferred

```
#!/usr/bin/env rubyrequire 'xmlrpc/client'CONFLUENCE_URL = 'https://example.wiki.edu/rpc/xmlrpc'printf "Username: "CONFLUENCE_LOGIN = gets.chompprintf "Password: "CONFLUENCE_PASSWORD = gets.chompclient = XMLRPC::Client.new_from_uri(CONFLUENCE_URL).proxy("confluence2")# hackity hack for SSL (if you need it)client.instance_variable_get("@server").instance_variable_get("@http").verify_mode = OpenSSL::SSL::VERIFY_NONEtoken = client.login(CONFLUENCE_LOGIN, CONFLUENCE_PASSWORD)spaces = client.getSpaces(token)spaces.each do |space|  pages = client.getPages(token, space['key'])  pages.each do |page|    rendered = client.renderContent(token, space['key'], page['id'], '')    if rendered.include? '&lt;div class="error"&gt;'      puts page['id']    end  endendclient.logout(token)
```

comments: author: Justin Rand
body: I'm getting an error when running this script.

```
Traceback (most recent call last):  File "./new_python.py", line 11, in &lt;module&gt;    authToken=client.confluence2.login(CONFLUENCE_LOGIN,CONFLUENCE_PASSWORD)  File "/usr/lib/python2.6/xmlrpclib.py", line 1199, in __call__    return self.__send(self.__name, args)  File "/usr/lib/python2.6/xmlrpclib.py", line 1489, in __request    verbose=self.__verbose  File "/usr/lib/python2.6/xmlrpclib.py", line 1243, in request    headersxmlrpclib.ProtocolError: &lt;ProtocolError for localhost:8443/RPC2: 404 Not Found&gt;
```

Any ideas?


author: William Schneider
body: What URL did you use for this? It looks like you are receiving a 404 Not Found error when trying to resolve localhost:8443/RPC2 . Try using the full URL to the xml-rpc api which can be found in the developer docs (<https://developer.atlassian.com/display/CONFDEV/Confluence+XML-RPC+and+SOAP+APIs>).


author: Justin Rand
body: Figured out the issue above, I didn't realize the URL needed to include the xmlrpc path.


author: William Schneider
body: Hey Justin, glad you were able to get it working! I guess between me getting the email of your reply and checking it online you solved the error you had originally posted in this comment?


author: William Schneider
body: No problem, glad you got it working.


author: Justin Rand
body: Yep it was a stupid copy/paste mistake for my second error. Thanks again!


author: Walter Kammergruber
body: In your python script you could probably remove the

```
if 1:
```

check ;-)

Thanks Billy for sharing your code. Clean and simple.


author: William Schneider
body: woidda - thanks, I've removed it now. The snippet was altered from code of mine that actually had a meaningful statement in it's place :)


author: CharlesH
body: We had this issue after migrating to 4.2. Atlassian Support suggested running the following queries, although I seem to recall the number of records it returned didn't tally exactly with the number reported in the message.

```
SELECT * FROM CONTENT WHERE CONTENTID IN (SELECT CONTENTID FROM bodycontent WHERE BODYTYPEID = 0) AND PREVVER IS NULL AND CONTENTTYPE IN ('PAGE','BLOGPOST');SELECT * FROM CONTENT WHERE CONTENTID IN (SELECT CONTENTID FROM bodycontent WHERE BODY LIKE '%unmigrated-wiki-markup%') AND PREVVER IS NULL AND CONTENTTYPE IN ('PAGE','BLOGPOST');
```


author: Application Services
body: Below is an SQL that I used to list the **page names** for pages that have unmigrated content:

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ``` select min(a.contentid),a.titlefrom content a,bodycontent bwhere a.contentid in( select b.contentid  from bodycontent b  where b.body like '%unmigrated%'  and a.contentid = b.contentid  and a.content_status='current')group by a.title; ``` |


author: Jositz, Michael (Allianz SE)
body: I there also an SQl for Oracle that gives me the ID's of the unmigrated pages?

After upgrading to Conlfuence 4.3.3 I struggle with 618 pages where Confluence discovered unknown macros. I checked with the method suggested above to show the issues in the log file. It works, but it does not show me 618 pages.

Anyone has an SQL where I can exactly that number that Confluence internally shows me?

Thanks Michael


Tags: compatibility

macro