diff --git a/Gemfile b/Gemfile index 4946767cd..b523846fa 100644 --- a/Gemfile +++ b/Gemfile @@ -12,7 +12,7 @@ gem 'bootstrap_form', '~> 2.7.0' gem 'devise', '~> 4.6.2' gem 'devise_invitable' gem 'figaro' -gem 'pg', '~> 0.18' +gem 'pg', '~> 1.1' gem 'pg_search' # PostgreSQL full text search gem 'rails', '~> 5.2.3' gem 'recaptcha', require: 'recaptcha/rails' diff --git a/Gemfile.lock b/Gemfile.lock index e2e5e6687..c2297e6d7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -364,7 +364,9 @@ GEM parallel (1.17.0) parser (2.6.3.0) ast (~> 2.4.0) - pg (0.21.0) + pg (1.1.4) + activerecord (>= 4.2) + activesupport (>= 4.2) pg_search (2.2.0) activerecord (>= 4.2) activesupport (>= 4.2) @@ -627,7 +629,7 @@ DEPENDENCIES omniauth-linkedin-oauth2 overcommit paperclip (~> 6.1) - pg (~> 0.18) + pg (~> 1.1) pg_search phantomjs poltergeist diff --git a/app/assets/javascripts/repositories/forms/repository_item_edit.js b/app/assets/javascripts/repositories/forms/repository_item_edit.js index 0a36e2d9e..b6b1d5a0d 100644 --- a/app/assets/javascripts/repositories/forms/repository_item_edit.js +++ b/app/assets/javascripts/repositories/forms/repository_item_edit.js @@ -71,7 +71,7 @@ $.each(itemData.repository_row.repository_cells, function(i, cell) { var tableCellId = 'colId-' + cell.cell_column_id; if(cell.type === 'RepositoryAssetValue') { - formBindingsData[tableCellId] = new File([""], cell.value.file_file_name); + formBindingsData[tableCellId] = new File([""], cell.value.file_name); } else { formBindingsData[tableCellId] = cell.value; } @@ -193,7 +193,7 @@ * @returns (String) */ function changeToInputFileField(object, name, value, id) { - var fileName = (value.file_file_name) ? value.file_file_name : I18n.t('general.file.no_file_chosen'); + var fileName = (value.file_name) ? value.file_name : I18n.t('general.file.no_file_chosen'); var buttonLabel = I18n.t('general.file.choose'); var html = "
" + "
" + buttonLabel + "

" + truncateLongString(fileName, 20) + "

