diff --git a/CHANGELOG.md b/CHANGELOG.md index cfc83f78..a961eb97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ Changelog for Redmine DMSF ========================== +3.0.1 *????-??-??* +------------------- + + Office documents displayed inline (preview) + 3.0.0 *2022-04-28* ------------------- diff --git a/Dockerfile b/Dockerfile index ec5ac1ae..a1d2fb7e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,6 +20,6 @@ FROM debian:latest RUN apt-get update -RUN apt-get -qq install mariadb-server postgresql sqlite3 libsqlite3-dev ruby ruby-dev build-essential libmariadb-dev libpq-dev subversion git litmus +RUN apt-get -qq install mariadb-server postgresql sqlite3 libsqlite3-dev ruby ruby-dev build-essential libmariadb-dev libpq-dev subversion git litmus libreoffice COPY . /app WORKDIR /app diff --git a/README.md b/README.md index 5c2625ee..d8752b5c 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,11 @@ Features * Wiki macros for quick content linking * Full read/write webdav functionality * Optional document content full-text search - * Documents and folders symbolic links + * Documents and folders' symbolic links * Trash bin * Documents attachable to issues + * Office documents are displayed inline + * Editing of office documents * Compatible with Redmine 5.0.x Dependencies @@ -112,6 +114,16 @@ sudo yum install xapian-core xapian-bindings-ruby libxapian-dev poppler-utils an libwps-tools gzip unrtf catdvi djview djview3 uuid uuid-dev xz libemail-outlook-message-perl ``` +### Inline displaying of office documents (optional) + +If LibreOffice binary `libreoffice` is present in the server, office documents (.odt, .ods,...) are displayed inline. + +`libreoffice` package is available in the most of Linux distributions, e.g. on Debain based systems: + +``` +sudo apt install libreoffice +``` + Usage ----- diff --git a/after_init.rb b/after_init.rb index 6d73d194..0380ff06 100644 --- a/after_init.rb +++ b/after_init.rb @@ -21,12 +21,9 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +require 'redmine' require 'zip' - -# All files in lib sub-folder are already loaded by Zeitwerk -if RedmineApp::Application.config.autoloader != :zeitwerk - require File.dirname(__FILE__) + '/lib/redmine_dmsf' -end +require File.dirname(__FILE__) + '/lib/redmine_dmsf' def dmsf_init # Administration menu extension diff --git a/app/controllers/dmsf_files_controller.rb b/app/controllers/dmsf_files_controller.rb index 95c87b0c..b2ea82fd 100644 --- a/app/controllers/dmsf_files_controller.rb +++ b/app/controllers/dmsf_files_controller.rb @@ -69,10 +69,15 @@ class DmsfFilesController < ApplicationController member = Member.find_by(user_id: User.current.id, project_id: @file.project.id) # IE has got a tendency to cache files expires_in 0.year, 'must-revalidate' => true - send_file @revision.disk_file, - filename: filename_for_content_disposition(@revision.formatted_name(member)), - type: @revision.detect_content_type, - disposition: params[:disposition].present? ? params[:disposition] : @revision.dmsf_file.disposition + pdf_preview = @file.pdf_preview + filename = filename_for_content_disposition(@revision.formatted_name(member)) + if pdf_preview.present? + basename = File.basename(filename, '.*') + send_file pdf_preview, filename: "#{basename}.pdf", type: 'application/pdf', disposition: 'inline' + else + send_file @revision.disk_file, filename: filename, type: @revision.detect_content_type, + disposition: params[:disposition].present? ? params[:disposition] : @revision.dmsf_file.disposition + end rescue RedmineDmsf::Errors::DmsfAccessError => e Rails.logger.error e.message render_403 diff --git a/app/models/dmsf_file.rb b/app/models/dmsf_file.rb index 537e8466..7c1e63c9 100644 --- a/app/models/dmsf_file.rb +++ b/app/models/dmsf_file.rb @@ -78,6 +78,9 @@ class DmsfFile < ActiveRecord::Base project_key: 'project_id', date_column: "#{table_name}.updated_at" + cattr_accessor :previews_storage_path + @@previews_storage_path = File.join(Rails.root, 'tmp', 'dmsf_previews') + before_create :default_values def default_values @@ -465,23 +468,34 @@ class DmsfFile < ActiveRecord::Base end def text? - last_revision && Redmine::MimeType.is_type?('text', last_revision.disk_filename) + Redmine::MimeType.is_type?('text', last_revision&.disk_filename) end def image? - last_revision && Redmine::MimeType.is_type?('image', last_revision.disk_filename) + Redmine::MimeType.is_type?('image', last_revision&.disk_filename) end def pdf? - last_revision && (Redmine::MimeType.of(last_revision.disk_filename) == 'application/pdf') + Redmine::MimeType.of(last_revision&.disk_filename) == 'application/pdf' end def video? - last_revision && Redmine::MimeType.is_type?('video', last_revision.disk_filename) + Redmine::MimeType.is_type?('video', last_revision&.disk_filename) end def html? - last_revision && (Redmine::MimeType.of(last_revision.disk_filename) == 'text/html') + Redmine::MimeType.of(last_revision&.disk_filename) == 'text/html' + end + + def office_doc? + case File.extname(last_revision&.disk_filename) + when '.odt', '.ods', '.odp', '.odg', # LibreOffice + '.doc', '.docx', '.docm', '.xls', '.xlsx', '.xlsm', '.ppt', '.pptx', '.pptm', # MS Office + '.rtf' # Universal + true + else + false + end end def disposition @@ -492,7 +506,30 @@ class DmsfFile < ActiveRecord::Base image? && Redmine::Thumbnail.convert_available? end - def preview(limit) + def previewable? + office_doc? && RedmineDmsf::Preview.office_available? + end + + # Deletes all previews + def self.clear_previews + Dir.glob(File.join(DmsfFile.previews_storage_path, '*.pdf')).each do |file| + File.delete file + end + end + + def pdf_preview + return '' unless previewable? + target = File.join(DmsfFile.previews_storage_path, "#{id}_#{last_revision.digest}.pdf") + + begin + RedmineDmsf::Preview.generate last_revision.disk_file.to_s, target + rescue => e + Rails.logger.error "An error occured while generating preview for #{last_revision.disk_file} to #{target}\nException was: #{e.message}" + nil + end + end + + def text_preview(limit) result = +'No preview available' if text? begin diff --git a/app/views/settings/_dmsf_settings.html.erb b/app/views/settings/_dmsf_settings.html.erb index 50fdc3d8..0ea98586 100644 --- a/app/views/settings/_dmsf_settings.html.erb +++ b/app/views/settings/_dmsf_settings.html.erb @@ -106,10 +106,18 @@ <% rescue %>
<%= l(:error_tmpfile_can_not_be_created) %>
<% ensure %> - <% FileUtils.rm_f(testfilename) %> + <% FileUtils.rm_f testfilename %> <% end %> <% end %> ++ <%= content_tag :label, l(:label_dmsf_office_bin) %> + <%= text_field_tag 'settings[office_bin]', @settings['office_bin'], size: 10 %> + + <%= l(:note_dmsf_office_bin) %> <%= l(:label_default) %>: 'libreoffice' + +
+
<%= content_tag :label, l(:label_physical_file_delete) %>
<%= check_box_tag 'settings[dmsf_really_delete_files]', true, @settings['dmsf_really_delete_files'] %>
diff --git a/config/locales/cs.yml b/config/locales/cs.yml
index f22d0a8b..be7f74d1 100644
--- a/config/locales/cs.yml
+++ b/config/locales/cs.yml
@@ -445,6 +445,9 @@ cs:
label_dmsf_max_notification_receivers_info: Maximální počet zobrazených příjemců notifikace
note_dmsf_max_notification_receivers_info: Omezí maximální počet zobrazených příjemců e-mailové notifikace
+ label_dmsf_office_bin: Binárka Libreofficu
+ note_dmsf_office_bin: Binárka ke konverzi kancelářských dokumentů do formátu PDF k poskytnutí jejich náhledu. Jestliže
+ náhledy nechcete, vložte se například 'xxx'.
easy_pages:
modules:
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 59f7e71a..be89b442 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -441,6 +441,9 @@ de:
label_dmsf_max_notification_receivers_info: Maximum notification receivers info
note_dmsf_max_notification_receivers_info: Limits maximum number of displayed email notification receivers.
+ label_dmsf_office_bin: Libreoffice binary
+ note_dmsf_office_bin: A binary to convert office documents to PDF format and provide their preview. If you want
+ to prevent previews of office documents, put here 'xxx' for example.
easy_pages:
modules:
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 70da0fee..5920c927 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -445,6 +445,9 @@ en:
label_dmsf_max_notification_receivers_info: Maximum notification receivers info
note_dmsf_max_notification_receivers_info: Limits maximum number of displayed email notification receivers.
+ label_dmsf_office_bin: Libreoffice binary
+ note_dmsf_office_bin: A binary to convert office documents to PDF format and provide their preview. If you want
+ to prevent previews of office documents, put here 'xxx' for example.
easy_pages:
modules:
diff --git a/config/locales/es.yml b/config/locales/es.yml
index e47ad039..7a3f4382 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -445,6 +445,9 @@ es:
label_dmsf_max_notification_receivers_info: Maximum notification receivers info
note_dmsf_max_notification_receivers_info: Limits maximum number of displayed email notification receivers.
+ label_dmsf_office_bin: Libreoffice binary
+ note_dmsf_office_bin: A binary to convert office documents to PDF format and provide their preview. If you want
+ to prevent previews of office documents, put here 'xxx' for example.
easy_pages:
modules:
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 384c6945..a5ddb67b 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -445,6 +445,9 @@ fr:
label_dmsf_max_notification_receivers_info: Maximum notification receivers info
note_dmsf_max_notification_receivers_info: Limits maximum number of displayed email notification receivers.
+ label_dmsf_office_bin: Libreoffice binary
+ note_dmsf_office_bin: A binary to convert office documents to PDF format and provide their preview. If you want
+ to prevent previews of office documents, put here 'xxx' for example.
easy_pages:
modules:
diff --git a/config/locales/hu.yml b/config/locales/hu.yml
index 0e719d74..7f6947f6 100644
--- a/config/locales/hu.yml
+++ b/config/locales/hu.yml
@@ -444,6 +444,9 @@ hu:
label_dmsf_max_notification_receivers_info: Maximum notification receivers info
note_dmsf_max_notification_receivers_info: Limits maximum number of displayed email notification receivers.
+ label_dmsf_office_bin: Libreoffice binary
+ note_dmsf_office_bin: A binary to convert office documents to PDF format and provide their preview. If you want
+ to prevent previews of office documents, put here 'xxx' for example.
easy_pages:
modules:
diff --git a/config/locales/it.yml b/config/locales/it.yml
index aa1ecf5b..0b38b547 100644
--- a/config/locales/it.yml
+++ b/config/locales/it.yml
@@ -445,6 +445,9 @@ it: # Italian strings thx 2 Matteo Arceci!
label_dmsf_max_notification_receivers_info: Maximum notification receivers info
note_dmsf_max_notification_receivers_info: Limits maximum number of displayed email notification receivers.
+ label_dmsf_office_bin: Libreoffice binary
+ note_dmsf_office_bin: A binary to convert office documents to PDF format and provide their preview. If you want
+ to prevent previews of office documents, put here 'xxx' for example.
easy_pages:
modules:
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index fdffef55..4bc00366 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -446,6 +446,9 @@ ja:
label_dmsf_max_notification_receivers_info: Maximum notification receivers info
note_dmsf_max_notification_receivers_info: Limits maximum number of displayed email notification receivers.
+ label_dmsf_office_bin: Libreoffice binary
+ note_dmsf_office_bin: A binary to convert office documents to PDF format and provide their preview. If you want
+ to prevent previews of office documents, put here 'xxx' for example.
easy_pages:
modules:
diff --git a/config/locales/ko.yml b/config/locales/ko.yml
index c1f6b718..52a6c84f 100644
--- a/config/locales/ko.yml
+++ b/config/locales/ko.yml
@@ -445,6 +445,9 @@ ko:
label_dmsf_max_notification_receivers_info: Maximum notification receivers info
note_dmsf_max_notification_receivers_info: Limits maximum number of displayed email notification receivers.
+ label_dmsf_office_bin: Libreoffice binary
+ note_dmsf_office_bin: A binary to convert office documents to PDF format and provide their preview. If you want
+ to prevent previews of office documents, put here 'xxx' for example.
easy_pages:
modules:
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index 6b00cbe1..50b91710 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -445,6 +445,9 @@ nl:
label_dmsf_max_notification_receivers_info: Maximum notification receivers info
note_dmsf_max_notification_receivers_info: Limits maximum number of displayed email notification receivers.
+ label_dmsf_office_bin: Libreoffice binary
+ note_dmsf_office_bin: A binary to convert office documents to PDF format and provide their preview. If you want
+ to prevent previews of office documents, put here 'xxx' for example.
easy_pages:
modules:
diff --git a/config/locales/pl.yml b/config/locales/pl.yml
index d5a7096d..e88ee576 100644
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -445,6 +445,9 @@ pl:
label_dmsf_max_notification_receivers_info: Maximum notification receivers info
note_dmsf_max_notification_receivers_info: Limits maximum number of displayed email notification receivers.
+ label_dmsf_office_bin: Libreoffice binary
+ note_dmsf_office_bin: A binary to convert office documents to PDF format and provide their preview. If you want
+ to prevent previews of office documents, put here 'xxx' for example.
easy_pages:
modules:
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index 2a2b0012..9cd6088a 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -445,6 +445,9 @@ pt-BR:
label_dmsf_max_notification_receivers_info: Maximum notification receivers info
note_dmsf_max_notification_receivers_info: Limits maximum number of displayed email notification receivers.
+ label_dmsf_office_bin: Libreoffice binary
+ note_dmsf_office_bin: A binary to convert office documents to PDF format and provide their preview. If you want
+ to prevent previews of office documents, put here 'xxx' for example.
easy_pages:
modules:
diff --git a/config/locales/sl.yml b/config/locales/sl.yml
index 79b79be8..97ba539a 100644
--- a/config/locales/sl.yml
+++ b/config/locales/sl.yml
@@ -445,6 +445,9 @@ sl:
label_dmsf_max_notification_receivers_info: Maximum notification receivers info
note_dmsf_max_notification_receivers_info: Limits maximum number of displayed email notification receivers.
+ label_dmsf_office_bin: Libreoffice binary
+ note_dmsf_office_bin: A binary to convert office documents to PDF format and provide their preview. If you want
+ to prevent previews of office documents, put here 'xxx' for example.
easy_pages:
modules:
diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml
index 2563e483..5f242f2a 100644
--- a/config/locales/zh-TW.yml
+++ b/config/locales/zh-TW.yml
@@ -444,6 +444,9 @@ zh-TW:
label_dmsf_max_notification_receivers_info: Maximum notification receivers info
note_dmsf_max_notification_receivers_info: Limits maximum number of displayed email notification receivers.
+ label_dmsf_office_bin: Libreoffice binary
+ note_dmsf_office_bin: A binary to convert office documents to PDF format and provide their preview. If you want
+ to prevent previews of office documents, put here 'xxx' for example.
easy_pages:
modules:
diff --git a/config/locales/zh.yml b/config/locales/zh.yml
index e8b7189c..3f6363cf 100644
--- a/config/locales/zh.yml
+++ b/config/locales/zh.yml
@@ -445,6 +445,9 @@ zh:
label_dmsf_max_notification_receivers_info: Maximum notification receivers info
note_dmsf_max_notification_receivers_info: Limits maximum number of displayed email notification receivers.
+ label_dmsf_office_bin: Libreoffice binary
+ note_dmsf_office_bin: A binary to convert office documents to PDF format and provide their preview. If you want
+ to prevent previews of office documents, put here 'xxx' for example.
easy_pages:
modules:
diff --git a/init.rb b/init.rb
index 4171bb00..e2356d7d 100644
--- a/init.rb
+++ b/init.rb
@@ -33,7 +33,7 @@ Redmine::Plugin.register :redmine_dmsf do
end
author 'Vít Jonáš / Daniel Munn / Karel Pičman'
description 'Document Management System Features'
- version '3.0.0'
+ version '3.0.1 devel'
requires_redmine version_or_higher: '4.2.0'
@@ -62,7 +62,8 @@ Redmine::Plugin.register :redmine_dmsf do
'dmsf_webdav_ignore_1b_file_for_authentication' => '1',
'dmsf_projects_as_subfolders' => nil,
'only_approval_zero_minor_version' => '0',
- 'dmsf_max_notification_receivers_info' => 10
+ 'dmsf_max_notification_receivers_info' => 10,
+ 'office_bin' => 'libreoffice'
}
end
diff --git a/lib/redmine_dmsf/macros.rb b/lib/redmine_dmsf/macros.rb
index 1a1fa607..fb5d5cb1 100644
--- a/lib/redmine_dmsf/macros.rb
+++ b/lib/redmine_dmsf/macros.rb
@@ -144,7 +144,7 @@ module RedmineDmsf
raise ArgumentError if args.length < 2 # Requires file id and lines number
file = DmsfFile.visible.find args[0]
if User.current&.allowed_to?(:view_dmsf_files, file.project)
- file.preview(args[1]).gsub("\n", ' #{@file1.preview(1)} #{@file1.text_preview(1)} #{@file1.preview(1)} #{@file1.text_preview(1)} #{@file1.preview(1)} #{@file1.text_preview(1)}
').html_safe
+ file.text_preview(args[1]).gsub("\n", '
').html_safe
else
raise l(:notice_not_authorized)
end
diff --git a/lib/redmine_dmsf/preview.rb b/lib/redmine_dmsf/preview.rb
new file mode 100644
index 00000000..5969921f
--- /dev/null
+++ b/lib/redmine_dmsf/preview.rb
@@ -0,0 +1,65 @@
+# encoding: utf-8
+# frozen_string_literal: true
+#
+# Redmine plugin for Document Management System "Features"
+#
+# Copyright © 2011 Vít Jonáš