Class: Mindee::Input::Source::URLInputSource

Inherits:
Object
  • Object
show all
Defined in:
lib/mindee/input/sources/url_input_source.rb,
sig/mindee/input/sources/url_input_source.rbs

Overview

Load a remote document from a file url.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url) ⇒ URLInputSource

Returns a new instance of URLInputSource.

Parameters:

  • (String)

Raises:



16
17
18
19
20
21
22
# File 'lib/mindee/input/sources/url_input_source.rb', line 16

def initialize(url)
  raise Error::MindeeInputError, 'URL must be HTTPS' unless url.start_with? 'https://'

  logger.debug("URL input: #{url}")

  @url = url
end

Instance Attribute Details

#urlString (readonly)

Returns:

  • (String)


14
15
16
# File 'lib/mindee/input/sources/url_input_source.rb', line 14

def url
  @url
end

Instance Method Details

#as_local_input_source(filename: nil, username: nil, password: nil, token: nil, max_redirects: 3) ⇒ BytesInputSource

Downloads the file from the url, and returns a BytesInputSource wrapper object for it.

Parameters:

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

    Optional name to give to the file.

  • username (String, nil) (defaults to: nil)

    Optional username for authentication.

  • password (String, nil) (defaults to: nil)

    Optional password for authentication.

  • token (String, nil) (defaults to: nil)

    Optional token for JWT-based authentication.

  • max_redirects (Integer) (defaults to: 3)

    Maximum amount of redirects to follow.

  • filename: (String, nil) (defaults to: nil)
  • username: (String, nil) (defaults to: nil)
  • password: (String, nil) (defaults to: nil)
  • token: (String, nil) (defaults to: nil)
  • max_redirects: (Integer) (defaults to: 3)

Returns:



53
54
55
56
57
58
59
60
# File 'lib/mindee/input/sources/url_input_source.rb', line 53

def as_local_input_source(filename: nil, username: nil, password: nil, token: nil, max_redirects: 3)
  filename = fill_filename(filename)
  response_body = fetch_file_content(username: username, password: password, token: token,
                                     max_redirects: max_redirects)
  bytes = StringIO.new(response_body)

  BytesInputSource.new(bytes.read || '', filename || '')
end

#extract_filename_from_url(uri) ⇒ String

Parameters:

  • (::URI::File, ::URI::FTP, ::URI::HTTP, ::URI::HTTPS, ::URI::LDAP, ::URI::LDAPS, ::URI::MailTo, ::URI::WS, ::URI::WSS, ::URI::Generic)

Returns:

  • (String)


88
89
90
91
# File 'lib/mindee/input/sources/url_input_source.rb', line 88

def extract_filename_from_url(uri)
  filename = File.basename(uri.path.to_s)
  filename.empty? ? '' : filename
end

#fetch_file_content(username: nil, password: nil, token: nil, max_redirects: 3) ⇒ String

Fetches the file content from the URL.

Parameters:

  • username (String, nil) (defaults to: nil)

    Optional username for authentication.

  • password (String, nil) (defaults to: nil)

    Optional password for authentication.

  • token (String, nil) (defaults to: nil)

    Optional token for JWT-based authentication.

  • max_redirects (Integer) (defaults to: 3)

    Maximum amount of redirects to follow.

  • username: (String, nil) (defaults to: nil)
  • password: (String, nil) (defaults to: nil)
  • token: (String, nil) (defaults to: nil)
  • max_redirects: (Integer) (defaults to: 3)

Returns:

  • (String)

    The downloaded file content.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/mindee/input/sources/url_input_source.rb', line 69

def fetch_file_content(username: nil, password: nil, token: nil, max_redirects: 3)
  uri = URI.parse(@url)
  request = Net::HTTP::Get.new(uri)

  request['Authorization'] = "Bearer #{token}" if token
  request.basic_auth(username, password) if username && password

  response = make_request(uri, request, max_redirects)
  if response.code.to_i > 299
    raise Error::MindeeAPIError, "Failed to download file: HTTP status code #{response.code}"
  elsif response.code.to_i < 200
    raise Error::MindeeAPIError, "Failed to download file: Invalid response code #{response.code}."
  end

  response.body
end

#fill_filename(filename) ⇒ String

Parameters:

  • (String, nil)

Returns:

  • (String)


93
94
95
96
97
98
99
# File 'lib/mindee/input/sources/url_input_source.rb', line 93

def fill_filename(filename)
  filename ||= extract_filename_from_url(URI.parse(@url))
  if filename.empty? || File.extname(filename).empty?
    filename = generate_file_name(extension: get_file_extension(filename))
  end
  filename
end

#generate_file_name(extension: nil) ⇒ String

Parameters:

  • extension: (String, nil) (defaults to: nil)

Returns:

  • (String)


122
123
124
125
126
# File 'lib/mindee/input/sources/url_input_source.rb', line 122

def generate_file_name(extension: nil)
  extension ||= '.tmp'
  random_string = Array.new(8) { rand(36).to_s(36) }.join
  "mindee_temp_#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}_#{random_string}#{extension}"
end

#get_file_extension(filename) ⇒ String?

Parameters:

  • (String)

Returns:

  • (String, nil)


117
118
119
120
# File 'lib/mindee/input/sources/url_input_source.rb', line 117

def get_file_extension(filename)
  ext = File.extname(filename)
  ext.empty? ? nil : ext.downcase
end

#loggerLogger

Returns:

  • (Logger)


7
# File 'sig/mindee/input/sources/url_input_source.rbs', line 7

def logger: () -> Logger

#make_request(uri, request, max_redirects) ⇒ Net::HTTPRedirection

Parameters:

Returns:



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/mindee/input/sources/url_input_source.rb', line 101

def make_request(uri, request, max_redirects)
  Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
    response = http.request(request)
    if response.is_a?(Net::HTTPRedirection) && max_redirects.positive?
      location = response['location']
      raise Error::MindeeInputError, 'No location in redirection header.' if location.nil?

      new_uri = URI.parse(location)
      request = Net::HTTP::Get.new(new_uri)
      make_request(new_uri, request, max_redirects - 1)
    else
      response
    end
  end
end

#write_to_file(path, filename: nil, username: nil, password: nil, token: nil, max_redirects: 3) ⇒ String

Downloads the file from the URL and saves it to the specified path.

Parameters:

  • path (String)

    Path to save the file to.

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

    Optional name to give to the file.

  • username (String, nil) (defaults to: nil)

    Optional username for authentication.

  • password (String, nil) (defaults to: nil)

    Optional password for authentication.

  • token (String, nil) (defaults to: nil)

    Optional token for JWT-based authentication.

  • max_redirects (Integer) (defaults to: 3)

    Maximum amount of redirects to follow.

  • (String)
  • filename: (String, nil) (defaults to: nil)
  • username: (String, nil) (defaults to: nil)
  • password: (String, nil) (defaults to: nil)
  • token: (String, nil) (defaults to: nil)
  • max_redirects: (Integer) (defaults to: 3)

Returns:

  • (String)

    The full path of the saved file.



33
34
35
36
37
38
39
40
41
42
43
# File 'lib/mindee/input/sources/url_input_source.rb', line 33

def write_to_file(path, filename: nil, username: nil, password: nil, token: nil, max_redirects: 3)
  response_body = fetch_file_content(username: username, password: password, token: token,
                                     max_redirects: max_redirects)

  filename = fill_filename(filename)

  full_path = File.join(path.chomp('/'), filename)
  File.write(full_path, response_body)

  full_path
end