Last modified by Eleni Cojocariu on 2026/10/23 14:40

Show last authors
1 Find the file holding an attachment's content under ##store/file##, whose directories are named after hashes rather than after the attachment, as [[Filesystem Store Layout>>doc:documentation.xs.admin.store.file-layout.WebHome]] describes.
2
3 The script below does the hashing for you. Running Groovy in a Page needs programming right, which is why it is given here rather than run on this Page.
4
5 1. Note the Page the attachment is on and its file name, for instance ##Sandbox.WebHome## and ##XWikiLogo.png##.
6 1. Create a Page on your own wiki and paste the script into it, in the wiki editor:(((
7 {{code language="groovy"}}
8 {{groovy}}
9 import org.apache.commons.codec.digest.DigestUtils
10 import org.xwiki.model.reference.DocumentReference
11 import org.xwiki.model.reference.EntityReferenceSerializer
12
13 // The attachment to locate, as "Space.Page@filename".
14 def target = "[email protected]"
15
16 def (page, filename) = target.split("@", 2)
17 // Resolve, then drop the locale: the store hashes the Page without it.
18 def docRef = new DocumentReference(services.model.resolveDocument(page), (Locale) null)
19 def localUid = services.component
20 .getInstance(EntityReferenceSerializer.TYPE_STRING, "local/uid")
21 .serialize(docRef)
22
23 def split = { s -> def h = DigestUtils.md5Hex(s); "${h.charAt(0)}/${h.charAt(1)}/${h.substring(2)}" }
24 def path = "${docRef.wikiReference.name}/${split(localUid)}/attachments/${split(filename)}"
25
26 println "|=Step|=Value"
27 println "|The Page, serialized with ##local/uid##|##${localUid}##"
28 println "|Its MD5|##${DigestUtils.md5Hex(localUid)}##"
29 println "|The MD5 of ##${filename}##|##${DigestUtils.md5Hex(filename)}##"
30 println "|The directory, under ##store/file##|##${path}##"
31 {{/groovy}}
32 {{/code}}
33 )))
34 1. Change the ##target## line to the Page and file name you noted, separated by ##@##, then save the Page.
35 1. Read the directory off the last row of the table and look for it under ##store/file## in the [[permanent directory>>doc:documentation.xs.admin.configuration.directories.permanent-directory.WebHome]]. The file inside it is called ##f## plus the extension of the attachment.(((
36 {{image reference="computed-path.png" size="extra" alt="The script's output table, its last row giving the directory under store/file"/}}
37 )))

Get Connected