Feature #306 » 0003-store-fulltext-in-the-attachment-model-and-make-it-s.patch
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 |