2023-06-12 16:29:17 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
class RepositoriesExportJob < ApplicationJob
|
|
|
|
include StringUtility
|
2023-09-06 18:51:34 +08:00
|
|
|
include FailedDeliveryNotifiableJob
|
2023-06-12 16:29:17 +08:00
|
|
|
|
2024-03-07 22:48:01 +08:00
|
|
|
def perform(file_type, repository_ids, user_id:, team_id:)
|
2023-08-11 21:31:29 +08:00
|
|
|
@user = User.find(user_id)
|
2023-09-06 18:51:34 +08:00
|
|
|
@team = Team.find(team_id)
|
2023-06-12 16:29:17 +08:00
|
|
|
@repositories = Repository.viewable_by_user(@user, @team).where(id: repository_ids).order(:id)
|
2024-03-07 22:48:01 +08:00
|
|
|
@file_type = file_type.to_sym
|
2023-06-12 16:29:17 +08:00
|
|
|
zip_input_dir = FileUtils.mkdir_p(Rails.root.join("tmp/temp_zip_#{Time.now.to_i}")).first
|
|
|
|
zip_dir = FileUtils.mkdir_p(Rails.root.join('tmp/zip-ready')).first
|
|
|
|
|
|
|
|
zip_name = "inventories_export_#{Time.now.utc.strftime('%F_%H-%M-%S_UTC')}.zip"
|
|
|
|
full_zip_name = File.join(zip_dir, zip_name)
|
|
|
|
|
|
|
|
fill_content(zip_input_dir)
|
|
|
|
ZipExport.transaction do
|
|
|
|
@zip_export = ZipExport.create!(user: @user)
|
|
|
|
@zip_export.zip!(zip_input_dir, full_zip_name)
|
|
|
|
@zip_export.zip_file.attach(io: File.open(full_zip_name), filename: zip_name)
|
|
|
|
generate_notification
|
|
|
|
end
|
|
|
|
ensure
|
|
|
|
FileUtils.rm_rf([zip_input_dir, full_zip_name], secure: true)
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def fill_content(tmp_dir)
|
|
|
|
# Create team dir
|
|
|
|
team_path = "#{tmp_dir}/#{to_filesystem_name(@team.name)}"
|
|
|
|
FileUtils.mkdir_p(team_path)
|
|
|
|
@repositories.each_with_index do |repository, idx|
|
2024-03-07 22:48:01 +08:00
|
|
|
save_repository_as_file(team_path, repository, idx)
|
2023-06-12 16:29:17 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-03-07 22:48:01 +08:00
|
|
|
def save_repository_as_file(path, repository, idx)
|
2023-06-12 16:29:17 +08:00
|
|
|
repository_name = "#{to_filesystem_name(repository.name)} (#{idx})"
|
|
|
|
|
|
|
|
# Attachments dir
|
|
|
|
relative_attachments_path = "#{repository_name} attachments"
|
|
|
|
attachments_path = "#{path}/#{relative_attachments_path}"
|
|
|
|
FileUtils.mkdir_p(attachments_path)
|
|
|
|
|
2024-03-07 22:48:01 +08:00
|
|
|
# File creation
|
2024-06-07 15:55:11 +08:00
|
|
|
repository_items_file_name = FileUtils.touch("#{path}/#{repository_name}.#{@file_type}").first
|
2023-06-12 16:29:17 +08:00
|
|
|
|
|
|
|
# Define headers and columns IDs
|
2024-05-22 23:23:39 +08:00
|
|
|
col_ids = [-3, -4, -5, -6, -7, -8, -9, -10]
|
|
|
|
col_ids << -11 if Repository.repository_row_connections_enabled?
|
2024-01-16 20:07:11 +08:00
|
|
|
col_ids += repository.repository_columns.map(&:id)
|
2023-06-12 16:29:17 +08:00
|
|
|
|
|
|
|
# Define callback function for file name
|
|
|
|
assets = {}
|
|
|
|
asset_counter = 0
|
|
|
|
handle_name_func = lambda do |asset|
|
|
|
|
file_name = append_file_suffix(asset.file_name, "_#{asset_counter}").to_s
|
|
|
|
|
|
|
|
# Save pair for downloading it later
|
|
|
|
assets[asset] = "#{attachments_path}/#{file_name}"
|
|
|
|
|
|
|
|
asset_counter += 1
|
|
|
|
relative_path = "#{relative_attachments_path}/#{file_name}"
|
|
|
|
return "=HYPERLINK(\"#{relative_path}\", \"#{relative_path}\")"
|
|
|
|
end
|
|
|
|
|
2024-03-07 22:48:01 +08:00
|
|
|
# Generate CSV / XLSX
|
|
|
|
service = RepositoryExportService
|
2024-08-06 19:26:14 +08:00
|
|
|
.new(@file_type, repository.repository_rows, col_ids, repository, handle_name_func)
|
2024-03-07 22:48:01 +08:00
|
|
|
exported_data = service.export!
|
|
|
|
|
2024-06-07 15:55:11 +08:00
|
|
|
File.binwrite(repository_items_file_name, exported_data)
|
2023-06-12 16:29:17 +08:00
|
|
|
|
|
|
|
# Save all attachments (it doesn't work directly in callback function
|
|
|
|
assets.each do |asset, asset_path|
|
|
|
|
asset.file.open do |file|
|
|
|
|
FileUtils.mv(file.path, asset_path)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def append_file_suffix(file_name, suffix)
|
|
|
|
ext = File.extname(file_name)
|
2023-08-08 16:56:23 +08:00
|
|
|
file_name = to_filesystem_name(file_name)
|
2023-06-12 16:29:17 +08:00
|
|
|
File.basename(file_name, ext) + suffix + ext
|
|
|
|
end
|
|
|
|
|
|
|
|
def generate_notification
|
2023-12-08 20:57:43 +08:00
|
|
|
DeliveryNotification.send_notifications(
|
|
|
|
{
|
|
|
|
title: I18n.t('zip_export.notification_title'),
|
|
|
|
message: "<a data-id='#{@zip_export.id}' " \
|
|
|
|
"data-turbolinks='false' " \
|
|
|
|
"href='#{Rails.application
|
|
|
|
.routes
|
|
|
|
.url_helpers
|
|
|
|
.zip_exports_download_export_all_path(@zip_export)}'>" \
|
|
|
|
"#{@zip_export.zip_file_name}</a>",
|
|
|
|
user: @user
|
|
|
|
}
|
|
|
|
)
|
2023-06-12 16:29:17 +08:00
|
|
|
end
|
2023-09-06 18:51:34 +08:00
|
|
|
|
|
|
|
# Overrides method from FailedDeliveryNotifiableJob concern
|
|
|
|
def failed_notification_title
|
2023-10-03 19:27:40 +08:00
|
|
|
I18n.t('activejob.failure_notifiable_job.item_notification_title',
|
|
|
|
item: I18n.t('activejob.failure_notifiable_job.items.repository'))
|
2023-09-06 18:51:34 +08:00
|
|
|
end
|
2023-06-12 16:29:17 +08:00
|
|
|
end
|