search_index.rb 3.9 KB

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