Feature #306 » 0002-store-fulltext-in-the-attachment-model-and-make-it-s.patch
| app/models/attachment.rb | ||
|---|---|---|
| 56 | 56 |
after_rollback :delete_from_disk, :on => :create |
| 57 | 57 |
after_commit :delete_from_disk, :on => :destroy |
| 58 | 58 |
after_commit :reuse_existing_file_if_possible, :on => :create |
| 59 |
after_commit :extract_fulltext, :on => :create |
|
| 59 | 60 | |
| 60 | 61 |
safe_attributes 'filename', 'content_type', 'description' |
| 61 | 62 | |
| ... | ... | |
| 421 | 422 |
digest.size < 64 ? "MD5" : "SHA256" if digest.present? |
| 422 | 423 |
end |
| 423 | 424 | |
| 425 |
def extract_fulltext |
|
| 426 |
if Redmine::Configuration['enable_fulltext_search'] and |
|
| 427 |
readable? and |
|
| 428 |
text = Redmine::TextExtractor.new(self).text |
|
| 429 | ||
| 430 |
update_column :fulltext, text |
|
| 431 |
end |
|
| 432 |
end |
|
| 433 | ||
| 424 | 434 |
private |
| 425 | 435 | |
| 426 | 436 |
def reuse_existing_file_if_possible |
| ... | ... | |
| 479 | 489 |
time.strftime("%Y/%m")
|
| 480 | 490 |
end |
| 481 | 491 | |
| 492 |
def self.extract_fulltext |
|
| 493 |
if Redmine::Configuration['enable_fulltext_search'] |
|
| 494 |
Attachment.where(fulltext: nil).find_in_batches do |group| |
|
| 495 |
group.each{|a| a.extract_fulltext}
|
|
| 496 |
end |
|
| 497 |
else |
|
| 498 |
logger.info "fulltext search is disabled, check configuration.yml" |
|
| 499 |
end |
|
| 500 |
end |
|
| 501 | ||
| 482 | 502 |
# Returns an ASCII or hashed filename that do not |
| 483 | 503 |
# exists yet in the given subdirectory |
| 484 | 504 |
def self.disk_filename(filename, directory=nil) |
| config/configuration.yml.example | ||
|---|---|---|
| 209 | 209 |
# allowed values: :memory, :file, :memcache |
| 210 | 210 |
#openid_authentication_store: :memory |
| 211 | 211 | |
| 212 | ||
| 213 |
# Enable fulltext extraction and fulltext search in attachments. |
|
| 214 |
# To make existing attachments fulltext searchable, run |
|
| 215 |
# rake redmine:attachments:extract_fulltext |
|
| 216 |
# |
|
| 217 |
# Enabled by default. |
|
| 218 |
# |
|
| 219 |
# enable_fulltext_search: false |
|
| 220 | ||
| 212 | 221 |
# Text extraction helper programs. |
| 213 | 222 |
# |
| 214 | 223 |
# 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 | ||
|---|---|---|
| 131 | 131 |
end |
| 132 | 132 | |
| 133 | 133 |
if searchable_options[:search_attachments] && (options[:titles_only] ? options[:attachments] == 'only' : options[:attachments] != '0') |
| 134 |
attachment_columns = ["#{Attachment.table_name}.filename", "#{Attachment.table_name}.description"]
|
|
| 135 |
if Redmine::Configuration['enable_fulltext_search'] |
|
| 136 |
attachment_columns << "#{Attachment.table_name}.fulltext"
|
|
| 137 |
end |
|
| 138 | ||
| 134 | 139 |
r |= fetch_ranks_and_ids( |
| 135 | 140 |
search_scope(user, projects, options). |
| 136 | 141 |
joins(:attachments). |
| 137 |
where(search_tokens_condition(["#{Attachment.table_name}.filename", "#{Attachment.table_name}.description"], tokens, options[:all_words])),
|
|
| 142 |
where(search_tokens_condition(attachment_columns, tokens, options[:all_words])),
|
|
| 138 | 143 |
options[:limit] |
| 139 | 144 |
) |
| 140 | 145 |
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 | ||
|---|---|---|
| 444 | 444 |
puts '(ImageMagick convert not available)' |
| 445 | 445 |
end |
| 446 | 446 | |
| 447 |
def test_should_extract_fulltext |
|
| 448 |
a = Attachment.create( |
|
| 449 |
:container => Issue.find(1), |
|
| 450 |
:file => uploaded_test_file("testfile.txt", "text/plain"),
|
|
| 451 |
:author => User.find(1), |
|
| 452 |
:content_type => 'text/plain') |
|
| 453 |
a.reload |
|
| 454 |
assert a.fulltext.include?("this is a text file for upload tests\r\nwith multiple lines")
|
|
| 455 |
end |
|
| 447 | 456 |
end |