search_index.rb 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. module Ticket::SearchIndex
  3. extend ActiveSupport::Concern
  4. def search_index_attribute_lookup(include_references: true)
  5. attributes = super
  6. return if !attributes
  7. # collect article data
  8. # add tags
  9. attributes['tags'] = tag_list
  10. # mentions
  11. attributes['mention_user_ids'] = mentions.pluck(:user_id)
  12. # checklists
  13. add_checklist(attributes)
  14. # current payload size
  15. total_size_current = 0
  16. # collect article data
  17. attributes['article'] = []
  18. Ticket::Article.where(ticket_id: id).limit(1000).find_each(batch_size: 50).each do |article|
  19. # lookup attributes of ref. objects (normally name and note)
  20. article_attributes = article.search_index_attribute_lookup(include_references: false)
  21. # remove note needed attributes
  22. ignore = %w[message_id_md5 ticket]
  23. ignore.each do |attribute|
  24. article_attributes.delete(attribute)
  25. end
  26. # index raw text body
  27. if article_attributes['content_type'] && article_attributes['content_type'] == 'text/html' && article_attributes['body']
  28. article_attributes['body'] = article_attributes['body'].html2text
  29. end
  30. article_attributes_payload_size = article_attributes.to_json.bytes.size
  31. next if search_index_attribute_lookup_oversized?(total_size_current + article_attributes_payload_size)
  32. # add body size to totel payload size
  33. total_size_current += article_attributes_payload_size
  34. # lookup attachments
  35. article_attributes['attachment'] = []
  36. article.attachments.each do |attachment|
  37. next if search_index_attribute_lookup_file_ignored?(attachment)
  38. next if search_index_attribute_lookup_file_oversized?(attachment, total_size_current)
  39. next if search_index_attribute_lookup_oversized?(total_size_current + attachment.content.bytes.size)
  40. # add attachment size to totel payload size
  41. total_size_current += attachment.content.bytes.size
  42. data = {
  43. 'size' => attachment.size,
  44. '_name' => attachment.filename,
  45. '_content' => Base64.encode64(attachment.content).delete("\n"),
  46. }
  47. article_attributes['attachment'].push data
  48. end
  49. attributes['article'].push article_attributes
  50. end
  51. attributes
  52. end
  53. private
  54. def search_index_attribute_lookup_oversized?(total_size_current)
  55. # if complete payload is to high
  56. total_max_size_in_kb = (Setting.get('es_total_max_size_in_mb') || 300).megabyte
  57. return true if total_size_current >= total_max_size_in_kb
  58. false
  59. end
  60. def search_index_attribute_lookup_file_oversized?(attachment, total_size_current)
  61. return true if attachment.content.blank?
  62. # if attachment size is bigger as configured
  63. attachment_max_size = (Setting.get('es_attachment_max_size_in_mb') || 10).megabyte
  64. return true if attachment.content.bytes.size > attachment_max_size
  65. # if complete size is bigger as configured
  66. return true if search_index_attribute_lookup_oversized?(total_size_current + attachment.content.bytes.size)
  67. false
  68. end
  69. def search_index_attribute_lookup_file_ignored?(attachment)
  70. return true if attachment.filename.blank?
  71. filename_extention = attachment.filename.downcase
  72. filename_extention.gsub!(%r{^.*(\..+?)$}, '\\1')
  73. # list ignored file extensions
  74. attachments_ignore = Setting.get('es_attachment_ignore') || [ '.png', '.jpg', '.jpeg', '.mpeg', '.mpg', '.mov', '.bin', '.exe' ]
  75. return true if attachments_ignore.include?(filename_extention.downcase)
  76. false
  77. end
  78. def add_checklist(attributes)
  79. return if !checklist
  80. attrs = {}
  81. attrs['name'] = checklist.name if checklist.name.present?
  82. items = checklist.items.pluck(:text).compact_blank
  83. attrs['items'] = items if items.present?
  84. return if attrs.blank?
  85. attributes['checklist'] = attrs
  86. end
  87. end