Skip to content

Commit

Permalink
Merge pull request #422 from marlinpierce/attachment-download
Browse files Browse the repository at this point in the history
Attachment download contents
  • Loading branch information
bobbrodie authored Apr 6, 2024
2 parents 302d8b8 + 3e0ddfb commit 29c506c
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
40 changes: 40 additions & 0 deletions lib/jira/resource/attachment.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'net/http/post/multipart'
require 'open-uri'

module JIRA
module Resource
Expand All @@ -19,6 +20,45 @@ def self.meta(client)
parse_json(response.body)
end

# Opens a file streaming the download of the attachment.
# @example Write file contents to a file.
# File.open('some-filename', 'wb') do |output|
# download_file do |file|
# IO.copy_stream(file, output)
# end
# end
# @example Stream file contents for an HTTP response.
# response.headers[ "Content-Type" ] = "application/octet-stream"
# download_file do |file|
# chunk = file.read(8000)
# while chunk.present? do
# response.stream.write(chunk)
# chunk = file.read(8000)
# end
# end
# response.stream.close
# @param [Hash] headers Any additional headers to call Jira.
# @yield |file|
# @yieldparam [IO] file The IO object streaming the download.
def download_file(headers = {}, &block)
default_headers = client.options[:default_headers]
URI.open(content, default_headers.merge(headers), &block)
end

# Downloads the file contents as a string object.
#
# Note that this reads the contents into a ruby string in memory.
# A file might be very large so it is recommend to avoid this unless you are certain about doing so.
# Use the download_file method instead and avoid calling the read method without a limit.
#
# @param [Hash] headers Any additional headers to call Jira.
# @return [String,NilClass] The file contents.
def download_contents(headers = {})
download_file(headers) do |file|
file.read
end
end

def save!(attrs, path = url)
file = attrs['file'] || attrs[:file] # Keep supporting 'file' parameter as a string for backward compatibility
mime_type = attrs[:mimeType] || 'application/binary'
Expand Down
37 changes: 37 additions & 0 deletions spec/jira/resource/attachment_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,43 @@
end
end

context 'there is an attachment on an issue' do
let(:client) do
JIRA::Client.new(username: 'username', password: 'password', auth_type: :basic, use_ssl: false )
end
let(:attachment_file_contents) { 'file contents' }
let(:file_target) { double(read: :attachment_file_contents) }
let(:attachment_url) { "https:jirahost/secure/attachment/32323/myfile.txt" }
subject(:attachment) do
JIRA::Resource::Attachment.new(
client,
issue: JIRA::Resource::Issue.new(client),
attrs: { 'author' => { 'foo' => 'bar' }, 'content' => attachment_url }
)
end

describe '.download_file' do
it 'passes file object to block' do
expect(URI).to receive(:open).with(attachment_url, anything).and_yield(file_target)

attachment.download_file do |file|
expect(file).to eq(file_target)
end

end
end

describe '.download_contents' do
it 'downloads the file contents as a string' do
expect(URI).to receive(:open).with(attachment_url, anything).and_return(attachment_file_contents)

result_str = attachment.download_contents

expect(result_str).to eq(attachment_file_contents)
end
end
end

context 'when there is a local file' do
let(:file_name) { 'short.txt' }
let(:file_size) { 11 }
Expand Down

0 comments on commit 29c506c

Please sign in to comment.