Commit caec810c authored by hh1966's avatar hh1966
Browse files

Refactor Export and Import again

parent 19fdf394
......@@ -3,18 +3,24 @@ module Chemotion
resource :imports do
post do
# ensure the tmp/imports directory is there
directory = File.join('tmp', 'import')
# create the import job in order to have the job id
job = ImportCollectionsJob.new
# create a directory `tmp/imports/<job_id>` for this import
directory = File.join('tmp', 'import', job.job_id)
FileUtils.mkdir_p(directory) unless File.directory?(directory)
# store the file in the tmp/imports dir
# store the file in the `tmp/imports/<job_id>` dir
file_path = File.join(directory, params[:file][:filename])
File.open(file_path, 'wb') do |file|
file.write(params[:file][:tempfile].read)
end
# run the asyncronous import job
ImportCollectionsJob.perform_later(file_path, current_user.id)
ImportCollectionsJob.perform_later(directory, params[:file][:filename], current_user.id)
# return the job id to the client
return job.job_id
end
end
end
......
......@@ -27,12 +27,12 @@ class ExportCollectionsJob < ActiveJob::Base
# create a zip buffer
zip = Zip::OutputStream.write_buffer do |zip|
# write the json file into the zip file
zip.put_next_entry File.join(self.job_id, 'data.json')
zip.put_next_entry File.join('data.json')
zip.write export.to_json()
# write all attachemnts into an attachments directory
export.attachments.each do |attachment|
zip.put_next_entry File.join(self.job_id, 'attachments', attachment.filename)
zip.put_next_entry File.join('attachments', attachment.filename)
zip.write attachment.read_file
end
end
......
class ImportCollectionsJob < ActiveJob::Base
queue_as :import_collections
def perform(file_path, current_user_id)
import = Import::ImportCollections.new(file_path, current_user_id)
def perform(directory, file_name, current_user_id)
import = Import::ImportCollections.new(directory, file_name, current_user_id)
import.process
# cleanup
FileUtils.remove_dir(directory) if File.exist?(directory)
end
end
......@@ -6,7 +6,7 @@ module Export
attr_reader :attachments
def initialize
@data = []
@data = {}
@uuids = {}
@attachments = []
end
......@@ -214,17 +214,17 @@ module Export
uuid = uuid(table_name, instance.id)
unless uuid?(table_name, uuid)
# replace id and foreign_keys with uuids
update = {:id => uuid}
update = {}
foreign_keys.each do |foreign_key, foreign_table|
update[foreign_key] = uuid(foreign_table, instance.send(foreign_key))
end
# append updated json to @data
@data << {
:class => class_name,
:table => table_name,
:fields => instance.as_json().merge(update),
}
unless @data.key?(class_name)
@data[class_name] = {}
end
@data[class_name][uuid] = instance.as_json().except('id').merge(update)
end
end
end
......
......@@ -3,16 +3,13 @@ require 'json'
module Import
class ImportCollections
def initialize(file_path, current_user_id)
@file_path = file_path
def initialize(directory, file_name, current_user_id)
@directory = directory
@file_name = file_name
@current_user_id = current_user_id
@directory = File.join(
File.dirname(@file_path),
File.basename(file_path, File.extname(file_path))
)
@data = nil
@uuids = {}
@instances = {}
@attachments = []
end
......@@ -24,22 +21,16 @@ module Import
end
def extract()
# # make sure that no old directory exists
# FileUtils.remove_dir(@directory) if File.directory?(@directory)
destination = File.dirname(@file_path)
Zip::File.open(@file_path) do |zip_file|
file_path = File.join(@directory, @file_name)
Zip::File.open(file_path) do |zip_file|
zip_file.each do |f|
fpath = File.join(destination, f.name)
fpath = File.join(@directory, f.name)
fdir = File.dirname(fpath)
FileUtils.mkdir_p(fdir) unless File.directory?(fdir)
zip_file.extract(f, fpath) unless File.exist?(fpath)
end
end
# delete the zip file
# File.delete(file_path) if File.exist?(file_path)
end
def read
......@@ -52,11 +43,70 @@ module Import
def import
ActiveRecord::Base.transaction do
@data.each do |item|
puts item
import_collections
import_samples
import_containers
end
end
def import_collections
@data['Collection'].each do |uuid, fields|
# create the collection
collection = Collection.new(fields)
collection.save!
# add sample to collection map
instances!(uuid, collection)
end
end
def import_samples
@data['Sample'].each do |uuid, fields|
# look for the collection for this sample
collections_sample = find_association('CollectionsSample', 'sample_id', uuid)
collection = instance('Collection', collections_sample['collection_id'])
# create the sample
sample = Sample.new(fields.except(
"molecule_id",
"sample_svg_file",
"user_id",
"fingerprint_id",
"molarity_value",
"molarity_unit",
"molecule_name_id",
"molfile_version"
))
sample.collections = [collection]
sample.save!
# add sample to instances map
instances!(uuid, sample)
end
end
def instances!(uuid, instance)
class_name = instance.class.name
unless @instances.key?(class_name)
@instances[class_name] = {}
end
@instances[class_name][uuid] = instance
end
def find_association(association_model, id_field, id)
@data[association_model].each do |uuid, fields|
if fields[id_field] == id
return fields
end
end
end
def instance(model, uuid)
if !uuid.nil? and @instances.key?(model) and @instances[model].key?(uuid)
return @instances[model][uuid]
end
end
end
end
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment