app/models/resource_import_textresult.rb
require 'axlsx'
class ResourceImportTextresult < ActiveRecord::Base
attr_accessible :resource_import_textfile_id, :body, :error_msg, :extraparams, :failed
default_scope :order => 'resource_import_textresults.id DESC'
scope :file_id, proc{|file_id| where(:resource_import_textfile_id => file_id)}
scope :failed, where(:manifestation_id => nil)
belongs_to :resource_import_textfile
belongs_to :manifestation
belongs_to :item
validates_presence_of :resource_import_textfile_id
def self.generate_resource_import_textresult_list(resource_import_textresults, output_type, current_user, &block)
threshold ||= Setting.background_job.threshold.export rescue nil
# 出力件数の計算
all_size = resource_import_textresults.count
resource_import_textresults.map(&:extraparams).each do |extraparams|
num = eval(extraparams)['row_num'] rescue nil
all_size += num.to_i if num
end
if threshold && threshold > 0 && all_size > threshold
# 指定件数以上のときにはバックグラウンドジョブにする。
job_name = GenerateResourceImportTextresultListJob.generate_job_name
Delayed::Job.enqueue GenerateResourceImportTextresultListJob.new(job_name, resource_import_textresults, output_type, current_user)
output = OpenStruct.new
output.result_type = :delayed
output.job_name = job_name
block.call(output)
return
end
generate_resource_import_textresult_list_internal(resource_import_textresults, output_type, &block)
end
def self.generate_resource_import_textresult_list_internal(resource_import_textresults, output_type, &block)
output = OpenStruct.new
output.result_type = output_type == 'xlsx' ? :path : :data
case output_type
when 'tsv'
output.data = get_resource_import_textresults_tsv_csv(resource_import_textresults)
output.filename = Setting.resource_import_textresults_print_tsv.filename
when 'csv'
output.data = get_resource_import_textresults_tsv_csv(resource_import_textresults)
output.filename = Setting.resource_import_textresults_print_csv.filename
when 'xlsx'
output.path = get_resource_import_textresults_excelx(resource_import_textresults)
output.filename = Setting.resource_import_textresults_print_xlsx.filename
end
block.call(output)
end
def self.get_resource_import_textresults_tsv_csv(resource_import_textresults)
split = SystemConfiguration.get("set_output_format_type") ? "\t" : ","
before_sheet_name = nil
data = String.new
data << "\xEF\xBB\xBF".force_encoding("UTF-8")
resource_import_textresults.sort.each do |result|
next if (eval(result.extraparams)['not_read'] rescue nil)
next if result.body.nil? and result.extraparams.nil?
sheet_name = eval(result.extraparams)['sheet'] rescue nil
wrong_sheet = eval(result.extraparams)['wrong_sheet'] rescue nil
wrong_format = eval(result.extraparams)['wrong_format'] rescue nil
if sheet_name and (sheet_name != before_sheet_name)
data << "\n" + '"sheet_name: ' + sheet_name + "\"\n"
before_sheet_name = sheet_name
end
if wrong_sheet
read_wrong_sheet(result.extraparams, { data: data })
elsif wrong_format
read_wrong_format(eval(result.extraparams)['filename'], { data: data })
else
row = result.body.split("\t")
data << '"' + row.join(%Q[\"#{split}\"]) +"\"\n"
delete_article(result)
end
end
return data
end
def self.get_resource_import_textresults_excelx(resource_import_textresults)
# initialize
out_dir = "#{Rails.root}/private/system/manifestations_list_excelx"
excel_filepath = "#{out_dir}/list#{Time.now.strftime('%s')}#{rand(10)}.xlsx"
FileUtils.mkdir_p(out_dir) unless FileTest.exist?(out_dir)
extraprams_list = resource_import_textresults.sort.map{ |r| r.extraparams }.uniq
logger.info "get_manifestation_list_excelx filepath=#{excel_filepath}"
Axlsx::Package.new do |p|
wb = p.workbook
wb.styles do |s|
default_style = s.add_style :font_name => Setting.manifestation_list_print_excelx.fontname
extraprams_list.each do |extraparams|
next if eval(extraparams)['not_read'] rescue nil
sheet_name = eval(extraparams)['sheet'] rescue nil
'Sheet1' unless sheet_name
wb.add_worksheet(:name => sheet_name) do |sheet|
wrong_sheet = eval(extraparams)['wrong_sheet'] rescue nil
wrong_format = eval(extraparams)['wrong_format'] rescue nil
if wrong_sheet
read_wrong_sheet(extraparams, { sheet: sheet, default_style: default_style })
elsif wrong_format
read_wrong_format(eval(extraparams)['filename'], { sheet: sheet, default_style: default_style })
else
results = resource_import_textresults.where(:extraparams => extraparams)
results.sort.each do |result|
unless result.body.nil?
row = result.body.split(/\t/)
sheet.add_row row, :style => Array.new(columns.size).fill(default_style)
delete_article(result)
end
end
end
end
end
p.serialize(excel_filepath)
end
end
return excel_filepath
end
def self.read_wrong_sheet(extraparams, options = { sheet: nil, default_style: nil, data: nil })
oo = Excelx.new(eval(extraparams)['filename'])
sheet_name = eval(extraparams)['sheet'] rescue nil
oo.default_sheet = sheet_name
begin
oo.first_row.upto(oo.last_row) do |row|
begin
datas = []
oo.first_column.upto(oo.last_column) do |column|
datas << oo.cell(row, column).to_s.strip
end
if options[:sheet]
options[:sheet].add_row datas, :types => :string, :style => Array.new(columns.size).fill(options[:default_style])
else
split = SystemConfiguration.get("set_output_format_type") ? "\t" : ","
options[:data] << '"' + datas.join(%Q[\"#{split}\"]) +"\"\n"
end
rescue
if options[:sheet]
sheet.add_row [], :types => :string, :style => Array.new(columns.size).fill(options[:default_style])
else
options[:data] << '""' + "\n"
end
end
end
rescue
if options[:sheet]
options[:sheet].add_row [], :types => :string, :style => Array.new(columns.size).fill(options[:default_style])
else
options[:data] << "\n"
end
end
end
def self.read_wrong_format(filename, options = { sheet: nil, default_style: nil, data: nil })
split = SystemConfiguration.get('set_output_format_type') ? "\t" : ","
#file = Tsvfile_Adapter.new.open_import_file(filename)
tempfile = Tempfile.new('resource_import_file')
if Setting.uploaded_file.storage == :s3
uploaded_file_path = open(self.resource_import.expiring_url(10)).path
else
uploaded_file_path = filename
end
open(uploaded_file_path) { |f|
f.each{ |line| tempfile.puts(NKF.nkf('-w -Lu', line)) }
}
tempfile.close
file = CSV.open(tempfile.path, :col_sep => split)
file.each_with_index do|row, c|
if options[:sheet]
options[:sheet].add_row row, :style => Array.new(columns.size).fill(options[:default_style])
else
options[:data] << '"' + row.join(%Q[\"#{split}\"]) +"\"\n"
end
end
file.close
end
def self.delete_article(result)
item = Item.find(result.item_id) rescue nil
if item
if item.manifestation.article?
if item.reserve
item.reserve.revert_request rescue nil
end
item.destroy
result.item_id = nil
end
end
manifestation = Manifestation.find(result.manifestation_id) rescue nil
if manifestation
if manifestation.items.size == 0
manifestation.destroy
result.manifestation_id = nil
end
end
result.save!
rescue => e
logger.info "failed to destroy item: #{result.item_id}"
logger.info e.message
end
class GenerateResourceImportTextresultListJob
include Rails.application.routes.url_helpers
include BackgroundJobUtils
def initialize(name, textresults, output_type, user)
@name = name
@textresults = textresults
@output_type = output_type
@user = user
end
attr_accessor :name, :textresults, :output_type, :user
def perform
user_file = UserFile.new(user)
ResourceImportTextresult.generate_resource_import_textresult_list_internal(textresults, output_type) do |output|
io, info = user_file.create(:resource_import_results, output.filename)
if output.result_type == :path
open(output.path) { |io2| FileUtils.copy_stream(io2, io) }
else
io.print output.data
end
io.close
url = my_account_url(:filename => info[:filename], :category => info[:category], :random => info[:random])
message(
user,
I18n.t('manifestation.output_job_success_subject', :job_name => name),
I18n.t('manifestation.output_job_success_body', :job_name => name, :url => url))
end
rescue => exception
message(
user,
I18n.t('manifestation.output_job_error_subject', :job_name => name),
I18n.t('manifestation.output_job_error_body', :job_name => name, :message => exception.message+exception.backtrace))
end
end
end
# == Schema Information
#
# Table name: resource_import_results
#
# id :integer not null, primary key
# resource_import_file_id :integer
# manifestation_id :integer
# item_id :integer
# body :text
# created_at :datetime
# updated_at :datetime
#