114 lines
4.0 KiB
Ruby
114 lines
4.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# Redmine plugin for Document Management System "Features"
|
|
#
|
|
# Vít Jonáš <vit.jonas@gmail.com>, Karel Pičman <karel.picman@kontron.com>
|
|
#
|
|
# This file is part of Redmine DMSF plugin.
|
|
#
|
|
# Redmine DMSF plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General
|
|
# Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
|
|
# later version.
|
|
#
|
|
# Redmine DMSF plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
|
# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
# more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along with Redmine DMSF plugin. If not, see
|
|
# <https://www.gnu.org/licenses/>.
|
|
|
|
require 'zip'
|
|
|
|
module RedmineDmsf
|
|
module DmsfZip
|
|
FILE_PREFIX = 'dmsf_zip_'
|
|
|
|
# ZIP
|
|
class Zip
|
|
attr_reader :dmsf_files
|
|
|
|
delegate :close, to: :@zip_file
|
|
|
|
def initialize
|
|
@temp_file = Tempfile.new([FILE_PREFIX, '.zip'], Rails.root.join('tmp'))
|
|
@zip_file = ::Zip::OutputStream.open(@temp_file)
|
|
@files = []
|
|
@dmsf_files = []
|
|
@folders = []
|
|
end
|
|
|
|
def read
|
|
File.read @temp_file
|
|
end
|
|
|
|
def finish
|
|
@zip_file.close
|
|
@temp_file.path
|
|
end
|
|
|
|
def add_dmsf_file(dmsf_file, member = nil, root_path = nil, path = nil)
|
|
raise DmsfFileNotFoundError unless dmsf_file&.last_revision && File.exist?(dmsf_file.last_revision.disk_file)
|
|
|
|
if path
|
|
string_path = path
|
|
else
|
|
string_path = dmsf_file.dmsf_folder.nil? ? '' : (dmsf_file.dmsf_folder.dmsf_path_str + File::SEPARATOR)
|
|
string_path = string_path[(root_path.length + 1)..string_path.length] if root_path
|
|
end
|
|
string_path += dmsf_file.formatted_name(member)
|
|
|
|
return if @files.include?(string_path)
|
|
|
|
zip_entry = ::Zip::Entry.new(@zip_file, string_path, nil, nil, nil, nil, nil, nil,
|
|
::Zip::DOSTime.at(dmsf_file.last_revision.updated_at))
|
|
@zip_file.put_next_entry zip_entry
|
|
File.open(dmsf_file.last_revision.disk_file, 'rb') do |f|
|
|
while (buffer = f.read(8192))
|
|
@zip_file.write buffer
|
|
end
|
|
end
|
|
@files << string_path
|
|
@dmsf_files << dmsf_file
|
|
end
|
|
|
|
def add_attachment(attachment, path)
|
|
return if @files.include?(path)
|
|
|
|
raise DmsfFileNotFoundError unless File.exist?(attachment.diskfile)
|
|
|
|
zip_entry = ::Zip::Entry.new(@zip_file, path, nil, nil, nil, nil, nil, nil,
|
|
::Zip::DOSTime.at(attachment.created_on))
|
|
@zip_file.put_next_entry zip_entry
|
|
File.open(attachment.diskfile, 'rb') do |f|
|
|
while (buffer = f.read(8192))
|
|
@zip_file.write buffer
|
|
end
|
|
end
|
|
@files << path
|
|
end
|
|
|
|
def add_raw_file(filename, data)
|
|
return if @files.include?(filename)
|
|
|
|
zip_entry = ::Zip::Entry.new(@zip_file, filename, nil, nil, nil, nil, nil, nil, ::Zip::DOSTime.now)
|
|
@zip_file.put_next_entry zip_entry
|
|
@zip_file.write data
|
|
@files << filename
|
|
end
|
|
|
|
def add_dmsf_folder(dmsf_folder, member, root_path = nil)
|
|
string_path = dmsf_folder.dmsf_path_str + File::SEPARATOR
|
|
string_path = string_path[(root_path.length + 1)..string_path.length] if root_path
|
|
zip_entry = ::Zip::Entry.new(@zip_file, string_path, nil, nil, nil, nil, nil, nil,
|
|
::Zip::DOSTime.at(dmsf_folder.modified))
|
|
return if @folders.include?(string_path)
|
|
|
|
@zip_file.put_next_entry zip_entry
|
|
@folders << string_path
|
|
dmsf_folder.dmsf_folders.visible.each { |folder| add_dmsf_folder(folder, member, root_path) }
|
|
dmsf_folder.dmsf_files.visible.each { |file| add_dmsf_file(file, member, root_path) }
|
|
end
|
|
end
|
|
end
|
|
end
|