"; - if(value.file_file_name) { + if(value.file_name) { html += "
e Rails.logger.fatal( - "Asset #{asset.id}: Error extracting contents from asset "\ - "file #{asset.file.path}: #{e.message}" + "Asset #{id}: Error extracting contents from asset "\ + "file #{file.blob.key}: #{e.message}" ) - ensure - File.delete file_path if fa end end # If team is provided, its space_taken # is updated as well def update_estimated_size(team = nil) - return if file_file_size.blank? || in_template + return if file_size.blank? || in_template - es = file_file_size + es = file_size if asset_text_datum.present? && asset_text_datum.persisted? asset_text_datum.reload es += get_octet_length_record(asset_text_datum, :data) @@ -351,29 +343,18 @@ class Asset < ApplicationRecord end end - # Preserving attachments (on client-side) between failed validations - # (only usable for small/few files!). - # Needs to be called before save method and view needs to have - # :file_content and :file_info hidden field. - # If file is an image, it can be viewed on front-end - # using @preview_cached with image_tag tag. - def preserve(file_data) - if file_data[:file_content].present? - restore_cached(file_data[:file_content], file_data[:file_info]) - end - cache - end - def can_perform_action(action) if ENV['WOPI_ENABLED'] == 'true' - file_ext = file_file_name.split('.').last + file_ext = file_name.split('.').last if file_ext == 'wopitest' && (!ENV['WOPI_TEST_ENABLED'] || ENV['WOPI_TEST_ENABLED'] == 'false') return false end + action = get_action(file_ext, action) return false if action.nil? + true else false @@ -381,7 +362,7 @@ class Asset < ApplicationRecord end def get_action_url(user, action, with_tokens = true) - file_ext = file_file_name.split('.').last + file_ext = file_name.split('.').last action = get_action(file_ext, action) if !action.nil? action_url = action.urlsrc @@ -404,7 +385,7 @@ class Asset < ApplicationRecord ) action_url += "WOPISrc=#{rest_url}" if with_tokens - token = user.get_wopi_token + token = user.get_wopi_token action_url + "&access_token=#{token.token}"\ "&access_token_ttl=#{(token.ttl * 1000)}" else @@ -416,7 +397,7 @@ class Asset < ApplicationRecord end def favicon_url(action) - file_ext = file_file_name.split('.').last + file_ext = file_name.split('.').last action = get_action(file_ext, action) action.wopi_app.icon if action.try(:wopi_app) end @@ -458,8 +439,8 @@ class Asset < ApplicationRecord def update_contents(new_file) new_file.class.class_eval { attr_accessor :original_filename } - new_file.original_filename = file_file_name - self.file = new_file + new_file.original_filename = file_name + file.attach(io: new_file, filename: original_filename) self.version = version.nil? ? 1 : version + 1 save end @@ -468,18 +449,12 @@ class Asset < ApplicationRecord !locked? && %r{^image/#{Regexp.union(Constants::WHITELISTED_IMAGE_TYPES_EDITABLE)}} =~ file.content_type end - protected - - # Checks if attachments is an image (in post processing imagemagick will - # generate styles) - def allow_styles_on_images - if !(file.content_type =~ %r{^(image|(x-)?application)/(x-png|pjpeg|jpeg|jpg|png|gif)$}) - return false - end - end - private + def tempdir + Rails.root.join('tmp') + end + def previewable_document? previewable = Constants::PREVIEWABLE_FILE_TYPES.include?(file.content_type) @@ -503,29 +478,6 @@ class Asset < ApplicationRecord file.blob&.content_type =~ %r{^image/#{Regexp.union(Constants::WHITELISTED_IMAGE_TYPES)}} end - def filter_paperclip_errors - if errors.size > 1 - temp_errors = errors[:file] - errors.clear - errors.add(:file, temp_errors) - end - end - - def file_changed? - previous_changes.present? and - ( - ( - previous_changes.key? "file_file_name" and - previous_changes["file_file_name"].first != - previous_changes["file_file_name"].last - ) or ( - previous_changes.key? "file_file_size" and - previous_changes["file_file_size"].first != - previous_changes["file_file_size"].last - ) - ) - end - def step_or_result_or_repository_asset_value # We must allow both step and result to be blank because of GUI # (even though it's not really a "valid" asset) @@ -558,30 +510,4 @@ class Asset < ApplicationRecord ) end end - - def cache - fetched_file = file.fetch - file_content = fetched_file.read - @file_content = encrypt(file_content) - @file_info = %Q[{"content_type" : "#{file.content_type}", "original_filename" : "#{file.original_filename}"}] - @file_info = encrypt(@file_info) - if !(file.content_type =~ /^image/).nil? - @preview_cached = "data:image/png;base64," + Base64.encode64(file_content) - end - end - - def restore_cached(file_content, file_info) - decoded_data = decrypt(file_content) - decoded_data_info = decrypt(file_info) - decoded_data_info = JSON.parse decoded_data_info - - data = StringIO.new(decoded_data) - data.class_eval do - attr_accessor :content_type, :original_filename - end - data.content_type = decoded_data_info['content_type'] - data.original_filename = File.basename(decoded_data_info['original_filename']) - - self.file = data - end end diff --git a/app/models/concerns/tiny_mce_images.rb b/app/models/concerns/tiny_mce_images.rb index 84f5ab59b..b5cc990f2 100644 --- a/app/models/concerns/tiny_mce_images.rb +++ b/app/models/concerns/tiny_mce_images.rb @@ -97,12 +97,11 @@ module TinyMceImages next if asset && asset.object == self && asset.team_id != asset_team_id new_image = asset.image - new_image_filename = new_image.image.filename.to_s + new_image_filename = new_image.file_name else # We need implement size and type checks here new_image = URI.parse(image['src']).open new_image_filename = asset.class.generate_unique_secure_token + '.jpg' - # new_image_filename = File.basename(new_image.base_uri.path) end new_asset = TinyMceAsset.create( diff --git a/app/models/protocol.rb b/app/models/protocol.rb index add6f26d4..942386d98 100644 --- a/app/models/protocol.rb +++ b/app/models/protocol.rb @@ -226,41 +226,15 @@ class Protocol < ApplicationRecord end # Deep-clone given array of assets - def self.deep_clone_assets(assets_to_clone, team) + def self.deep_clone_assets(assets_to_clone) assets_to_clone.each do |src_id, dest_id| src = Asset.find_by_id(src_id) dest = Asset.find_by_id(dest_id) dest.destroy! if src.blank? && dest.present? next unless src.present? && dest.present? + # Clone file - dest.file = src.file - dest.save! - - if dest.image? - dest.file.reprocess!(:large) - dest.file.reprocess!(:medium) - end - - # Clone extracted text data if it exists - if (atd = src.asset_text_datum).present? - atd2 = AssetTextDatum.new( - data: atd.data, - asset: dest - ) - atd2.save! - end - - # Update estimated size of cloned asset - # (& file_present flag) - dest.update( - estimated_size: src.estimated_size, - file_present: true - ) - - # Update team's space taken - team.reload - team.take_space(dest.estimated_size) - team.save! + src.duplicate_file(dst) end end @@ -318,16 +292,8 @@ class Protocol < ApplicationRecord # "Shallow" Copy assets step.assets.each do |asset| - asset2 = Asset.new_empty( - asset.file_file_name, - asset.file_file_size - ) - asset2.created_by = current_user - asset2.team = dest.team - asset2.last_modified_by = current_user - asset2.file_processing = true if asset.image? + asset2 = asset.dup asset2.save! - step2.assets << asset2 assets_to_clone << [asset.id, asset2.id] end @@ -348,10 +314,7 @@ class Protocol < ApplicationRecord step.clone_tinymce_assets(step2, dest.team) end # Call clone helper - Protocol.delay(queue: :assets).deep_clone_assets( - assets_to_clone, - dest.team - ) + Protocol.delay(queue: :assets).deep_clone_assets(assets_to_clone) end def in_repository_active? diff --git a/app/models/repository_asset_value.rb b/app/models/repository_asset_value.rb index a8bb65de2..e1eb6e4c3 100644 --- a/app/models/repository_asset_value.rb +++ b/app/models/repository_asset_value.rb @@ -16,11 +16,11 @@ class RepositoryAssetValue < ApplicationRecord validates :asset, :repository_cell, presence: true def formatted - asset.file_file_name + asset.file_name end def data - asset.file_file_name + asset.file_name end def data_changed?(_new_data) @@ -28,9 +28,8 @@ class RepositoryAssetValue < ApplicationRecord end def update_data!(new_data, user) - file = Paperclip.io_adapters.for(new_data[:file_data]) file.original_filename = new_data[:file_name] - asset.file = file + asset.file.attach(io: new_data[:file_data], filename: new_data[:file_name]) asset.last_modified_by = user self.last_modified_by = user asset.save! && save! diff --git a/app/models/team.rb b/app/models/team.rb index dbc88f7da..ccd350add 100644 --- a/app/models/team.rb +++ b/app/models/team.rb @@ -63,124 +63,6 @@ class Team < ApplicationRecord .where('full_name ILIKE ? OR email ILIKE ?', a_query, a_query) end - # Imports samples into db - # -1 == sample_name, - # -2 == sample_type, - # -3 == sample_group - # TODO: use constants - def import_samples(sheet, mappings, user) - errors = false - nr_of_added = 0 - total_nr = 0 - header_skipped = false - - # First let's query for all custom_fields we're refering to - custom_fields = [] - sname_index = -1 - stype_index = -1 - sgroup_index = -1 - mappings.each.with_index do |(_, v), i| - if v == '-1' - # Fill blank space, so our indices stay the same - custom_fields << nil - sname_index = i - elsif v == '-2' - custom_fields << nil - stype_index = i - elsif v == '-3' - custom_fields << nil - sgroup_index = i - else - cf = CustomField.find_by_id(v) - - # Even if doesn't exist we add nil value in order not to destroy our - # indices - custom_fields << cf - end - end - - rows = SpreadsheetParser.spreadsheet_enumerator(sheet) - - # Now we can iterate through sample data and save stuff into db - rows.each do |row| - # Skip empty rows - next if row.empty? - unless header_skipped - header_skipped = true - next - end - total_nr += 1 - row = SpreadsheetParser.parse_row(row, sheet) - - sample = Sample.new(name: row[sname_index], - team: self, - user: user) - - sample.transaction do - unless sample.valid? - errors = true - raise ActiveRecord::Rollback - end - - row.each.with_index do |value, index| - next unless value.present? - if index == stype_index - stype = SampleType.where(team: self) - .where('name ILIKE ?', value.strip) - .take - - unless stype - stype = SampleType.new(name: value.strip, team: self) - unless stype.save - errors = true - raise ActiveRecord::Rollback - end - end - sample.sample_type = stype - elsif index == sgroup_index - sgroup = SampleGroup.where(team: self) - .where('name ILIKE ?', value.strip) - .take - - unless sgroup - sgroup = SampleGroup.new(name: value.strip, team: self) - unless sgroup.save - errors = true - raise ActiveRecord::Rollback - end - end - sample.sample_group = sgroup - elsif value && custom_fields[index] - # we're working with CustomField - scf = SampleCustomField.new( - sample: sample, - custom_field: custom_fields[index], - value: value - ) - unless scf.valid? - errors = true - raise ActiveRecord::Rollback - end - sample.sample_custom_fields << scf - end - end - if Sample.import([sample], - recursive: true, - validate: false).failed_instances.any? - errors = true - raise ActiveRecord::Rollback - end - nr_of_added += 1 - end - end - - if errors - return { status: :error, nr_of_added: nr_of_added, total_nr: total_nr } - else - return { status: :ok, nr_of_added: nr_of_added, total_nr: total_nr } - end - end - def to_csv(samples, headers) require "csv" diff --git a/app/models/team_zip_export.rb b/app/models/team_zip_export.rb index 742ab5294..b741365a7 100644 --- a/app/models/team_zip_export.rb +++ b/app/models/team_zip_export.rb @@ -147,7 +147,7 @@ class TeamZipExport < ZipExport .routes .url_helpers .zip_exports_download_export_all_path(self)}'>" \ - "#{zip_file_file_name}" + "#{zip_file_name}" ) UserNotification.create(notification: notification, user: user) end @@ -197,11 +197,9 @@ class TeamZipExport < ZipExport if type == :step name = "#{directory}/" \ - "#{append_file_suffix(asset.file_file_name, - "_#{i}_Step#{element.step.position_plus_one}")}" + "#{append_file_suffix(asset.file_name, "_#{i}_Step#{element.step.position_plus_one}")}" elsif type == :result - name = "#{directory}/#{append_file_suffix(asset.file_file_name, - "_#{i}")}" + name = "#{directory}/#{append_file_suffix(asset.file_name, "_#{i}")}" end asset.file.copy_to_local_file(:original, name) if asset.file.exists? asset_indexes[asset.id] = name @@ -254,8 +252,7 @@ class TeamZipExport < ZipExport assets = {} asset_counter = 0 handle_name_func = lambda do |asset| - file_name = append_file_suffix(asset.file_file_name, - "_#{asset_counter}").to_s + file_name = append_file_suffix(asset.file_name, "_#{asset_counter}").to_s # Save pair for downloading it later assets[asset] = "#{attach_path}/#{file_name}" diff --git a/app/models/tiny_mce_asset.rb b/app/models/tiny_mce_asset.rb index 701f7e825..6f56d307a 100644 --- a/app/models/tiny_mce_asset.rb +++ b/app/models/tiny_mce_asset.rb @@ -70,6 +70,26 @@ class TinyMceAsset < ApplicationRecord description.css('body').inner_html.to_s end + def file_name + return '' unless image.attached? + + image.blob&.filename&.to_s + end + + def file_size + return 0 unless image.attached? + + image.blob&.byte_size + end + + def content_type + image&.blob&.content_type + end + + def file_size + image&.blob&.byte_size + end + def preview image.variant(resize: Constants::LARGE_PIC_FORMAT) end @@ -122,8 +142,7 @@ class TinyMceAsset < ApplicationRecord asset_guid = get_guid(tiny_mce_asset.id) asset_file_name = "rte-#{asset_guid.to_s + File.extname(tiny_mce_asset.image.filename.to_s)}" ostream.put_next_entry("#{dir}/#{asset_file_name}") - input_file = tiny_mce_asset.image.download - ostream.print(input_file.read) + ostream.print(tiny_mce_asset.image.download) input_file.close end end diff --git a/app/models/user.rb b/app/models/user.rb index d7a6a215a..9698b474a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -229,11 +229,6 @@ class User < ApplicationRecord foreign_key: :resource_owner_id, dependent: :delete_all - # If other errors besides parameter "avatar" exist, - # they will propagate to "avatar" also, so remove them - # and put all other (more specific ones) in it - # after_validation :filter_paperclip_errors - before_destroy :destroy_notifications def name @@ -334,20 +329,6 @@ class User < ApplicationRecord self.avatar_file_size = size.to_i end - def filter_paperclip_errors - if errors.key? :avatar - errors.delete(:avatar) - messages = [] - errors.each do |attribute| - errors.full_messages_for(attribute).each do |message| - messages << message.split(' ').drop(1).join(' ') - end - end - errors.clear - errors.add(:avatar, messages.join(',')) - end - end - # Whether user is active (= confirmed) or not def active? confirmed_at.present? diff --git a/app/models/zip_export.rb b/app/models/zip_export.rb index 27ede12ef..6706662a8 100644 --- a/app/models/zip_export.rb +++ b/app/models/zip_export.rb @@ -48,6 +48,12 @@ class ZipExport < ApplicationRecord export&.destroy end + def zip_file_name + return '' unless file.attached? + + zip_file.blob&.filename&.to_s + end + def generate_exportable_zip(user, data, type, options = {}) I18n.backend.date_format = user.settings[:date_format] || Constants::DEFAULT_DATE_FORMAT zip_input_dir = FileUtils.mkdir_p(File.join(Rails.root, "tmp/temp_zip_#{Time.now.to_i}")).first @@ -96,7 +102,7 @@ class ZipExport < ApplicationRecord .routes .url_helpers .zip_exports_download_path(self)}'>" \ - "#{zip_file_file_name}" + "#{zip_file_name}" ) UserNotification.create(notification: notification, user: user) end diff --git a/app/serializers/api/v1/repository_asset_value_serializer.rb b/app/serializers/api/v1/repository_asset_value_serializer.rb index ad7eb2458..a64c49532 100644 --- a/app/serializers/api/v1/repository_asset_value_serializer.rb +++ b/app/serializers/api/v1/repository_asset_value_serializer.rb @@ -10,11 +10,11 @@ module Api end def file_name - object.asset&.file_file_name + object.asset&.file_name end def file_size - object.asset&.file_file_size + object.asset&.file_size end def url diff --git a/app/serializers/api/v1/result_asset_serializer.rb b/app/serializers/api/v1/result_asset_serializer.rb index 8e24e9a3b..d86e999f2 100644 --- a/app/serializers/api/v1/result_asset_serializer.rb +++ b/app/serializers/api/v1/result_asset_serializer.rb @@ -11,11 +11,11 @@ module Api end def file_name - object.asset&.file_file_name + object.asset&.file_name end def file_size - object.asset&.file_file_size + object.asset&.file_size end def url diff --git a/app/services/repository_actions/duplicate_cell.rb b/app/services/repository_actions/duplicate_cell.rb index 554638226..e3f717fa1 100644 --- a/app/services/repository_actions/duplicate_cell.rb +++ b/app/services/repository_actions/duplicate_cell.rb @@ -43,7 +43,7 @@ module RepositoryActions def duplicate_repository_asset_value old_value = @cell.value - new_asset = create_new_asset(old_value.asset) + new_asset = old_value.asset.duplicate RepositoryAssetValue.create( old_value.attributes.merge( id: nil, asset: new_asset, created_by: @user, last_modified_by: @user, @@ -67,30 +67,5 @@ module RepositoryActions ) ) end - - # reuses the same code we have in copy protocols action - def create_new_asset(old_asset) - new_asset = Asset.new_empty( - old_asset.file_file_name, - old_asset.file_file_size - ) - new_asset.created_by = old_asset.created_by - new_asset.team = @team - new_asset.last_modified_by = @user - new_asset.file_processing = true if old_asset.image? - new_asset.file = old_asset.file - new_asset.save - - return unless new_asset.valid? - - if new_asset.image? - new_asset.file.reprocess!(:large) - new_asset.file.reprocess!(:medium) - end - - new_asset.post_process_file(new_asset.team) - - new_asset - end end end diff --git a/app/services/repository_datatable_service.rb b/app/services/repository_datatable_service.rb index 2e2887230..9a5e55160 100644 --- a/app/services/repository_datatable_service.rb +++ b/app/services/repository_datatable_service.rb @@ -171,12 +171,18 @@ class RepositoryDatatableService def filter_by_asset_value(records, id, dir) records.joins( "LEFT OUTER JOIN (SELECT repository_cells.repository_row_id, - assets.file_file_name AS value + active_storage_blobs.filename AS value FROM repository_cells INNER JOIN repository_asset_values ON repository_asset_values.id = repository_cells.value_id INNER JOIN assets ON repository_asset_values.asset_id = assets.id + INNER JOIN active_storage_attachments + ON active_storage_attachments.record_id = assets.id + AND active_storage_attachments.record_type = 'Asset' + AND active_storage_attachments.name = 'file' + INNER JOIN active_storage_blobs + ON active_storage_blobs.id = active_storage_attachments.blob_id WHERE repository_cells.repository_column_id = #{id}) AS values ON values.repository_row_id = repository_rows.id" ).order("values.value #{dir}") diff --git a/app/services/spreadsheet_parser.rb b/app/services/spreadsheet_parser.rb index ab2c54235..ef36175f4 100644 --- a/app/services/spreadsheet_parser.rb +++ b/app/services/spreadsheet_parser.rb @@ -4,11 +4,6 @@ class SpreadsheetParser 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) diff --git a/app/services/team_importer.rb b/app/services/team_importer.rb index 74ed1dfcb..ecb3c7dc1 100644 --- a/app/services/team_importer.rb +++ b/app/services/team_importer.rb @@ -340,8 +340,8 @@ class TeamImporter tiny_mce_asset.object_id = mappings[tiny_mce_asset.object_id] end tiny_mce_asset.team = team - tiny_mce_asset.image = tiny_mce_file tiny_mce_asset.save! + tiny_mce_asset.image.attach(io: tiny_mce_file, filename: tiny_mce_file.basename) @mce_asset_counter += 1 if tiny_mce_asset.object_id.present? object = tiny_mce_asset.object @@ -794,7 +794,7 @@ class TeamImporter def create_asset(asset_json, team, user_id = nil) asset = Asset.new(asset_json) File.open( - "#{@import_dir}/assets/#{asset.id}/#{asset.file_file_name}" + "#{@import_dir}/assets/#{asset.id}/#{asset.file_name}" ) do |file| orig_asset_id = asset.id asset.id = nil @@ -802,9 +802,9 @@ class TeamImporter asset.last_modified_by_id = user_id || find_user(asset.last_modified_by_id) asset.team = team - asset.file = file asset.in_template = true if @is_template asset.save! + asset.file.attach(io: file, filename: file.basename) asset.post_process_file(team) @asset_mappings[orig_asset_id] = asset.id @asset_counter += 1 diff --git a/app/utilities/protocols_exporter.rb b/app/utilities/protocols_exporter.rb index cb402e2dc..f63d31246 100644 --- a/app/utilities/protocols_exporter.rb +++ b/app/utilities/protocols_exporter.rb @@ -51,12 +51,11 @@ module ProtocolsExporter next unless img img_guid = get_guid(img.id) - asset_file_name = "rte-#{img_guid}" \ - "#{File.extname(img.image_file_name)}" + asset_file_name = "rte-#{img_guid}#{File.extname(img.file_name)}" asset_xml = "\n" - asset_xml << "#{img.image_file_name}\n" - asset_xml << "#{img.image_content_type}\n" + asset_xml << "#{img.file_name}\n" + asset_xml << "#{img.content_type}\n" asset_xml << "\n" tiny_assets_xml << asset_xml end @@ -100,11 +99,11 @@ module ProtocolsExporter step.assets.order(:id).each do |asset| asset_guid = get_guid(asset.id) asset_file_name = "#{asset_guid}" \ - "#{File.extname(asset.file_file_name)}" + "#{File.extname(asset.file_name)}" asset_xml = "\n" - asset_xml << "#{asset.file_file_name}\n" - asset_xml << "#{asset.file_content_type}\n" + asset_xml << "#{asset.file_name}\n" + asset_xml << "#{asset.content_type}\n" asset_xml << "\n" step_xml << asset_xml end diff --git a/app/utilities/protocols_importer.rb b/app/utilities/protocols_importer.rb index d095a12d7..00726582d 100644 --- a/app/utilities/protocols_importer.rb +++ b/app/utilities/protocols_importer.rb @@ -111,9 +111,7 @@ module ProtocolsImporter ) # Decode the file bytes - asset.file = StringIO.new(Base64.decode64(asset_json['bytes'])) - asset.file_file_name = asset_json['fileName'] - asset.file_content_type = asset_json['fileType'] + asset.file.attach(io: StringIO.new(Base64.decode64(asset_json['bytes'])), filename: asset_json['fileName']) asset.save! asset_ids << asset.id @@ -152,12 +150,11 @@ module ProtocolsImporter team_id: team.id, saved: true ) - # Decode the file bytes - tiny_mce_img.image = StringIO.new( - Base64.decode64(tiny_mce_img_json['bytes']) - ) - tiny_mce_img.image_content_type = tiny_mce_img_json['fileType'] tiny_mce_img.save! + + # Decode the file bytes + tiny_mce_img.image.attach(io: StringIO.new(Base64.decode64(tiny_mce_img_json['bytes'])), + filename: tiny_mce_img_json['fileName']) if description.gsub!("data-mce-token=\"#{tiny_mce_img_json['tokenId']}\"", "data-mce-token=\"#{Base62.encode(tiny_mce_img.id)}\"") else diff --git a/app/utilities/wopi_util.rb b/app/utilities/wopi_util.rb index eabeaa693..2ed5ebb9e 100644 --- a/app/utilities/wopi_util.rb +++ b/app/utilities/wopi_util.rb @@ -83,7 +83,7 @@ module WopiUtil default_step_items = { step: @asset.step.id, step_position: { id: @asset.step.id, value_for: 'position_plus_one' }, - asset_name: { id: @asset.id, value_for: 'file_file_name' }, + asset_name: { id: @asset.id, value_for: 'file_name' }, action: action } if @protocol.in_module? project = @protocol.my_module.experiment.project @@ -113,7 +113,7 @@ module WopiUtil project: @my_module.experiment.project, message_items: { result: @asset.result.id, - asset_name: { id: @asset.id, value_for: 'file_file_name' }, + asset_name: { id: @asset.id, value_for: 'file_name' }, action: action }) end diff --git a/app/views/assets/edit.erb b/app/views/assets/edit.erb index 17e71dc25..f4617301f 100644 --- a/app/views/assets/edit.erb +++ b/app/views/assets/edit.erb @@ -6,7 +6,7 @@ - <%= t('assets.head_title.edit', file_name: @asset.file_file_name) %> + <%= t('assets.head_title.edit', file_name: @asset.file_name) %> diff --git a/app/views/assets/view.erb b/app/views/assets/view.erb index e20aa03ff..1bd84e2a2 100644 --- a/app/views/assets/view.erb +++ b/app/views/assets/view.erb @@ -6,7 +6,7 @@ - <%= t('assets.head_title.view', file_name: @asset.file_file_name) %> + <%= t('assets.head_title.view', file_name: @asset.file_name) %> diff --git a/app/views/reports/elements/_my_module_result_asset_element.html.erb b/app/views/reports/elements/_my_module_result_asset_element.html.erb index 3cbb13b6e..e934d8adf 100644 --- a/app/views/reports/elements/_my_module_result_asset_element.html.erb +++ b/app/views/reports/elements/_my_module_result_asset_element.html.erb @@ -24,7 +24,7 @@ <% else %> <%=t "projects.reports.elements.result_asset.file_name", - file: truncate(asset.file_file_name, + file: truncate(asset.file_name, length: Constants::FILENAME_TRUNCATION_LENGTH) %> <% end %>
diff --git a/app/views/reports/elements/_step_asset_element.html.erb b/app/views/reports/elements/_step_asset_element.html.erb index b84d9a61b..ef768927b 100644 --- a/app/views/reports/elements/_step_asset_element.html.erb +++ b/app/views/reports/elements/_step_asset_element.html.erb @@ -2,7 +2,7 @@ <% is_image = asset.image? %> <% timestamp = asset.created_at %> <% icon_class = 'fas ' + (is_image ? 'fa-image' : 'fa-file') %> -
" data-icon-class="<%= icon_class %>"> +
" data-icon-class="<%= icon_class %>">
@@ -16,7 +16,7 @@ <% else %> <%=t 'projects.reports.elements.step_asset.file_name', - file: truncate(asset.file_file_name, + file: truncate(asset.file_name, length: Constants::FILENAME_TRUNCATION_LENGTH) %> <% end %>
diff --git a/app/views/result_assets/_edit.html.erb b/app/views/result_assets/_edit.html.erb index e35b55239..7d1bc574d 100644 --- a/app/views/result_assets/_edit.html.erb +++ b/app/views/result_assets/_edit.html.erb @@ -5,7 +5,7 @@ <%=t "result_assets.edit.uploaded_asset" %>

<%= file_extension_icon(ff.object) %> - <%= ff.object.file_file_name %> + <%= ff.object.file_name %>

<%= ff.file_field :file %> <% end %> diff --git a/app/views/search/results/partials/_asset_text.html.erb b/app/views/search/results/partials/_asset_text.html.erb index f5a483393..04de9d822 100644 --- a/app/views/search/results/partials/_asset_text.html.erb +++ b/app/views/search/results/partials/_asset_text.html.erb @@ -1,6 +1,6 @@ <% query ||= nil %> <% asset_read_allowed = false %> -<% text = query.present? ? highlight(asset.file_file_name, query.strip.split(/\s+/)) : asset.file_file_name %> +<% text = query.present? ? highlight(asset.file_name, query.strip.split(/\s+/)) : asset.file_name %> <% if asset.step %> <% protocol = asset.step.protocol %> diff --git a/config/environments/production.rb b/config/environments/production.rb index 5df50d3fc..676fca7c2 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -48,7 +48,7 @@ Rails.application.configure do # Compress JavaScripts and CSS. - config.assets.js_compressor = :uglifier + config.assets.js_compressor = Uglifier.new(harmony: true) # config.assets.css_compressor = :sass # Do not fallback to assets pipeline if a precompiled asset is missed. @@ -71,6 +71,8 @@ Rails.application.configure do # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. config.force_ssl = ENV['RAILS_FORCE_SSL'].present? + config.ssl_options = { redirect: { exclude: ->(request) { request.path =~ %r{api\/health} } } } + # Use the lowest log level to ensure availability of diagnostic information # when problems arise. config.log_level = :debug diff --git a/config/initializers/extends.rb b/config/initializers/extends.rb index 2e79014d1..4aac4bfff 100644 --- a/config/initializers/extends.rb +++ b/config/initializers/extends.rb @@ -55,12 +55,12 @@ class Extends # are only supported REPOSITORY_EXTRA_SEARCH_ATTR = ['repository_text_values.data', 'repository_list_items.data', - 'assets.file_file_name'] + 'active_storage_blobs.filename'] # Array of includes used in search query for repository rows REPOSITORY_SEARCH_INCLUDES = [:repository_text_value, repository_list_value: :repository_list_item, - repository_asset_value: :asset] + repository_asset_value: { asset: { file_attachment: :blob } }] # List of implemented core API versions API_VERSIONS = ['v1'] diff --git a/config/locales/en.yml b/config/locales/en.yml index 536da4a75..14407e7b5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1262,7 +1262,6 @@ en: scinote_columns_html: "SciNote columns:" file_columns: "Imported columns:" example_value: "Imported file content:" - import_samples: "Import samples" do_not_include_column: "Do not include this column" errors: invalid_file: "The file you provided is invalid. Make sure the file is encoded using %{encoding}." diff --git a/config/routes.rb b/config/routes.rb index a9a665a6a..6f5bf3cdb 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -192,8 +192,6 @@ Rails.application.routes.draw do # end member do post 'parse_sheet', defaults: { format: 'json' } - # post 'import_samples' - # post 'export_samples' post 'export_repository', to: 'repositories#export_repository' post 'export_projects' get 'export_projects_modal' diff --git a/docker-compose.production.yml b/docker-compose.production.yml index 0877637cb..f8dbfa157 100644 --- a/docker-compose.production.yml +++ b/docker-compose.production.yml @@ -37,7 +37,9 @@ services: - RAILS_ENV=production volumes: - scinote_production_files:/usr/src/app/public/system + - scinote_production_storage:/usr/src/app/storage volumes: scinote_production_postgres: scinote_production_files: + scinote_production_storage: