Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Script to delete attachment's version

I'm trying to write a script job to scan and delete attachment versions on a page.

For example on a page I have attach file A and reattach a few times to get 5 versions for file A. I want to write a script to delete the first 4 version.

Here's my attempt:

import com.atlassian.confluence.pages.Attachment
import com.atlassian.confluence.pages.AttachmentManager
import com.atlassian.sal.api.component.ComponentLocator


def attachmentManager = ComponentLocator.getComponent(AttachmentManager)

hits.each { attachment ->
def attachmentOnPage = attachmentManager.getAttachments(attachment)
if (attachmentOnPage.size() >1)
{
log.warn "attachmentOnPage: ${attachmentOnPage}"
log.warn "size: ${attachmentOnPage.size()}"
int size = attachmentOnPage.size()
int sizeMax = size - 1
List<String> attachmentDeleteList = new ArrayList<String>()
for(int i=0;i<size;i++)
{
if (i<sizeMax)
{
def attachmentSingle = attachmentOnPage.get(i)
attachmentDeleteList.add(attachmentSingle)
log.warn "attachmentDeleteList: ${attachmentDeleteList}"
//log.warn "attachmentSingle: ${attachmentSingle}"
//attachmentManager.removeAttachmentFromServer(attachmentSingle)
}
}
}
}

However, when I try to run the removeAttachmentFromServer method, it delete every versions and the file itself in the database. I also tried the removeAttachment(attachmentDeleteList) and it does the same thing. Is there any method that just delete the version not the attachment itself.

2 answers

0 votes
Bill Bailey Community Leader Jun 06, 2019

Well maybe it is easier to do via a REST call? The URL for deleting an attachment version takes the form of:

https://www.your-conlfuence.com/pages/confirmattachmentversionremoval.action?pageId=######&fileName=<your file name>&version=n

Where n is the version number. Now I don't know if you delete version 1, if the rest of the attachments will renumber so you will have to experiment (meaning you may have to delete version 1 four times in your case).

We would like to automate this using the scheduled script job in Scriptrunner though. I've managed to make my script works. Will post the answer here shortly. 

Hey Nyugen, 

Any chance you got this script working - looking to do something similar so would be a great help.

Thanks

Like Alex Gregory likes this

I've made it.

 

import com.atlassian.confluence.spaces.SpaceManager
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.confluence.pages.PageManager
import com.atlassian.confluence.pages.AttachmentManager

def attachments
def attachmentManager = ComponentLocator.getComponent(AttachmentManager)
def spaceManager = ComponentLocator.getComponent(SpaceManager)
def pageManager = ComponentLocator.getComponent(PageManager)
def space=spaceManager.getSpace('RUBIK')
def pages = pageManager.getPages(space, true)
for (page in pages) { //loop for every active page in the space

for (attachment in attachmentManager.getLatestVersionsOfAttachments(page)) { //list of latest attachments
attachmentManager.getPreviousVersions(attachment).each { //for every not latest version
attachmentManager.removeAttachmentVersionFromServer(it)
}
}
}

Thanks for this, quick question, do you know if this works fine on pages regardless of restrictions? 

 

I've been looking at using the built in scripts but they have massive limitations, such as only showing (even to an admin) pages they have explicit access to. This is due to the built in script abiding by the confines of the quick search bar, that doesn't give admins search capability on something they don't have explicit access to. Then to make matters worse, when I tied to get the space owner to run it, it errors out.

Also, do you know whether or not this triggers the content updated notification email or not? A space owner was bombarded with the notification emails after we used the built in script, which isn't useful if we want to do this in the background for many spaces.

 

Is it possible you could put up a variation that runs across the entire instance?

 

thanks

This is working on admin permission of app. Doesn't look on restrictions. 

I suggest to test it first on acc on few spaces. In some cases we have got problems with missing attachments.

 

About all spaces variant:

 

import com.atlassian.confluence.spaces.SpaceManager
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.confluence.pages.PageManager
import com.atlassian.confluence.pages.AttachmentManager

def attachments
def attachmentManager = ComponentLocator.getComponent(AttachmentManager)
def spaceManager = ComponentLocator.getComponent(SpaceManager)
def pageManager = ComponentLocator.getComponent(PageManager)
def allSpaces = spaceManager.getAllSpaces()

for( def space : allSpaces)
{
def pages = pageManager.getPages(space, true)
for (page in pages) { //loop for every active page in the space
for (attachment in attachmentManager.getLatestVersionsOfAttachments(page)) { //list of latest attachments
attachmentManager.getPreviousVersions(attachment).each { //for every not latest version
attachmentManager.removeAttachmentVersionFromServer(it)
}
}
}
}

Oooo, going to try it now :)

Where do you run it from for it to not run as a regular user but to run as the system? Do you just put it in the jobs area of Scriptrunner? Although that does ask for a user to run as.

This script is based on java classes inside confluence. You need to run as Admin on Confluence to use it / run it.

 

Some scripts I think use current login user, other (script and function) doesn't need any authentication to run a code.

