Class: Uploadcare::Internal::UploadIo

Inherits:
Object
  • Object
show all
Defined in:
lib/uploadcare/internal/upload_io.rb

Overview

Wraps upload inputs so multipart and direct uploads can treat files and streams uniformly.

Constant Summary collapse

DEFAULT_FILENAME =

Fallback filename used when the source object does not expose one.

'upload.bin'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io, original_filename:, cleanup:) ⇒ UploadIo

Returns a new instance of UploadIo.

Parameters:

  • io (IO)
  • original_filename (String)
  • cleanup (Boolean)


69
70
71
72
73
# File 'lib/uploadcare/internal/upload_io.rb', line 69

def initialize(io, original_filename:, cleanup:)
  @io = io
  @original_filename = original_filename
  @cleanup = cleanup
end

Instance Attribute Details

#ioObject (readonly)

Returns the value of attribute io.



10
11
12
# File 'lib/uploadcare/internal/upload_io.rb', line 10

def io
  @io
end

#original_filenameObject (readonly)

Returns the value of attribute original_filename.



10
11
12
# File 'lib/uploadcare/internal/upload_io.rb', line 10

def original_filename
  @original_filename
end

Class Method Details

.extract_filename(source) ⇒ String

Parameters:

  • source (IO)

Returns:

  • (String)


38
39
40
41
42
43
44
45
46
# File 'lib/uploadcare/internal/upload_io.rb', line 38

def self.extract_filename(source)
  if source.respond_to?(:original_filename) && source.original_filename && !source.original_filename.empty?
    source.original_filename
  elsif path_backed?(source)
    ::File.basename(source.path)
  else
    DEFAULT_FILENAME
  end
end

.path_backed?(source) ⇒ Boolean

Parameters:

  • source (IO)

Returns:

  • (Boolean)


29
30
31
32
33
34
# File 'lib/uploadcare/internal/upload_io.rb', line 29

def self.path_backed?(source)
  source.respond_to?(:path) &&
    source.path &&
    ::File.file?(source.path) &&
    ::File.readable?(source.path)
end

.wrap(source, filename: nil) ⇒ Uploadcare::Internal::UploadIo

Wrap a readable source into a unified upload object.

Parameters:

  • source (IO)
  • filename (String, nil) (defaults to: nil)

Returns:

Raises:

  • (ArgumentError)


17
18
19
20
21
22
23
24
25
# File 'lib/uploadcare/internal/upload_io.rb', line 17

def self.wrap(source, filename: nil)
  raise ArgumentError, 'file must be a readable IO object' unless source.respond_to?(:read)

  if path_backed?(source)
    new(source, original_filename: filename || extract_filename(source), cleanup: false)
  else
    wrap_stream(source, filename: filename || extract_filename(source))
  end
end

.wrap_stream(source, filename:) ⇒ Uploadcare::Internal::UploadIo

Materialize a non-path-backed stream into a tempfile.

Parameters:

  • source (IO)
  • filename (String)

Returns:



53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/uploadcare/internal/upload_io.rb', line 53

def self.wrap_stream(source, filename:)
  extension = ::File.extname(filename.to_s)
  tempfile = Tempfile.new(['uploadcare-upload', extension.empty? ? '.bin' : extension])
  tempfile.binmode

  source.rewind if source.respond_to?(:rewind)
  IO.copy_stream(source, tempfile)
  tempfile.rewind
  source.rewind if source.respond_to?(:rewind)

  new(tempfile, original_filename: filename, cleanup: true)
end

Instance Method Details

#close!void

This method returns an undefined value.

Close and unlink the wrapped tempfile when cleanup is enabled.



105
106
107
108
109
# File 'lib/uploadcare/internal/upload_io.rb', line 105

def close!
  return unless @cleanup

  io.close!
end

#pathString

Returns:

  • (String)


76
77
78
# File 'lib/uploadcare/internal/upload_io.rb', line 76

def path
  io.path
end

#read(*args) ⇒ String?

Returns:

  • (String, nil)


88
89
90
# File 'lib/uploadcare/internal/upload_io.rb', line 88

def read(*args)
  io.read(*args)
end

#rewindvoid

This method returns an undefined value.



98
99
100
# File 'lib/uploadcare/internal/upload_io.rb', line 98

def rewind
  io.rewind
end

#seek(*args) ⇒ Integer

Returns:

  • (Integer)


93
94
95
# File 'lib/uploadcare/internal/upload_io.rb', line 93

def seek(*args)
  io.seek(*args)
end

#sizeInteger

Returns:

  • (Integer)


81
82
83
84
85
# File 'lib/uploadcare/internal/upload_io.rb', line 81

def size
  return io.size if io.respond_to?(:size)

  ::File.size(path)
end