2026-01-05 15:54:29 +09:00

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