mirror of
https://github.com/zammad/zammad
synced 2026-05-24 09:48:36 +00:00
106 lines
2.3 KiB
Ruby
106 lines
2.3 KiB
Ruby
# Copyright (C) 2012-2026 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
|