Hi,
I've finally made un update of my initial script which I described here .
Now it checkes all the pages in our instance, and write the output in a Confluence page.
Quite sure many people here have already more sophisticated ways to do the job, but if this can help rookie-admins like me, then I'm happy.
I know I should stop using PageManager and SpaceManager get... calls, but honestly I haven't yet really understood how to make it work in the other way :-) so I'm staying on the good old managers I know ... :-)
Ciao Ciao, Andrea
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.confluence.pages.Page
import com.atlassian.confluence.pages.PageManager
import com.atlassian.confluence.spaces.Space
import com.atlassian.confluence.spaces.SpaceManager
import com.atlassian.confluence.pages.Attachment
import com.atlassian.confluence.pages.AttachmentManager
import com.atlassian.confluence.core.DefaultSaveContext
import groovy.xml.MarkupBuilder
import java.math.RoundingMode
import org.jsoup.Jsoup
def spaceManager = ComponentLocator.getComponent(SpaceManager)
def pageManager = ComponentLocator.getComponent(PageManager)
def attachmentManager = ComponentLocator.getComponent(AttachmentManager)
//All spaces to check
def spacesChecked=spaceManager.allSpaces.findAll{it instanceof Space}
//log.warn(spacesChecked)
//List and Map for attachments use cases
def attachmentUseCases=[]
//List and Map for attachment cases
def attachmentCases=[]
def attachmentCasesMap=[:]
//List and Map for unused attachment cases
def unusedAttachmentCases=[]
def unusedAttachmentCasesMap=[:]
////////////////////////////////////////
//Loop through spaces
////////////////////////////////////////
spacesChecked.each(){
spaceChecked->
//Pages to be checked
def pagesChecked=pageManager.getPages(spaceChecked, true).findAll{it instanceof Page}
////////////////////////////////////////
//Loop through space pages
////////////////////////////////////////
pagesChecked.each(){
pageChecked->
//////////////////////////////////////////
//Looking for attachment use cases in page
//////////////////////////////////////////
//Get content page for parsing
def body = pageChecked.bodyContent.body
//Parse page content
//Refs for use of Jsoup
//https://jsoup.org/cookbook/extracting-data/selector-syntax
//https://jsoup.org/cookbook/extracting-data/attributes-text-html
def parsedBody = Jsoup.parse(body)
//Looking for attachment tag
def attachments = parsedBody.select("ri|attachment")
//Going through all the attachment tags found
attachments.each(){
attachment ->
//Attachment file name
def attFileName=attachment.attr('ri:filename')
//Page of origin of the attachment
def attPageOrigin=attachment.select("ri|page").attr('ri:content-title')
if (attPageOrigin){
}
else{
attPageOrigin=pageChecked.title
}
//Space of origin of the attachment
def attSpaceOrigin=attachment.select("ri|page").attr('ri:space-key')
if (attSpaceOrigin){
}
else{
attSpaceOrigin=spaceChecked.key
}
//Attachment use case unique id
def attUseCaseId="${attSpaceOrigin}__${attPageOrigin}__${attFileName}"
//Add attachment use case id to list
if(!attachmentUseCases.contains(attUseCaseId)){
attachmentUseCases.add(attUseCaseId)
}
}
/////////////////////////////////
//Looking for attachments to page
/////////////////////////////////
def loadedAttachments=attachmentManager.getLatestVersionsOfAttachments(pageChecked)
loadedAttachments.each(){
lAttachment->
def lAttachmentFileName=lAttachment.fileName
def lAttachmentSize=(double)lAttachment.getFileSize()/(1024*1024)
BigDecimal lAttachmentSizeBD = new BigDecimal(lAttachmentSize).setScale(4, RoundingMode.HALF_UP)
def lAttachmentId="${spaceChecked.key}__${pageChecked.title}__${lAttachmentFileName}"
attachmentCases.add(lAttachmentId) //List for quick reference
def attachmentCasesMapAtt=[
space:spaceChecked.key,
page:pageChecked.title,
pageId:pageChecked.id,
pagePath:pageChecked.getUrlPath(),
name:lAttachmentFileName,
size:lAttachmentSizeBD.toString(),
path:lAttachment.getDownloadPath()
]
attachmentCasesMap.put(lAttachmentId, attachmentCasesMapAtt)
}
}
}
////////////////////////////////////////
//Check resulting lists from loops
////////////////////////////////////////
//Sort lists
attachmentCases.sort()
attachmentUseCases.sort()
//Compare lists to find unused attachment cases
attachmentCases.each(){
eAttachment->
if(!attachmentUseCases.contains(eAttachment)){
unusedAttachmentCases.add(eAttachment)
}
}
/////////////////////////////////
//Export to a table
/////////////////////////////////
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.p("Unused attachment cases:")
xml.table(class: "aui") {
thead {
tr{
th('Space')
th('Page')
th('Page Id')
th('Attachment')
th('Size (MB)')
th('Download Path')
th('Delete Link')
}
}
tbody{
unusedAttachmentCases.each(){
unusedAttachmentCase->
tr{
td(attachmentCasesMap.get(unusedAttachmentCase).get('space'))
td{
a(href:[CONFLUENCE BASE DIR]+
attachmentCasesMap.get(unusedAttachmentCase).get('pagePath')){
p(attachmentCasesMap.get(unusedAttachmentCase).get('page'))
}
}
td(attachmentCasesMap.get(unusedAttachmentCase).get('pageId'))
td(attachmentCasesMap.get(unusedAttachmentCase).get('name'))
td(attachmentCasesMap.get(unusedAttachmentCase).get('size'))
td{
a(href:[CONFLUENCE BASE DIR]+attachmentCasesMap.get(unusedAttachmentCase).get('path')){
p('Download Link')
}
}
td{
a([CONFLUENCE BASE DIR]+'/lockpoint/confirmattachmentremoval.action?pageId='
+attachmentCasesMap.get(unusedAttachmentCase).get('pageId')+'&fileName='
+attachmentCasesMap.get(unusedAttachmentCase).get('name')){
p('Delete Link')
}
}
}
}
}
}
/////////////////////////////////
//Write Page in Confluence
/////////////////////////////////
//Define Space and Page for output
def outputPage=pageManager.getPage("MySpace", "MyPage")
def oldVersion=outputPage.clone()
def contentEntityObjectOut = outputPage.getEntity()
contentEntityObjectOut.setBodyAsString(writer.toString())
pageManager.saveContentEntity(outputPage, oldVersion, DefaultSaveContext.BULK_OPERATION)
//Finally write in console
return writer
ABoerio
Program Manager, Information Technology Enthusiast
1 accepted answer
2 comments