mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-01-30 19:48:18 +08:00
Move duplicated code to service [SCI-1665]
This commit is contained in:
parent
56f52ebfa7
commit
c8d2ae70fa
8 changed files with 70 additions and 127 deletions
2
Gemfile
2
Gemfile
|
@ -73,6 +73,7 @@ gem 'ruby-graphviz', '~> 1.2' # Graphviz for rails
|
||||||
gem 'tinymce-rails', '~> 4.5.7' # Rich text editor
|
gem 'tinymce-rails', '~> 4.5.7' # Rich text editor
|
||||||
|
|
||||||
gem 'base62' # Used for smart annotations
|
gem 'base62' # Used for smart annotations
|
||||||
|
gem 'newrelic_rpm'
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
gem 'byebug'
|
gem 'byebug'
|
||||||
|
@ -85,7 +86,6 @@ group :development, :test do
|
||||||
end
|
end
|
||||||
|
|
||||||
group :production do
|
group :production do
|
||||||
gem 'newrelic_rpm'
|
|
||||||
gem 'puma'
|
gem 'puma'
|
||||||
gem 'rails_12factor'
|
gem 'rails_12factor'
|
||||||
end
|
end
|
||||||
|
|
|
@ -205,8 +205,7 @@ class RepositoriesController < ApplicationController
|
||||||
return repository_response(t('teams.parse_sheet.errors.empty_file'))
|
return repository_response(t('teams.parse_sheet.errors.empty_file'))
|
||||||
end
|
end
|
||||||
|
|
||||||
@temp_file = parsed_file.generate_temp_file
|
if (@temp_file = parsed_file.generate_temp_file)
|
||||||
if @temp_file
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.json do
|
format.json do
|
||||||
render json: {
|
render json: {
|
||||||
|
|
|
@ -17,30 +17,10 @@ class TeamsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
sheet = Team.open_spreadsheet(params[:file])
|
sheet = SpreadsheetParser.open_spreadsheet(params[:file])
|
||||||
# Get data (it will trigger any errors as well)
|
@header, @columns = SpreadsheetParser.first_two_rows(sheet)
|
||||||
if sheet.is_a?(Roo::CSV)
|
|
||||||
@header = sheet.row(1)
|
|
||||||
@columns = sheet.row(2)
|
|
||||||
elsif sheet.is_a?(Roo::Excelx)
|
|
||||||
i = 1
|
|
||||||
sheet.each_row_streaming do |row|
|
|
||||||
@header = row.map(&:cell_value) if i == 1
|
|
||||||
@columns = row.map(&:cell_value) if i == 2
|
|
||||||
i += 1
|
|
||||||
break if i > 2
|
|
||||||
end
|
|
||||||
else
|
|
||||||
i = 1
|
|
||||||
sheet.rows.each do |row|
|
|
||||||
@header = row.values if i == 1
|
|
||||||
@columns = row.values if i == 2
|
|
||||||
i += 1
|
|
||||||
break if i > 2
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
unless @header && @header.any? && @columns && @columns.any?
|
unless @header.any? && @columns.any?
|
||||||
return parse_sheet_error(t('teams.parse_sheet.errors.empty_file'))
|
return parse_sheet_error(t('teams.parse_sheet.errors.empty_file'))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -93,7 +73,7 @@ class TeamsController < ApplicationController
|
||||||
if @temp_file.session_id == session.id
|
if @temp_file.session_id == session.id
|
||||||
# Check if mappings exists or else we don't have anything to parse
|
# Check if mappings exists or else we don't have anything to parse
|
||||||
if params[:mappings]
|
if params[:mappings]
|
||||||
@sheet = Team.open_spreadsheet(@temp_file.file)
|
@sheet = SpreadsheetParser.open_spreadsheet(@temp_file.file)
|
||||||
|
|
||||||
# Check for duplicated values
|
# Check for duplicated values
|
||||||
h1 = params[:mappings].clone.delete_if { |k, v| v.empty? }
|
h1 = params[:mappings].clone.delete_if { |k, v| v.empty? }
|
||||||
|
|
|
@ -58,17 +58,6 @@ class Repository < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def open_spreadsheet(file)
|
|
||||||
filename = file.original_filename
|
|
||||||
file_path = file.path
|
|
||||||
|
|
||||||
if file.class == Paperclip::Attachment && file.is_stored_on_s3?
|
|
||||||
fa = file.fetch
|
|
||||||
file_path = fa.path
|
|
||||||
end
|
|
||||||
generate_file(filename, file_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
def available_repository_fields
|
def available_repository_fields
|
||||||
fields = {}
|
fields = {}
|
||||||
# First and foremost add record name
|
# First and foremost add record name
|
||||||
|
@ -131,13 +120,7 @@ class Repository < ActiveRecord::Base
|
||||||
unless col_compact.map(&:id).uniq.length == col_compact.length
|
unless col_compact.map(&:id).uniq.length == col_compact.length
|
||||||
return { status: :error, nr_of_added: nr_of_added, total_nr: total_nr }
|
return { status: :error, nr_of_added: nr_of_added, total_nr: total_nr }
|
||||||
end
|
end
|
||||||
rows = if sheet.is_a?(Roo::CSV)
|
rows = SpreadsheetParser.spreadsheet_enumerator(sheet)
|
||||||
sheet
|
|
||||||
elsif sheet.is_a?(Roo::Excelx)
|
|
||||||
sheet.each_row_streaming
|
|
||||||
else
|
|
||||||
sheet.rows
|
|
||||||
end
|
|
||||||
|
|
||||||
# Now we can iterate through record data and save stuff into db
|
# Now we can iterate through record data and save stuff into db
|
||||||
rows.each do |row|
|
rows.each do |row|
|
||||||
|
@ -202,25 +185,4 @@ class Repository < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
{ status: :ok, nr_of_added: nr_of_added, total_nr: total_nr }
|
{ status: :ok, nr_of_added: nr_of_added, total_nr: total_nr }
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def generate_file(filename, file_path)
|
|
||||||
case File.extname(filename)
|
|
||||||
when '.csv'
|
|
||||||
Roo::CSV.new(file_path, extension: :csv)
|
|
||||||
when '.tsv'
|
|
||||||
Roo::CSV.new(file_path, csv_options: { col_sep: "\t" })
|
|
||||||
when '.txt'
|
|
||||||
# This assumption is based purely on biologist's habits
|
|
||||||
Roo::CSV.new(file_path, csv_options: { col_sep: "\t" })
|
|
||||||
when '.xlsx'
|
|
||||||
# Roo Excel parcel was replaced with Creek, but it can be enabled back,
|
|
||||||
# just swap lines below. But only one can be enabled at the same time.
|
|
||||||
# Roo::Excelx.new(file_path)
|
|
||||||
Creek::Book.new(file_path).sheets[0]
|
|
||||||
else
|
|
||||||
raise TypeError
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,33 +26,6 @@ class Team < ActiveRecord::Base
|
||||||
has_many :protocol_keywords, inverse_of: :team, dependent: :destroy
|
has_many :protocol_keywords, inverse_of: :team, dependent: :destroy
|
||||||
has_many :tiny_mce_assets, inverse_of: :team, dependent: :destroy
|
has_many :tiny_mce_assets, inverse_of: :team, dependent: :destroy
|
||||||
has_many :repositories, dependent: :destroy
|
has_many :repositories, dependent: :destroy
|
||||||
# Based on file's extension opens file (used for importing)
|
|
||||||
def self.open_spreadsheet(file)
|
|
||||||
filename = file.original_filename
|
|
||||||
file_path = file.path
|
|
||||||
|
|
||||||
if file.class == Paperclip::Attachment and file.is_stored_on_s3?
|
|
||||||
fa = file.fetch
|
|
||||||
file_path = fa.path
|
|
||||||
end
|
|
||||||
|
|
||||||
case File.extname(filename)
|
|
||||||
when '.csv' then
|
|
||||||
Roo::CSV.new(file_path, extension: :csv)
|
|
||||||
when '.tsv' then
|
|
||||||
Roo::CSV.new(file_path, csv_options: { col_sep: "\t" })
|
|
||||||
when '.txt' then
|
|
||||||
# This assumption is based purely on biologist's habits
|
|
||||||
Roo::CSV.new(file_path, csv_options: { col_sep: "\t" })
|
|
||||||
when '.xlsx' then
|
|
||||||
# Roo Excel parcel was replaced with Creek, but it can be enabled back,
|
|
||||||
# just swap lines below. But only one can be enabled at the same time.
|
|
||||||
# Roo::Excelx.new(file_path)
|
|
||||||
Creek::Book.new(file_path).sheets[0]
|
|
||||||
else
|
|
||||||
raise TypeError
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def search_users(query = nil)
|
def search_users(query = nil)
|
||||||
a_query = "%#{query}%"
|
a_query = "%#{query}%"
|
||||||
|
@ -96,13 +69,7 @@ class Team < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
rows = if sheet.is_a?(Roo::CSV)
|
rows = SpreadsheetParser.spreadsheet_enumerator(sheet)
|
||||||
sheet
|
|
||||||
elsif sheet.is_a?(Roo::Excelx)
|
|
||||||
sheet.each_row_streaming
|
|
||||||
else
|
|
||||||
sheet.rows
|
|
||||||
end
|
|
||||||
|
|
||||||
# Now we can iterate through sample data and save stuff into db
|
# Now we can iterate through sample data and save stuff into db
|
||||||
rows.each do |row|
|
rows.each do |row|
|
||||||
|
|
|
@ -17,9 +17,11 @@ module ImportRepository
|
||||||
private
|
private
|
||||||
|
|
||||||
def run_import_actions
|
def run_import_actions
|
||||||
@repository.import_records(@repository.open_spreadsheet(@temp_file.file),
|
@repository.import_records(
|
||||||
@mappings,
|
SpreadsheetParser.open_spreadsheet(@temp_file.file),
|
||||||
@user)
|
@mappings,
|
||||||
|
@user
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def run_checks
|
def run_checks
|
||||||
|
|
|
@ -5,37 +5,15 @@ module ImportRepository
|
||||||
@file = options.fetch(:file)
|
@file = options.fetch(:file)
|
||||||
@repository = options.fetch(:repository)
|
@repository = options.fetch(:repository)
|
||||||
@session = options.fetch(:session)
|
@session = options.fetch(:session)
|
||||||
@sheet = @repository.open_spreadsheet(@file)
|
@sheet = SpreadsheetParser.open_spreadsheet(@file)
|
||||||
end
|
end
|
||||||
|
|
||||||
def data
|
def data
|
||||||
# Get data (it will trigger any errors as well)
|
header, columns = SpreadsheetParser.first_two_rows(@sheet)
|
||||||
if @sheet.is_a?(Roo::CSV)
|
|
||||||
header = @sheet.row(1)
|
|
||||||
columns = @sheet.row(2)
|
|
||||||
elsif @sheet.is_a?(Roo::Excelx)
|
|
||||||
i = 1
|
|
||||||
@sheet.each_row_streaming do |row|
|
|
||||||
header = row.map(&:cell_value) if i == 1
|
|
||||||
columns = row.map(&:cell_value) if i == 2
|
|
||||||
i += 1
|
|
||||||
break if i > 2
|
|
||||||
end
|
|
||||||
else
|
|
||||||
i = 1
|
|
||||||
@sheet.rows.each do |row|
|
|
||||||
header = row.values if i == 1
|
|
||||||
columns = row.values if i == 2
|
|
||||||
i += 1
|
|
||||||
break if i > 2
|
|
||||||
end
|
|
||||||
end
|
|
||||||
# Fill in fields for dropdown
|
# Fill in fields for dropdown
|
||||||
@repository.available_repository_fields.transform_values! do |name|
|
@repository.available_repository_fields.transform_values! do |name|
|
||||||
truncate(name, length: Constants::NAME_TRUNCATION_LENGTH_DROPDOWN)
|
truncate(name, length: Constants::NAME_TRUNCATION_LENGTH_DROPDOWN)
|
||||||
end
|
end
|
||||||
header ||= []
|
|
||||||
columns ||= []
|
|
||||||
Data.new(header,
|
Data.new(header,
|
||||||
columns,
|
columns,
|
||||||
@repository.available_repository_fields,
|
@repository.available_repository_fields,
|
||||||
|
|
55
app/services/spreadsheet_parser.rb
Normal file
55
app/services/spreadsheet_parser.rb
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
class SpreadsheetParser
|
||||||
|
# Based on file's extension opens file (used for importing)
|
||||||
|
def self.open_spreadsheet(file)
|
||||||
|
filename = file.original_filename
|
||||||
|
file_path = file.path
|
||||||
|
|
||||||
|
if file.class == Paperclip::Attachment && file.is_stored_on_s3?
|
||||||
|
fa = file.fetch
|
||||||
|
file_path = fa.path
|
||||||
|
end
|
||||||
|
|
||||||
|
case File.extname(filename)
|
||||||
|
when '.csv'
|
||||||
|
Roo::CSV.new(file_path, extension: :csv)
|
||||||
|
when '.tsv'
|
||||||
|
Roo::CSV.new(file_path, csv_options: { col_sep: "\t" })
|
||||||
|
when '.txt'
|
||||||
|
# This assumption is based purely on biologist's habits
|
||||||
|
Roo::CSV.new(file_path, csv_options: { col_sep: "\t" })
|
||||||
|
when '.xlsx'
|
||||||
|
# Roo Excel parcel was replaced with Creek, but it can be enabled back,
|
||||||
|
# just swap lines below. But only one can be enabled at the same time.
|
||||||
|
# Roo::Excelx.new(file_path)
|
||||||
|
Creek::Book.new(file_path).sheets[0]
|
||||||
|
else
|
||||||
|
raise TypeError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.spreadsheet_enumerator(sheet)
|
||||||
|
if sheet.is_a?(Roo::CSV)
|
||||||
|
sheet
|
||||||
|
elsif sheet.is_a?(Roo::Excelx)
|
||||||
|
sheet.each_row_streaming
|
||||||
|
else
|
||||||
|
sheet.rows
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.first_two_rows(sheet)
|
||||||
|
rows = spreadsheet_enumerator(sheet)
|
||||||
|
header = []
|
||||||
|
columns = []
|
||||||
|
i = 1
|
||||||
|
rows.each do |row|
|
||||||
|
# Creek XLSX parser returns Hash of the row, Roo - Array
|
||||||
|
row = row.is_a?(Hash) ? row.values.map(&:to_s) : row.map(&:to_s)
|
||||||
|
header = row if i == 1 && row
|
||||||
|
columns = row if i == 2 && row
|
||||||
|
i += 1
|
||||||
|
break if i > 2
|
||||||
|
end
|
||||||
|
return header, columns
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue