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 |