123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- class FailedEmail < ApplicationModel
- def reprocess(params = {})
- ticket, _article, _user, _mail = Channel::EmailParser.new.process_with_timeout(params, data)
- raise __('Unknown error: Could not create a ticket from this email.') if !ticket
- destroy
- ticket
- rescue => e
- self.retries += 1
- self.parsing_error = e
- save!
- message = "Can't reprocess failed email '#{id}'. This was attempt # #{retries}."
- puts "ERROR: #{message}" # rubocop:disable Rails/Output
- puts "ERROR: #{e.inspect}" # rubocop:disable Rails/Output
- Rails.logger.error message
- Rails.logger.error e
- false
- end
- def parsing_error=(input)
- message = case input
- when StandardError
- "#{input.inspect}\n#{input.backtrace&.join("\n")}"
- else
- input
- end
- write_attribute :parsing_error, message
- end
- def self.by_filepath(filepath)
- id = Pathname
- .new(filepath)
- .basename
- .to_s
- .delete_suffix('.eml')
- return if id.include?('.')
- find_by(id:)
- end
- def self.reprocess_all(params = {})
- reorder(id: :desc)
- .in_batches
- .each_record
- .select { |elem| elem.reprocess(params) }
- .map { |elem| "#{elem.id}.eml" }
- end
- def self.generate_path
- Rails.root.join('tmp', "failed-email-#{SecureRandom.uuid}")
- end
- def self.export_all(path = generate_path)
- in_batches
- .each_record
- .map { |elem| elem.export(path) }
- end
- def export(path = self.class.generate_path)
- FileUtils.mkdir_p(path)
- full_path = path.join("#{id}.eml")
- File.binwrite full_path, data
- full_path
- end
- def self.import_all(path)
- Dir
- .each_child(path)
- .filter_map do |filename|
- next if !filename.ends_with?('.eml')
- import(path.join(filename))
- end
- end
- def self.import(filepath)
- failed_email = FailedEmail.by_filepath(filepath.basename)
- return if !failed_email
- new_data = File.binread filepath
- if new_data != failed_email.data
- failed_email.data = new_data
- failed_email.parsing_error = nil
- failed_email.save!
- end
- return if !failed_email.reprocess
- filepath.unlink
- filepath
- end
- end
|