How to get the file path of an attachment which is stored in the file system?

Attachments in my wiki are stored in the file system.
I want to get the file path of an attachment to do some tasks by a shell call e.g. get form data of a pdf file.

I found the function

doc.getAttachment("test.txt").getAttachment().getAttachment_content().storageFile.getAbsolutePath()

to get the file path of the attachment “test.txt”.

But there is a problem:
getAttachment_content() will result in a null value if the attachment was not “active” just before.

“active” means:

  • the attachment was just uploaded
  • the attachment was just viewed/downloaded

Is there a database field containing the file system path of the attachment?
Sorry, but I missed identifying it.

No, it’s dynamically resolved based on the reference and the configuration.

Since you don’t seem to be afraid of using internal API (you are actually accessing a private field :slight_smile: ), you have a much faster helper to get the path of an attachment without loading anything: use the component org.xwiki.store.filesystem.internal.FilesystemStoreTools and especially the method #getAttachmentDir(AttachmentReference).

Many thanks for the hint

The following (a bit dirty) groovy code lines do the job:

import org.xwiki.store.filesystem.internal.FilesystemStoreTools

def getAttachmentFilePath(docFullName,attachmentName) {
    FilesystemStoreTools FST = new FilesystemStoreTools()
    return  "/var/local/xwiki/store/file/" +
                FST.getAttachmentDir(xwiki.getDocument(docFullName).getAttachment(attachmentName).getReference()) +
                "/f" + attachmentName.replaceAll(/^.*\./,".")
}

The root directory of the attachment store is hard coded. As I am admin I will see if somebody tries to do changes, :slightly_smiling_face:

Norbert

@NorSch there is a snippet here that does the same thing:

it’s longer because it provides an UI to operate it (specify the page and attachment name).

Thank you for pointing this out - I simply overlooked the snippet.

My old code is then cleaner and condensed into

import org.xwiki.store.filesystem.internal.FilesystemStoreTools

def getAttachmentFilePath(docFullName,attachmentName) {
    def comp = services.component.getInstance(FilesystemStoreTools.class)
    return comp.getAttachmentFileProvider(xwiki.getDocument(docFullName).getAttachment(attachmentName).getReference()).getAttachmentContentFile()
}

Norbert

1 Like