diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e914f02..0e258735 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,17 @@ Changelog for Redmine DMSF ========================== +4.2.1 *2025-07-10* +------------------ + + Searching in multiple revisions + +IMPORTANT: Issue tracking numbering has been restarted after the movement to the new repository + +* Bug: #1 - Can't install 3.2.4 on redmine 5.0 +* Bug: #3 - Download CSV file leads to 404 +* New: #4 - Searching in multiple revisions + 4.2.0 *2025-07-04* ------------------ @@ -92,15 +103,10 @@ NOTE: These issues are still from the original danmunn's repository ------------------ Multiple file upload fix + Uploaded file size fix * Bug: #1559 - Multiple files upload * Bug: #1558 - Deleting of uploaded files - -3.2.3 *2024-10-18* ------------------- - - Uploaded file size fix - * Bug: 1556 - Wrong file size when uploading documents 3.2.2 *2024-10-09* diff --git a/README.md b/README.md index 57c71b65..a89876e4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Redmine DMSF Plugin 4.2.0 +# Redmine DMSF Plugin 4.2.1 [](https://github.com/picman/redmine_dmsf/actions/workflows/rubyonrails.yml) [](https://github.com/support-ukraine/support-ukraine) diff --git a/app/controllers/dmsf_files_controller.rb b/app/controllers/dmsf_files_controller.rb index 49d9d766..49fe0451 100644 --- a/app/controllers/dmsf_files_controller.rb +++ b/app/controllers/dmsf_files_controller.rb @@ -81,7 +81,7 @@ class DmsfFilesController < ApplicationController send_file pdf_preview, filename: "#{basename}.pdf", type: 'application/pdf', disposition: 'inline' # Text preview elsif !api_request? && params[:download].blank? && (@file.size <= Setting.file_max_size_displayed.to_i.kilobyte) && - (@file.text? || @file.markdown? || @file.textile?) && !@file.html? + (@file.text? || @file.markdown? || @file.textile?) && !@file.html? && formats.include?(:html) @content = File.read(@revision.disk_file, mode: 'rb') render action: 'document' # Offer the file for download diff --git a/app/models/dmsf_file.rb b/app/models/dmsf_file.rb index 1aa83990..14f36f97 100644 --- a/app/models/dmsf_file.rb +++ b/app/models/dmsf_file.rb @@ -51,22 +51,56 @@ class DmsfFile < ApplicationRecord case_sensitive: true } - acts_as_event title: proc { |o| o.name }, - description: proc { |o| - desc = Redmine::Search.cache_store.fetch("DmsfFile-#{o.id}") - if desc - Redmine::Search.cache_store.delete("DmsfFile-#{o.id}") - else - # Set desc to an empty string if o.description is nil - desc = o.description.nil? ? +'' : +o.description - desc += ' / ' if o.description.present? && o.last_revision.comment.present? - desc += o.last_revision.comment if o.last_revision.comment.present? - end - desc - }, - url: proc { |o| { controller: 'dmsf_files', action: 'view', id: o } }, - datetime: proc { |o| o.updated_at }, - author: proc { |o| o.last_revision.user } + acts_as_event( + title: proc { |o| + @searched_revision = nil + o.dmsf_file_revisions.visible.each do |r| + key = "DmsfFile-#{o.id}-#{r.id}" + @desc = Redmine::Search.cache_store.fetch(key) + next unless @desc + + Redmine::Search.cache_store.delete key + @searched_revision = r + break + end + if @searched_revision && (@searched_revision != o.last_revision) + "#{o.name} (r#{@searched_revision.id})" + else + o.name + end + }, + description: proc { |o| + unless @desc + # Set desc to an empty string if o.description is nil + @desc = o.description.nil? ? +'' : +o.description + @desc += ' / ' if o.description.present? && o.last_revision.comment.present? + @desc += o.last_revision.comment if o.last_revision.comment.present? + end + @desc + }, + url: proc { |o| + if @searched_revision + { controller: 'dmsf_files', action: 'view', id: o.id, download: @searched_revision.id, + filename: o.name } + else + { controller: 'dmsf_files', action: 'view', id: o.id, filename: o.name } + end + }, + datetime: proc { |o| + if @searched_revision + @searched_revision.updated_at + else + o.updated_at + end + }, + author: proc { |o| + if @searched_revision + @searched_revision.user + else + o.last_revision.user + end + } + ) acts_as_watchable acts_as_searchable( columns: [ @@ -415,20 +449,21 @@ class DmsfFile < ApplicationRecord filename = dochash['url'] next unless filename - dmsf_attrs = filename.scan(%r{^([^/]+/[^_]+)_(\d+)_(.*)$}) + dmsf_attrs = filename.scan(%r{^\d{4}/\d{2}/(\d{12}_(\d+)_.*)$}) id_attribute = 0 id_attribute = dmsf_attrs[0][1] if dmsf_attrs.length.positive? next if dmsf_attrs.empty? || id_attribute.to_i.zero? - next unless results.none? { |f| f.id.to_s == id_attribute } dmsf_file = DmsfFile.visible.where(limit_options).find_by(id: id_attribute) - next unless dmsf_file && DmsfFolder.permissions?(dmsf_file.dmsf_folder) && user.allowed_to?(:view_dmsf_files, dmsf_file.project) && (project_ids.blank? || project_ids.include?(dmsf_file.project_id)) + rev_id = DmsfFileRevision.where(dmsf_file_id: dmsf_file.id, disk_filename: dmsf_attrs[0][0]) + .pick(:id) if dochash['sample'] - Redmine::Search.cache_store.write("DmsfFile-#{dmsf_file.id}", dochash['sample'].force_encoding('UTF-8')) + Redmine::Search.cache_store.write("DmsfFile-#{dmsf_file.id}-#{rev_id}", + dochash['sample'].force_encoding('UTF-8')) end break if options[:limit].present? && results.count >= options[:limit] diff --git a/app/views/settings/_dmsf_settings.html.erb b/app/views/settings/_dmsf_settings.html.erb index c3164b50..47968b35 100644 --- a/app/views/settings/_dmsf_settings.html.erb +++ b/app/views/settings/_dmsf_settings.html.erb @@ -324,12 +324,10 @@
- <%= l(:text_fulltext_search, cmd1: 'libreoffice', cmd2: 'pdftotext') %> + <%= l(:label_full_text) %> -
+ <% if RedmineDmsf::Plugin.lib_available?('xapian') %><%= content_tag :label, l(:label_index_database) %> diff --git a/config/locales/cs.yml b/config/locales/cs.yml index e6c0603a..783e3410 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -470,8 +470,6 @@ cs: label_remove_original_documents_module: Odstranit původní modul Dokumenty - text_fulltext_search: 'Full-textové vyhledávání v dokumentech vyžaduje přítomnost %{cmd1} and %{cmd2} na serveru.' - notice_entries_copied: Kopírování se podařilo notice_entries_moved: Přesun se podařil label_dmsf_file_revision: DMS Dokument rev. diff --git a/config/locales/de.yml b/config/locales/de.yml index 4c6fc8b4..90c13c14 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -465,8 +465,6 @@ de: label_remove_original_documents_module: Original Projektmodule Dokumente entfernen - text_fulltext_search: 'Full-text Suche in Dokumente fordert die Existenz %{cmd1} and %{cmd2} auf dem Server.' - notice_entries_copied: Kopieren ist gelungen notice_entries_moved: Verschieben ist gelungen label_dmsf_file_revision: DMS Dokument Rev. diff --git a/config/locales/en.yml b/config/locales/en.yml index 0a3b8f12..b8032cab 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -469,8 +469,6 @@ en: label_remove_original_documents_module: Remove the original Documents module - text_fulltext_search: 'Full-text search in documents requires presence of %{cmd1} and %{cmd2} commands on the server.' - notice_entries_copied: Copying has succeeded notice_entries_moved: Moving has succeeded label_dmsf_file_revision: DMS Document rev. diff --git a/config/locales/es.yml b/config/locales/es.yml index 85757eed..850d6109 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -469,8 +469,6 @@ es: label_remove_original_documents_module: Remove the original Documents module - text_fulltext_search: 'Full-text search in documents requires presence of %{cmd1} and %{cmd2} commands on the server.' - notice_entries_copied: Copying has succeeded notice_entries_moved: Moving has succeeded label_dmsf_file_revision: DMS Document rev. diff --git a/config/locales/fa.yml b/config/locales/fa.yml index 77e67a05..9298d77b 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -448,8 +448,6 @@ fa: label_remove_original_documents_module: Remove the original Documents module - text_fulltext_search: 'Full-text search in documents requires presence of %{cmd1} and %{cmd2} commands on the server.' - notice_entries_copied: Copying has succeeded notice_entries_moved: Moving has succeeded label_dmsf_file_revision: DMS Document rev. diff --git a/config/locales/fr.yml b/config/locales/fr.yml index ea99646a..d0a46667 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -469,8 +469,6 @@ fr: label_remove_original_documents_module: Remove the original Documents module - text_fulltext_search: 'Full-text search in documents requires presence of %{cmd1} and %{cmd2} commands on the server.' - notice_entries_copied: Copying has succeeded notice_entries_moved: Moving has succeeded label_dmsf_file_revision: DMS Document rev. diff --git a/config/locales/hu.yml b/config/locales/hu.yml index b02b0401..29a3edda 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -468,8 +468,6 @@ hu: label_remove_original_documents_module: Remove the original Documents module - text_fulltext_search: 'Full-text search in documents requires presence of %{cmd1} and %{cmd2} commands on the server.' - notice_entries_copied: Copying has succeeded notice_entries_moved: Moving has succeeded label_dmsf_file_revision: DMS Document rev. diff --git a/config/locales/it.yml b/config/locales/it.yml index d4ef24a0..43cc1f6c 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -469,8 +469,6 @@ it: # Italian strings thx 2 Matteo Arceci! label_remove_original_documents_module: Remove the original Documents module - text_fulltext_search: 'Full-text search in documents requires presence of %{cmd1} and %{cmd2} commands on the server.' - notice_entries_copied: Copying has succeeded notice_entries_moved: Moving has succeeded label_dmsf_file_revision: DMS Document rev. diff --git a/config/locales/ja.yml b/config/locales/ja.yml index f9087d21..79a2ff00 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -470,8 +470,6 @@ ja: label_remove_original_documents_module: Remove the original Documents module - text_fulltext_search: 'Full-text search in documents requires presence of %{cmd1} and %{cmd2} commands on the server.' - notice_entries_copied: Copying has succeeded notice_entries_moved: Moving has succeeded label_dmsf_file_revision: DMS Document rev. diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 68aa478a..941a64b9 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -469,8 +469,6 @@ ko: label_remove_original_documents_module: Remove the original Documents module - text_fulltext_search: 'Full-text search in documents requires presence of %{cmd1} and %{cmd2} commands on the server.' - notice_entries_copied: Copying has succeeded notice_entries_moved: Moving has succeeded label_dmsf_file_revision: DMS Document rev. diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 1ed00e21..b9dd3eb7 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -469,8 +469,6 @@ nl: label_remove_original_documents_module: Remove the original Documents module - text_fulltext_search: 'Full-text search in documents requires presence of %{cmd1} and %{cmd2} commands on the server.' - notice_entries_copied: Copying has succeeded notice_entries_moved: Moving has succeeded label_dmsf_file_revision: DMS Document rev. diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 618e1ff2..b8dd78cf 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -469,8 +469,6 @@ pl: label_remove_original_documents_module: Remove the original Documents module - text_fulltext_search: 'Full-text search in documents requires presence of %{cmd1} and %{cmd2} commands on the server.' - notice_entries_copied: Copying has succeeded notice_entries_moved: Moving has succeeded label_dmsf_file_revision: DMS Document rev. diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index b00355ef..f6dcb30c 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -469,8 +469,6 @@ pt-BR: label_remove_original_documents_module: Remove the original Documents module - text_fulltext_search: 'Full-text search in documents requires presence of %{cmd1} and %{cmd2} commands on the server.' - notice_entries_copied: Copying has succeeded notice_entries_moved: Moving has succeeded label_dmsf_file_revision: DMS Document rev. diff --git a/config/locales/sl.yml b/config/locales/sl.yml index e26aca4a..f4b76e58 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -469,8 +469,6 @@ sl: label_remove_original_documents_module: Remove the original Documents module - text_fulltext_search: 'Full-text search in documents requires presence of %{cmd1} and %{cmd2} commands on the server.' - notice_entries_copied: Copying has succeeded notice_entries_moved: Moving has succeeded label_dmsf_file_revision: DMS Document rev. diff --git a/config/locales/uk.yml b/config/locales/uk.yml index efe5b810..dec75710 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -471,8 +471,6 @@ uk: label_remove_original_documents_module: Видалити модуль оригінальних документів - text_fulltext_search: 'Повнотекстовий пошук вимагає наявності %{cmd1} та %{cmd2} команд на сервері.' - notice_entries_copied: Copying has succeeded notice_entries_moved: Moving has succeeded label_dmsf_file_revision: DMS Document rev. diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 8a612d20..6ec983a7 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -468,8 +468,6 @@ zh-TW: label_remove_original_documents_module: Remove the original Documents module - text_fulltext_search: 'Full-text search in documents requires presence of %{cmd1} and %{cmd2} commands on the server.' - notice_entries_copied: Copying has succeeded notice_entries_moved: Moving has succeeded label_dmsf_file_revision: DMS Document rev. diff --git a/config/locales/zh.yml b/config/locales/zh.yml index 43b3e4f4..82f65f53 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -469,8 +469,6 @@ zh: label_remove_original_documents_module: Remove the original Documents module - text_fulltext_search: 'Full-text search in documents requires presence of %{cmd1} and %{cmd2} commands on the server.' - notice_entries_copied: Copying has succeeded notice_entries_moved: Moving has succeeded label_dmsf_file_revision: DMS Document rev. diff --git a/init.rb b/init.rb index b167de33..d800df49 100644 --- a/init.rb +++ b/init.rb @@ -27,7 +27,7 @@ Redmine::Plugin.register :redmine_dmsf do author_url 'https://github.com/picman/redmine_dmsf/graphs/contributors' author 'Vít Jonáš / Daniel Munn / Karel Pičman' description 'Document Management System Features' - version '4.2.0' + version '4.2.1' requires_redmine version_or_higher: '6.0.0' diff --git a/test/functional/dmsf_files_controller_test.rb b/test/functional/dmsf_files_controller_test.rb index f29ef98d..8a67c2bb 100644 --- a/test/functional/dmsf_files_controller_test.rb +++ b/test/functional/dmsf_files_controller_test.rb @@ -61,13 +61,20 @@ class DmsfFilesControllerTest < RedmineDmsf::Test::TestCase assert_response :forbidden end - def test_view_file_ok + def test_view_file_standard_url # Permissions OK post '/login', params: { username: 'jsmith', password: 'jsmith' } get "/dmsf/files/#{@file1.id}/view", params: { id: @file1.id } assert_response :success end + def test_view_file_pretty_url + # Permissions OK + post '/login', params: { username: 'jsmith', password: 'jsmith' } + get "/dmsf/files/#{@file1.id}/test.txt", params: { id: @file1.id } + assert_response :success + end + def test_view_file_forbidden # Missing permissions post '/login', params: { username: 'jsmith', password: 'jsmith' }