Hi,
I've managed to append content to an existing page in Confluence by scriptrunner console.
Below a sample of the code I'm using, which I know it's far from being an elegant programming example, :-), but in the end it works, and I'm using to introduce text, tables, etc...
//Libraries
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.sal.api.component.ComponentLocator
import com.atlassian.confluence.core.DefaultSaveContext
//Defining the management objects
def spaceManager = ComponentLocator.getComponent(SpaceManager)
def pageManager = ComponentLocator.getComponent(PageManager)
def attachmentManager = ComponentLocator.getComponent(AttachmentManager)
//Defining the page to update (the page already exists)
def outputPage=pageManager.getPage("~BOERIO", "Output")
//Get the current content of the page
def contentEntityObject = outputPage.getContentEntityObject()
def pageBody=outputPage.getBodyAsString()
// I want to add this text to the page
String appendedText="<p>Hello Confluence Page!</p>"
//Building the string with the new content
String outputPageBody=pageBody+appendedText
//Assigning the new content to the page
contentEntityObject.setBodyAsString(outputPageBody)
//Saving the page
pageManager.saveContentEntity(outputPage, DefaultSaveContext.DEFAULT)
//return outputPageBody
My question is related to the risk to reach a size limit for the string I'm building and assigning as new page content. Will I reach the point where the current page content is no more manageable with a string?
Is there a better approach to follow?
Thanks in advance for any suggestion.
Ciao, Andrea
Hi Andrea,
Thank you, because of the script you provided, I could get started.
I am sure you would have found an answer by this time for your question,
still if I can share my views on this topic for others who might visit here, due the maximum string limitation (65536 characters is my understanding) which hits (I tested it with a large string and it throws error) the following are my attempts. All these are assuming ScriptRunner is installed in Confluence and JIRA and those apps are connected through Applink
Also I did not use xml, directly formed the page contents as strings
The caveat is when user views the page full content is visible but during edit, parent/child pages have to be edited separately
This is my trial attempt and worked for me, not sure any other things will hit later
Hope it helps others,
with warm regards
ramki
Hi Ramki,
thanks for your feedback. In case of issues with content size I'll consider it.
actually I have started to use StringWriter, so a sample code is the following (it's still ugly, but it works).
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.sal.api.component.ComponentLocator
import com.atlassian.confluence.core.DefaultSaveContext
import groovy.xml.MarkupBuilder
import java.math.RoundingMode
import java.time.LocalTime
//needed this to monitor execution time
def inizio=LocalTime.now()
log.warn('Inizio:'+ inizio)
//general objects definition
def spaceManager = ComponentLocator.getComponent(SpaceManager)
def pageManager = ComponentLocator.getComponent(PageManager)
def attachmentManager = ComponentLocator.getComponent(AttachmentManager)
//decided to use StringWriter()
def writer2 = new StringWriter()
def xml2 = new MarkupBuilder(writer2)
//Define the target page (I know this page e)
def outputPage=pageManager.getPage("~BOERIO", "Statistiche Pagine Spazi")
def contentEntityObject = outputPage.getEntity()
//List all spaces in our instance
def spaziOMT=spaceManager.allSpaces.findAll{it.isGlobal()}
def quantiSpazi=spaziOMT.size()
log.warn('Spazi considerati:'+quantiSpazi)
xml2.p{
h3("Numero totale spazi: "+ quantiSpazi.toString())
}
//Create table
xml2.table(class: "aui") {
//table head
thead {
tr {
//Column titles
th('#Riga')
th('#Spazio')
th('Titolo Spazio')
th('#Pagina Spazio')
th('Titolo Pagina')
th('Id Pagina')
th('Ultimo Aggiornamento')
th('Numero Versioni')
th('Dimensioni Pagina')
th('N° Allegati (Ultime Rev)')
th('Peso Allegati (Ultime Rev)')
th('N° Vecchie Rev. Allegati')
th('Peso Allegati (Vecchie Rev)')
}
}
// counters
int rowNumber=0
int spaceNumber=0
int pageNumberInSpace=0
long MEGABYTE = 1024 * 1024
def spaziOMTCheck=spaziOMT
//table body/rows
tbody{
spaziOMTCheck.each(){
spazio ->
spaceNumber=spaceNumber+1
pageNumberInSpace=0
def pagineOMT=pageManager.getPages(spazio, true).findAll {
it instanceof Page}
def start=LocalTime.now().toSecondOfDay()
pagineOMT.each(){
pagina ->
rowNumber=rowNumber+1
pageNumberInSpace=pageNumberInSpace+1
tr{
td(rowNumber)
td(spaceNumber)
td(spazio.name)
td(pageNumberInSpace)
td{
a(href:'https://wiki-omt.mindmercatis.com'+pagina.getUrlPath()){
p(pagina.title)
}
}
td(pagina.id)
td(pagina.lastModificationDate.format("dd/MM/yy"))
td(pagina.version)
td(pagina.getBodyAsString().length())
def quantiAllegati=attachmentManager.countLatestVersionsOfAttachments(pagina)
def tutteVersioniAllegati=attachmentManager.getAllVersionsOfAttachments(pagina)
def vecchieVersioniAllegati=tutteVersioniAllegati.size()-quantiAllegati
long pesoUltimeRevAllegati=0
long pesoVecchieRevAllegati=0
tutteVersioniAllegati.each(){
versioneAllegato ->
if (versioneAllegato.isIndexable()){
pesoUltimeRevAllegati=pesoUltimeRevAllegati+versioneAllegato.fileSize
}
else {
pesoVecchieRevAllegati=pesoVecchieRevAllegati+versioneAllegato.fileSize
}
}
td(quantiAllegati)
double pesoUltimeRevAllegatiDB=pesoUltimeRevAllegati/MEGABYTE
BigDecimal pesoUltimeRevAllegatiDB2 = new BigDecimal(pesoUltimeRevAllegatiDB).setScale(2, RoundingMode.HALF_UP)
td(pesoUltimeRevAllegatiDB2)
//td(pesoUltimeRevAllegati)
td(vecchieVersioniAllegati)
double pesoVecchieRevAllegatiDB=pesoVecchieRevAllegati/MEGABYTE
BigDecimal pesoVecchieRevAllegatiDB2 = new BigDecimal(pesoVecchieRevAllegatiDB).setScale(2, RoundingMode.HALF_UP)
td(pesoVecchieRevAllegatiDB2)
//td(pesoVecchieRevAllegati)
}
}
def tempoSpazio=LocalTime.now().toSecondOfDay()-start
log.warn('Secondi:'+tempoSpazio+ ' Pagine:'+pagineOMT.size()+' Spazio:'+spazio.name)
}
}
}
def fineWriter=LocalTime.now()
log.warn('Fine Writer:'+fineWriter)
def totaleWriter=fineWriter.toSecondOfDay()-inizio.toSecondOfDay()
log.warn('Secondi impegati sino al Writer:'+totaleWriter)
xml2.p{
h3("Lavoro completato in "+totaleWriter+" secondi.")
}
//scrivo nel corpo della pagina la stringa costruita //salvo modifica alla pagina
contentEntityObject.setBodyAsString(writer2.toString())
pageManager.saveContentEntity(outputPage, DefaultSaveContext.DEFAULT)
def fine=LocalTime.now()
log.warn('Fine Script:'+fine)
def totale=fine.toSecondOfDay()-inizio.toSecondOfDay()
log.warn('Secondi impegati sino a fine script:'+totale)
return writer2
I use pretty much the same approach when trying to send reports from Jira (in this case by REST API calls, checking existing version of the page, etc...).
Ciao, Andrea
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Andrea,
Thank you for the response, with further learning I had on this subject
actually it is not required to create child pages and all. With your script as the base, developed Confluence REST END point given below. So, the variable
String outputPageBody = pageBody + appendedText
does not look like limited by the string length 65536. I am not sure whether there is any upper limit when sending appendText string as url parameter.
In my calling script I set multiple string variables for each section of the wiki page.
Then I set one master string variable concatenating each of those string variables
def masterStringVariable_toAppend = sec1_str + sec2_str + sec3_str ...
then I am able to call this REST END point and the page is created.
masterStringVariable_toAppend length in my case is 104521 characters
/*import org.apache.log4j.Level
import org.apache.log4j.Logger
def log = Logger.getLogger("com.onresolve.jira.groovy")
log.setLevel(Level.DEBUG)*/
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.transform.BaseScript
import org.codehaus.jackson.map.ObjectMapper
import com.atlassian.confluence.spaces.Space
import com.atlassian.confluence.pages.Page
import com.atlassian.confluence.spaces.SpaceManager
import com.atlassian.confluence.pages.PageManager
import com.atlassian.confluence.core.DefaultSaveContext
import com.atlassian.confluence.api.impl.sal.ConfluenceApplicationProperties
import javax.ws.rs.core.Response
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.confluence.pages.templates.PageTemplateManager
import javax.servlet.http.HttpServletRequest
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response
import static com.atlassian.user.security.password.Credential.unencrypted
import com.atlassian.confluence.setup.settings.SettingsManager
import com.atlassian.confluence.pages.Attachment
import com.atlassian.confluence.pages.AttachmentManager
//Libraries
import com.atlassian.confluence.pages.Attachment
import com.atlassian.confluence.pages.AttachmentManager
//https://scriptrunner.adaptavist.com/latest/confluence/macros/CustomMacros.html#_including_all_child_pages
//https://community.atlassian.com/t5/Adaptavist-questions/Append-Content-to-page-with-Scriptrunner-size-limits-with/qaq-p/1075598
//https://community.atlassian.com/t5/Marketplace-Apps-Integrations/Script-runner-post-function-to-create-confluence-page-FROM/qaq-p/842469
import com.atlassian.confluence.xhtml.api.MacroDefinition
import com.atlassian.confluence.xhtml.api.XhtmlContent
import com.atlassian.renderer.v2.RenderUtils
import groovy.xml.MarkupBuilder
import groovy.json.JsonBuilder
@BaseScript CustomEndpointDelegate delegate
//End point name is the same as the method's name
append_rn_page_by_post(httpMethod: "POST") { MultivaluedMap queryParams, String body ->
//Defining the management objects
def spaceManager = ComponentLocator.getComponent(SpaceManager)
def pageManager = ComponentLocator.getComponent(PageManager)
def attachmentManager = ComponentLocator.getComponent(AttachmentManager)
//https://community.atlassian.com/t5/Marketplace-Apps-Integrations/Script-runner-post-function-to-create-confluence-page-FROM/qaq-p/842469
//def spaceKey = queryParams.getFirst("space").toString()
//def title = queryParams.getFirst("title").toString()
//log.debug("$spaceKey $title")
def mapper = new ObjectMapper()
def params = mapper.readValue(body, Map)
assert params.title // must provide title for the page
assert params.spaceKey // must provide spaceKey like MCDE
def spaceKey = params.spaceKey.toString()
def title = params.title.toString()
//log.debug("$spaceKey $title")
def pageIdMap = [:]
pageIdMap["pageId"] = 0
pageIdMap["Exception"] = "None"
pageIdMap["Invalid"] = "None"
def outputPage
if(spaceKey && title) {
//Defining the page to update (the page already exists)
try {
outputPage=pageManager.getPage(spaceKey, title)
pageIdMap["pageId"] = outputPage.id
//Get the current content of the page
def contentEntityObject = outputPage.getContentEntityObject()
def pageBody=outputPage.getBodyAsString()
// I want to add this text to the page
//String appendedText="<p>Hello Confluence Page!</p>"
String appendedText = params.appendContent
//Building the string with the new content
String outputPageBody = pageBody + appendedText
//Assigning the new content to the page
contentEntityObject.setBodyAsString(outputPageBody)
//Saving the page
pageManager.saveContentEntity(outputPage, DefaultSaveContext.DEFAULT)
} catch(Exception ex) {
pageIdMap["Exception"] = "Exception to get page or append page for spaceKey = ${spaceKey} and title = ${title}: ${ex.toString()}"
}
} else {
pageIdMap["Invalid"] = "Invalid spaceKey = ${spaceKey} or title = ${title}"
}
//return outputPageBody
//return Response.ok().build()
return Response.ok(new JsonBuilder(pageIdMap).toString()).build()
with warm regards
ramki
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.