class TusClient::Uploader

Uploads a file to a tus server

Attributes

extra_headers[R]
io[R]
upload_url[R]

Public Class Methods

default_content_type() click to toggle source
# File lib/tusc/uploader.rb, line 11
def self.default_content_type
  'application/offset+octet-stream'
end
from_file_path(file_path:, upload_url:, extra_headers: {}) click to toggle source
# File lib/tusc/uploader.rb, line 15
def self.from_file_path(file_path:, upload_url:, extra_headers: {})
  raise ArgumentError, "file_path is required (#{file_path})" if file_path.blank?

  file_pathname = Pathname.new(file_path)
  raise ArgumentError, "Passed file does NOT exist: #{file_pathname.inspect}" unless file_pathname.exist?

  new(io: file_pathname.open, upload_url: upload_url, extra_headers: extra_headers)
end
new(io:, upload_url:, extra_headers: {}) click to toggle source
# File lib/tusc/uploader.rb, line 24
def initialize(io:, upload_url:, extra_headers: {})
  # fail ArgumentError.new("io must be an IO object") unless io.is_a?(IO) || io.is_a?(StringIO)
  %i[size read close].each do |required_method|
    raise ArgumentError, "io must respond to ##{required_method}" unless io.respond_to?(required_method)
  end
  raise ArgumentError, "upload_url is required (#{upload_url})" if upload_url.blank?
  raise ArgumentError, "upload_url must be a valid url (#{upload_url})" unless upload_url =~ URI::ABS_URI

  @io = io
  @upload_url = upload_url
  @extra_headers = extra_headers
end

Public Instance Methods

cancel_upload() click to toggle source

Optionally, if the client wants to delete an upload because it won’t be needed anymore,

a DELETE request can be sent to the upload URL.
After this, the upload can be cleaned up by the server and resuming the upload is not possible anymore.
# File lib/tusc/uploader.rb, line 40
def cancel_upload
  delete upload_url
end
chunk_size() click to toggle source

Uploaded files are split into “chunks” This provides the size, in bytes, of each chunk

# File lib/tusc/uploader.rb, line 46
def chunk_size
  @chunk_size ||= TusClient.chunk_size
end
content_type() click to toggle source
# File lib/tusc/uploader.rb, line 50
def content_type
  # We used to detect content type, using MimeMagic,
  #  but the videos only uploaded if we used the default (octet-stream)
  #  So... we just use the default
  default_content_type
end
default_content_type() click to toggle source
# File lib/tusc/uploader.rb, line 57
def default_content_type
  self.class.default_content_type
end
headers() click to toggle source
# File lib/tusc/uploader.rb, line 61
def headers
  {
    'Content-Type' => content_type,
    'Tus-Resumable' => tus_resumable_version,
    'Upload-Offset' => 0.to_s
  }.merge(extra_headers)
end
logger() click to toggle source
# File lib/tusc/uploader.rb, line 69
def logger
  @logger ||= TusClient.logger
end
offset_requester() click to toggle source
# File lib/tusc/uploader.rb, line 73
def offset_requester
  @offset_requester ||= TusClient::OffsetRequest.new(upload_url: upload_uri, extra_headers: extra_headers)
end
perform() click to toggle source

Performs the upload, one chunk at a time Starts by asking for the currnet offset Each follow-on request, returns the current offset.

# File lib/tusc/uploader.rb, line 80
def perform
  # TODO: asynch?
  logger.debug { 'Starting upload...' }

  offset = retrieve_offset
  begin
    logger.debug { ['Reading io...', { size: size, offset: offset, chunk_size: chunk_size }] }
    io.pos = offset
    chunk = io.read(chunk_size)
    upload_response = push_chunk(chunk, offset)
    unless upload_response.success?
      raise "Issue uploading file: #{{ code: upload_response.status_code, message: upload_response.body }}."
    end

    offset = upload_response.offset
  end while upload_response.success? && upload_response.incomplete?

  io.close
  upload_response
end
push_chunk(chunk, offset) click to toggle source
# File lib/tusc/uploader.rb, line 101
def push_chunk(chunk, offset)
  push_chunk_via_upload_request(chunk, offset)
end
push_chunk_via_upload_request(chunk, offset) click to toggle source
# File lib/tusc/uploader.rb, line 105
def push_chunk_via_upload_request(chunk, offset)
  upload_request = TusClient::UploadRequest.new(
    upload_uri: upload_url,
    chunk_to_upload: chunk,
    offset: offset,
    file_size: size,
    extra_headers: extra_headers
  )
  upload_request.perform
end
retrieve_offset() click to toggle source
# File lib/tusc/uploader.rb, line 116
def retrieve_offset
  offset_requester.perform.offset
end
size() click to toggle source
# File lib/tusc/uploader.rb, line 120
def size
  @size ||= io.size
end
tus_resumable_version() click to toggle source
# File lib/tusc/uploader.rb, line 124
def tus_resumable_version
  '1.0.0'
end
upload_incomplete() click to toggle source
# File lib/tusc/uploader.rb, line 128
def upload_incomplete
  retrieve_offset < size
end
upload_uri() click to toggle source
# File lib/tusc/uploader.rb, line 132
def upload_uri
  @upload_uri ||= URI.parse(upload_url)
end
video_url() click to toggle source
# File lib/tusc/uploader.rb, line 136
def video_url
  upload_response.fetch('uri')
end