lib/wolf_core/utils/file_utils.rb
require_relative "logging_utils" require_relative "string_utils" module WolfCore module FileUtils extend WolfCore::LoggingUtils extend WolfCore::StringUtils module_function 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 def safe_require(missing_files) # rubocop:disable Metrics/MethodLength 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" end missing_files << file if error_counter[file] < 15 end end end 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 def encode_file_to_base64_from_url(url) # rubocop:disable Metrics/MethodLength uri, response = download_file_from_url(url).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 def download_file_from_url(url) uri = URI.parse(url) response = Net::HTTP.get_response(uri) raise_service_error({ message: "Failed to download file", url: url }) unless response.is_a?(Net::HTTPSuccess) { uri: uri, response: response } end def bytes_from_url(url) uri, response = download_file_from_url(url).values_at(:uri, :response) bytes = response.body filename = filename_from_response(response, uri) { bytes: bytes, filename: filename } end 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 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 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 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 end end