Ah ok so just stick it in the jobs area. It seems to slowly be running through it anyway, this ia n improvement over the Scriptrunner built in script as it always times out when using theirs because of proxy timeouts, even when raised to 10 minutes.

 

You may be able to help me with another issue. I need to bulk add a specific group to every page in my instance. Because of this issue:

https://jira.atlassian.com/browse/CONFSERVER-36393

 

But the script Adaptavist made for me doesn't work because of this issue:

https://jira.atlassian.com/browse/CONFSERVER-58536

 

This is the script below, do you have any ideas on how it could get to work?

import com.atlassian.confluence.core.ContentPermissionManager
import com.atlassian.confluence.pages.Page
import com.atlassian.confluence.pages.PageManager
import com.atlassian.confluence.security.ContentPermission
import com.atlassian.confluence.security.ContentPermissionSet
import com.atlassian.confluence.spaces.Space
import com.atlassian.confluence.spaces.SpaceManager
import com.atlassian.sal.api.component.ComponentLocator

import static com.atlassian.confluence.security.ContentPermission.EDIT_PERMISSION
import static com.atlassian.confluence.security.ContentPermission.VIEW_PERMISSION

/**
* This script runs through all spaces and pages (with true parameter in getPages, eagerly fetch permissions at the same time)
* and assign view permission to the 'groupToAddPermission' variable. If this group already has View or edit permission,
* the script does not make any change
*/
SpaceManager spaceManager = ComponentLocator.getComponent(SpaceManager)
PageManager pageManager = ComponentLocator.getComponent(PageManager)
ContentPermissionManager contentPermissionManager = ComponentLocator.getComponent(ContentPermissionManager)
final String groupToAddPermission = 'confluence-administrators'

ContentPermission viewPermission = ContentPermission.createGroupPermission(VIEW_PERMISSION, groupToAddPermission)
ContentPermission editPermission = ContentPermission.createGroupPermission(EDIT_PERMISSION, groupToAddPermission)
log.error "view Permission ${viewPermission}"
log.error "edit Permission ${editPermission}"

spaceManager.allSpaces.each { Space space ->
log.error "Space ${space}"
if(space.key == '<KEY>'){
pageManager.getPages(space, true).each { Page page ->
log.error "Page ${page}"
ContentPermissionSet viewContentPermissionSet = page.getContentPermissionSet(VIEW_PERMISSION)
ContentPermissionSet editContentPermissionSet = page.getContentPermissionSet(EDIT_PERMISSION)
log.error "viewContentPermissionSet: ${viewContentPermissionSet}"
log.error "editContentPermissionSet: ${editContentPermissionSet}"
boolean containsGroupPermissions = viewContentPermissionSet?.contains(viewPermission) || editContentPermissionSet?.contains(editPermission)
boolean containsAnyRestrictions = viewContentPermissionSet || editContentPermissionSet

if (!containsGroupPermissions && containsAnyRestrictions) {
log.error "Assign new Content"
contentPermissionManager.addContentPermission(viewPermission, page)
log.error "viewContentPermissionSet Result1: ${ page.getContentPermissionSet(VIEW_PERMISSION)}"
log.error "editContentPermissionSet Result1: ${ page.getContentPermissionSet(EDIT_PERMISSION)}"
}
}
}
}

Here

 

import com.atlassian.confluence.spaces.SpaceManager
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.confluence.pages.PageManager
import com.atlassian.confluence.pages.AttachmentManager

def attachments
def attachmentManager = ComponentLocator.getComponent(AttachmentManager)
def spaceManager = ComponentLocator.getComponent(SpaceManager)
def pageManager = ComponentLocator.getComponent(PageManager)
def space=spaceManager.getSpace('RUBIK')
def pages = pageManager.getPages(space, true)
for (page in pages) { //loop for every active page in the space
for (attachment in attachmentManager.getLatestVersionsOfAttachments(page)) { //list of latest attachments
attachmentManager.getPreviousVersions(attachment).each { //for every not latest version
attachmentManager.removeAttachmentVersionFromServer(it)
}
}
}

hi,
Thank you, the script is very useful.
Could anyone tell me how to modify this script to leave eg the last 5 versions of each attachment? I'm not a developer and I'm trying to modify it by trial and error.

Not final work, but only a concept. Good luck.

 

for (attachment in attachmentManager.getLatestVersionsOfAttachments(page)) { //list of latest attachments
def newestVersion = attachment.version //not sure if this is right field
attachmentManager.getPreviousVersions(attachment).each { //for every not latest version

//here need some logs to see if the results are sorted from the newest

//something like that:
if(it.version < newestVersion-5) {
attachmentManager.removeAttachmentVersionFromServer(it)
}

}
}
 

Thanks.
I will test it. 

Suggest an answer

Log in or Sign up to answer
TAGS
Community showcase
Published in Confluence

🏑 Atlympic Event: Confluence

Hello Community!  Quick disclaimer: We are running a contest on Community (The Atlympics!) from July 23rd - August 8th of 2021. If you are interested in participating in this contest (prizes! ...

343 views 14 10
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you