search_index.rb 3.5 KB

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