Project

General

Profile

Feature #306 » 0003-store-fulltext-in-the-attachment-model-and-make-it-s.patch

Jens Krämer, 2017-06-21 11:13

View differences:

app/models/attachment.rb
57 57
  after_rollback :delete_from_disk, :on => :create
58 58
  after_commit :delete_from_disk, :on => :destroy
59 59
  after_commit :reuse_existing_file_if_possible, :on => :create
60
  after_commit :extract_fulltext, :on => :create
60 61

  
61 62
  safe_attributes 'filename', 'content_type', 'description'
62 63

  
......
414 415
    digest.size < 64 ? "MD5" : "SHA256" if digest.present?
415 416
  end
416 417

  
418
  def extract_fulltext
419
    if Redmine::Configuration['enable_fulltext_search'] and
420
      readable? and
421
      text = Redmine::TextExtractor.new(self).text
422

  
423
      update_column :fulltext, text
424
    end
425
  end
426

  
417 427
  private
418 428

  
419 429
  def reuse_existing_file_if_possible
......
472 482
    time.strftime("%Y/%m")
473 483
  end
474 484

  
485
  def self.extract_fulltext
486
    if Redmine::Configuration['enable_fulltext_search']
487
      Attachment.where(fulltext: nil).find_in_batches do |group|
488
        group.each{|a| a.extract_fulltext}
489
      end
490
    else
491
      logger.info "fulltext search is disabled, check configuration.yml"
492
    end
493
  end
494

  
475 495
  # Returns an ASCII or hashed filename that do not
476 496
  # exists yet in the given subdirectory
477 497
  def self.disk_filename(filename, directory=nil)
config/configuration.yml.example
212 212
  # allowed values: :memory, :file, :memcache
213 213
  #openid_authentication_store: :memory
214 214

  
215

  
216
  # Enable fulltext extraction and fulltext search in attachments.
217
  # To make existing attachments fulltext searchable, run
218
  # rake redmine:attachments:extract_fulltext
219
  #
220
  # Enabled by default.
221
  #
222
  # enable_fulltext_search: false
223

  
215 224
  # Text extraction helper programs.
216 225
  #
217 226
  # commands should write the resulting plain text to STDOUT. Use __FILE__ as
db/migrate/20170613064930_add_fulltext_to_attachments.rb
1
class AddFulltextToAttachments < ActiveRecord::Migration
2
  def change
3
    add_column :attachments, :fulltext, :text, :limit => 4.megabytes # room for at least 1 million characters / approx. 80 pages of english text
4
  end
5
end
lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb
132 132
            end
133 133

  
134 134
            if searchable_options[:search_attachments] && (options[:titles_only] ? options[:attachments] == 'only' : options[:attachments] != '0')
135
              attachment_columns = ["#{Attachment.table_name}.filename", "#{Attachment.table_name}.description"]
136
              if Redmine::Configuration['enable_fulltext_search']
137
                attachment_columns << "#{Attachment.table_name}.fulltext"
138
              end
139

  
135 140
              r |= fetch_ranks_and_ids(
136 141
                search_scope(user, projects, options).
137 142
                joins(:attachments).
138
                where(search_tokens_condition(["#{Attachment.table_name}.filename", "#{Attachment.table_name}.description"], tokens, options[:all_words])),
143
                where(search_tokens_condition(attachment_columns, tokens, options[:all_words])),
139 144
                options[:limit]
140 145
              )
141 146
              queries += 1
lib/redmine/configuration.rb
21 21
    # Configuration default values
22 22
    @defaults = {
23 23
      'email_delivery' => nil,
24
      'enable_fulltext_search' => true,
24 25
      'max_concurrent_ajax_uploads' => 2
25 26
    }
26 27

  
lib/tasks/redmine.rake
31 31
    task :update_digests => :environment do
32 32
      Attachment.update_digests_to_sha256
33 33
    end
34

  
35
    desc 'Makes existing attachments fulltext searchable'
36
    task :extract_fulltext => :environment do
37
      Attachment.extract_fulltext
38
    end
34 39
  end
35 40

  
36 41
  namespace :tokens do
test/unit/attachment_test.rb
447 447
    puts '(ImageMagick convert not available)'
448 448
  end
449 449

  
450
  def test_should_extract_fulltext
451
    a = Attachment.create(
452
      :container => Issue.find(1),
453
      :file => uploaded_test_file("testfile.txt", "text/plain"),
454
      :author => User.find(1),
455
      :content_type => 'text/plain')
456
    a.reload
457
    assert a.fulltext.include?("this is a text file for upload tests\r\nwith multiple lines")
458
  end
459

  
450 460
end
(2-2/11)