Module: WolfCore::FileUtils

Extended by:
LoggingUtils, StringUtils
Defined in:
lib/wolf_core/utils/file_utils.rb

Class Method Summary collapse

Methods included from LoggingUtils

log_object

Methods included from StringUtils

base64_encoded?, camelcase_to_spaces, clean_phone_number, deep_parse_json, hash_str_to_json, remove_blank_spaces, remove_non_alphanumeric_chars, split_address, split_name, to_kebab_case, to_snake_case, valid_json?, valid_url?

Class Method Details

.base64_string_to_bytes(base64_string) ⇒ Object



142
143
144
145
146
147
148
149
# File 'lib/wolf_core/utils/file_utils.rb', line 142

def base64_string_to_bytes(base64_string)
  begin
    bytes = Base64.strict_decode64(base64_string)
    bytes
  rescue ArgumentError
    raise_service_error({ message: 'Failed to decode base64 string', base64_string: base64_string })
  end
end

.bytes_from_file(file) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/wolf_core/utils/file_utils.rb', line 129

def bytes_from_file(file)
  if file.is_a?(ActionDispatch::Http::UploadedFile)
    file.read
  elsif base64_encoded?(file)
    base64_string_to_bytes(file)
  else
    raise_service_error({
      message: "Can not generate bytes from this file",
      file: file,
    })
  end
end

.bytes_from_url(url, headers: {}) ⇒ Object



78
79
80
81
82
83
# File 'lib/wolf_core/utils/file_utils.rb', line 78

def bytes_from_url(url, headers: {})
  uri, response = download_file_from_url(url, headers: headers).values_at(:uri, :response)
  bytes = response.body
  filename = filename_from_response(response, uri)
  { bytes: bytes, filename: filename }
end

.create_tempfile(filename, bytes) ⇒ Object



151
152
153
154
155
156
157
# File 'lib/wolf_core/utils/file_utils.rb', line 151

def create_tempfile(filename, bytes)
  temp_file = Tempfile.new([File.basename(filename, ".*"), File.extname(filename)])
  temp_file.binmode
  temp_file.write(bytes)
  temp_file.rewind
  temp_file
end

.delete_files(*args) ⇒ Object



39
40
41
42
43
44
45
46
47
48
# File 'lib/wolf_core/utils/file_utils.rb', line 39

def delete_files(*args)
  pattern = File.join(*args)
  files_to_delete = Dir.glob(pattern)
  files_to_delete.each do |file|
    File.delete(file)
    log_object "File deleted: #{file}"
  end

  log_object "File Deleting Process Finished! (#{files_to_delete.size} files deleted)"
end

.download_file_from_url(url, headers: {}) ⇒ Object



67
68
69
70
71
72
73
74
75
76
# File 'lib/wolf_core/utils/file_utils.rb', line 67

def download_file_from_url(url, headers: {})
  uri = URI.parse(url)
  request = Net::HTTP::Get.new(uri)
  headers.each { |key, value| request[key] = value }
  response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
    http.request(request)
  end
  raise_service_error({ message: "Failed to download file", url: url }) unless response.is_a?(Net::HTTPSuccess)
  { uri: uri, response: response }
end

.encode_file_to_base64_from_url(url, headers: {}) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/wolf_core/utils/file_utils.rb', line 50

def encode_file_to_base64_from_url(url, headers: {})
  uri, response = download_file_from_url(url, headers: headers).values_at(:uri, :response)
  bytes = response.body

  encoded_file = Base64.strict_encode64(bytes)

  filename = filename_from_response(response, uri)
  log_object filename, title: "filename is"
  { filename: filename, encoded_file: encoded_file }
rescue StandardError => e
  raise_service_error({
                        message: "Failed to encode file url",
                        encode_file_error: { message: e.message, backtrace: e.backtrace },
                        url: url
                      })
end

.filename_from_response(response, uri) ⇒ Object



85
86
87
88
89
90
91
92
93
# File 'lib/wolf_core/utils/file_utils.rb', line 85

def filename_from_response(response, uri)
  content_disposition = response["content-disposition"]
  if content_disposition
    match = content_disposition.match(/filename="?([^"]+)"?/)
    match ? match[1] : File.basename(uri.path)
  else
    File.basename(uri.path)
  end
end

.generate_url_from_file(file:, api_key:) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/wolf_core/utils/file_utils.rb', line 95

def generate_url_from_file(file:, api_key:)
  url = URI.parse("https://www.filestackapi.com/api/store/S3?key=#{api_key}")
  request = Net::HTTP::Post.new(url)
  request["Content-Type"] = "application/octet-stream"
  request.body = bytes_from_file(file)

  response = Net::HTTP.start(url.hostname, url.port, use_ssl: true) do |http|
    http.request(request)
  end

  parse_json_error = nil
  if response.is_a?(Net::HTTPSuccess)
    begin
      response_body = JSON.parse(response.body)
    rescue => e
      parse_json_error = {
        message: e.message,
        backtrace: e.backtrace,
      }
    end
    return response_body['url'] if response_body['url'].present?
  end

  raise_service_error({
    message: "Failed to generate url from file",
    url: url,
    file: file,
    request: request,
    response: response,
    response_body: response.body,
    parse_json_error: parse_json_error,
  })
end

.require_relative_folder(*folders) ⇒ Object



12
13
14
15
16
17
# File 'lib/wolf_core/utils/file_utils.rb', line 12

def require_relative_folder(*folders)
  folder_files = File.join(*folders, "**", "*.rb")
  files_to_require = Dir[folder_files].sort
  # log_object files_to_require, title: 'Files to require are'
  safe_require(files_to_require)
end

.safe_require(missing_files) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/wolf_core/utils/file_utils.rb', line 19

def safe_require(missing_files)
  error_counter = {}
  while missing_files.any?
    files_to_require = missing_files
    missing_files = []
    files_to_require.each do |file|
      # log_object "Requiring file: #{file}"
      require_relative file
    rescue NameError => e
      error_counter[file] = error_counter[file].to_i + 1
      if error_counter[file] >= 10
        log_object "Error requiring file: #{file}"
        log_object e, title: "Error is"
        log_object e.backtrace, title: "Error backtrace is"
      end
      missing_files << file if error_counter[file] < 15
    end
  end
end