attachments.rb 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class Sequencer::Unit::Import::Freshdesk::Conversation::Attachments < Sequencer::Unit::Base
  3. prepend ::Sequencer::Unit::Import::Common::Model::Mixin::Skip::Action
  4. optional :action
  5. skip_action :skipped, :failed
  6. uses :resource, :instance, :model_class, :dry_run
  7. def self.mutex
  8. @mutex ||= Mutex.new
  9. end
  10. def process
  11. return if skip?
  12. download_threads.each(&:join)
  13. end
  14. private
  15. def local_attachments
  16. @local_attachments ||= instance.attachments&.filter { |attachment| attachment.preferences&.dig('Content-Disposition') != 'inline' }
  17. end
  18. def skip?
  19. ensure_common_ground
  20. attachments_equal?
  21. end
  22. def ensure_common_ground
  23. return if attachments_equal?
  24. local_attachments.each(&:delete)
  25. end
  26. def attachments_equal?
  27. resource['attachments'].count == local_attachments.count
  28. end
  29. def download_threads
  30. resource['attachments'].map do |attachment|
  31. Thread.new do
  32. sync(attachment)
  33. end
  34. end
  35. end
  36. def sync(attachment)
  37. logger.debug { "Downloading attachment #{attachment}" }
  38. response = ::UserAgent.get(
  39. attachment['attachment_url'],
  40. {},
  41. {
  42. open_timeout: 20,
  43. read_timeout: 240,
  44. verify_ssl: true,
  45. },
  46. )
  47. if !response.success?
  48. logger.error response.error
  49. return
  50. end
  51. return if dry_run
  52. store_attachment(attachment, response)
  53. end
  54. def store_attachment(attachment, response)
  55. self.class.mutex.synchronize do
  56. ::Store.create!(
  57. object: model_class.name,
  58. o_id: instance.id,
  59. data: response.body,
  60. filename: attachment['name'],
  61. preferences: {
  62. 'Content-Type' => attachment['content_type']
  63. },
  64. created_by_id: 1
  65. )
  66. end
  67. end
  68. end