How to read a text file attached to an issue with scriptrunner?

ABoerio November 13, 2019

Hi, 

I'm trying to read a text file attached to an issue, using a script.

Here below the code I'm trying to use:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.comments.CommentManager
import com.atlassian.jira.issue.AttachmentManager
import com.atlassian.jira.issue.attachment.Attachment

def issueManager = ComponentAccessor.getIssueManager()
def aM= ComponentAccessor.getAttachmentManager()
def pM = ComponentAccessor.getAttachmentPathManager()
def issue = issueManager.getIssueObject("TEST-129")

List attachments = aM.getAttachments(issue)

if (!attachments.isEmpty()) {
for (Attachment a in attachments) {
String fileName=a.getFilename()
log.warn(fileName)
String storePath=pM.getAttachmentPath()
def attachmentFilePath = new File(storePath).path
def attachmentFile= new File(attachmentFilePath,fileName)
log.warn(attachmentFile)
log.warn(attachmentFile.text)
}
}

 

Quite sure I'm missing something, because the logs I get are the following:

 

image.png

Thanks in advance for any hint.

Andrea

 

2 answers

1 accepted

0 votes
Answer accepted
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
November 13, 2019

The file is stored in a special path under the storePath.

storePath/projectKey/bucket/issueKey/attachmentId

There is a really easy way to get the correct file path using AttachmentUtils but it's deprecated.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.util.AttachmentUtils

def issueManager = ComponentAccessor.getIssueManager()
def aM= ComponentAccessor.getAttachmentManager()

def issue = issueManager.getIssueObject("TEST-129")

def attachments = aM.getAttachments(issue)

attachments.each{a ->
def fileName = a.fileName
log.warn(filename)
def filePath = AttachmentUtils.getAttachmentFile(a)
def attachmentFile = new File(filePath)
log.warn(attachmentFile)
log.warn(attachmentFile.text)
}
 The current way to access the content of a file is using AttachmentManager.steamAttachmentContent

There are some examples here: https://community.atlassian.com/t5/Answers-Developer-Questions/Accessing-jira-attachment-file-data-from-a-jira-plugin/qaq-p/564803

ABoerio November 15, 2019

Thank you! I'll try to follow your suggestments and let you know.

Andrea

ABoerio November 20, 2019

Hi @Peter-Dave Sheehan 

I tried to follow your hint, read the links, and spent some time on the StreamAttachmentContent. The file to be read has become an XML.

I did something like this

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.comments.CommentManager
import com.atlassian.jira.issue.AttachmentManager
import com.atlassian.jira.issue.attachment.Attachment
import com.atlassian.jira.issue.attachment.FileAttachments
import com.atlassian.jira.util.AttachmentUtils
import org.apache.commons.io.FilenameUtils
import com.atlassian.jira.util.io.InputStreamConsumer
import org.springframework.util.StreamUtils
import java.io.FileOutputStream
import java.io.InputStream
import java.io.IOException
import groovy.util.XmlParser
import groovy.util.XmlSlurper

def issueManager = ComponentAccessor.getIssueManager()
def aM= ComponentAccessor.getAttachmentManager()
def pM = ComponentAccessor.getAttachmentPathManager()
def issue = issueManager.getIssueObject("TEST-129")
def attachments = aM.getAttachments(issue)

String attachmentFileText=""

if (!attachments.isEmpty()) {
for (Attachment a in attachments) {
def fileName=FilenameUtils.getBaseName(a.getFilename())
//log.warn (fileName)
def fileExtension=FilenameUtils.getExtension(a.getFilename())
//log.warn (fileExtension)
def attachmentFile = aM.streamAttachmentContent(a, new FileInputStreamConsumer(a.getFilename()))

List attachmentFileLines = attachmentFile.text.split('\n')
def righeFile=1
attachmentFileLines.each(){
singleLine->
//log.warn(righeFile)
//log.warn(singleLine)
attachmentFileText=attachmentFileText+singleLine
righeFile=righeFile+1
}
}
}





def inputXML = new XmlParser().parseText(attachmentFileText)

inputXML.requirement.each{
req->
log.warn(req.Key.text())
}


/**

inputXML.requirements.requirement.findAll{
req ->
req.Key!=null
}.each { reqK ->
log.warn("${reqK.Summary.text()}")
}

**/

class FileInputStreamConsumer implements InputStreamConsumer{

private final String filename;
public FileInputStreamConsumer(String filename) {
this.filename = filename;
}
@Override
public File withInputStream(InputStream is) throws IOException {
final File f = File.createTempFile(FilenameUtils.getBaseName(filename), FilenameUtils.getExtension(filename));
StreamUtils.copy(is, new FileOutputStream(f));
return f;
}
}

 

and it seems it reads the file, even though with a lot of warnings.

The file I am reading is an XML exported from Excel.

It seems I'm reading it. Now I need some experience with XML parser.

image.png

Like sujoychakraborty93 likes this
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
November 20, 2019

Nice job.

Yeah I'm not a big fan of working with xml node and the xmlparser. Json is so much easier.

I always get tons of "static type checking" errors in the scriptrunner editor. That's because the editor tries to validate your code but is missing information about what the data type of various variable will be. Those types will be assigned only at runtime.

I mostly ignore those warnings. I only use them as clues to find when code actually fails to run. The "proof is in the pudding" as they say.

Like ABoerio likes this
ABRAR ALI November 15, 2022

Hi @ABoerio , @Peter-Dave Sheehan ,

I have a similar requirement. 

Using your script , I keep getting an error --  org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.

How did you manage to resolve this ?

-Abrar

Andrea Boerio November 16, 2022

Hello @ABRAR ALI , my old script was kinf of a Frankenstein file :-).

And actually I haven't then dedicated so much time to develop it, as the need for reading attachments was no more in the top priority list.

Anyway, the issue you're getting is because it tries to treat as an xml a string that might not represent an xml.

I would comment all the lines related to xml handling (which were very specific to some test I was doing at the time),

Immagine 2022-11-16 091033.png

activate a few logs, to check if you're reading

Immagine 2022-11-16 091348.png

and then try with simple text file attachments.

Or you can also attach an xml file, but simply treat it as a txt file, as I've tried to do a few minutes ago.

Immagine 2022-11-16 091152.png

Then you can try to play with the content and, if it is an xml structure, you might try again to use an xml parser (I'm definetly not an expert).

Ciao, Andrea

ABRAR ALI November 16, 2022

Hi @Andrea Boerio ,

Yes only txt file is being read.

If I attach an Excel or word document , the outcome is a non-human readable format.

image.png-Abrar

Andrea Boerio November 16, 2022

Correct, one thing is getting the attachment, another is handling its content.

With txt files (or txt-like, for example and xls generated form excel, which in the end is text) it's quite easy and human readable, otherwise you should look for some specific library to import.

Ciao, Andrea

Like ABRAR ALI likes this
0 votes
Ondrej Kvinta April 24, 2023

Hi @Peter-Dave Sheehan , 

Is any chance to read attachment similar way at JIRA Cloud.
Thank you 


Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
April 24, 2023

I have no experience with Jira cloud.

Suggest an answer

Log in or Sign up to answer