From 7efed83dbb371dc7717c4f258d9de54b7b112496 Mon Sep 17 00:00:00 2001 From: Rob Paskin Date: Wed, 22 May 2024 15:02:58 +0100 Subject: [PATCH 01/28] Upgrade actions in CodeQL workflow to latest versions Current versions are deprecated and will be unsupported by the end of the year. See: - https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/ - https://github.blog/changelog/2024-01-12-code-scanning-deprecation-of-codeql-action-v2/ --- .github/workflows/codeql.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 7756a87..f52af9a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -42,11 +42,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -60,7 +60,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 # â„šī¸ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -73,6 +73,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" From 388e43577e9ff613d434900daef273cc61196fe2 Mon Sep 17 00:00:00 2001 From: Rob Paskin Date: Wed, 22 May 2024 15:13:09 +0100 Subject: [PATCH 02/28] Add workflow to sync Dependabot alerts to Jira --- .github/workflows/github-security-jira.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/github-security-jira.yml diff --git a/.github/workflows/github-security-jira.yml b/.github/workflows/github-security-jira.yml new file mode 100644 index 0000000..c0e05a8 --- /dev/null +++ b/.github/workflows/github-security-jira.yml @@ -0,0 +1,22 @@ +name: GitHub Security Alerts for Jira + +on: + schedule: + - cron: '0 4 * * *' + workflow_dispatch: + +jobs: + syncSecurityAlerts: + runs-on: ubuntu-latest + steps: + - name: "Sync security alerts to Jira issues" + uses: reload/github-security-jira@v1.5.0 + env: + GH_SECURITY_TOKEN: ${{ secrets.ORG_GITHUBSECURITYTOKEN }} + JIRA_TOKEN: ${{ secrets.ORG_JIRA_TOKEN }} + JIRA_HOST: https://360insights.atlassian.net/ + JIRA_USER: ${{secrets.ORG_JIRA_USERNAME}} + JIRA_PROJECT: SB + JIRA_ISSUE_TYPE: Security Code Analysis + JIRA_ISSUE_LABELS: MYREWARDS_SECURITY_ALERT + JIRA_RESTRICTED_COMMENT_ROLE: Developer From c30c747e3f55fbf435fe1ebbf58b4ab9f60a2718 Mon Sep 17 00:00:00 2001 From: Rob Paskin Date: Wed, 5 Feb 2025 14:32:19 +0000 Subject: [PATCH 03/28] Update Ruby & MySQL versions to 'current' Versions match what we're currently running. --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 2c039bc..f3a1ed4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '3' services: app: - image: ruby:${RUBY_VERSION:-2.6.10} + image: ruby:${RUBY_VERSION:-2.7.8} working_dir: /app command: > bash -eu -c ' @@ -18,7 +18,7 @@ services: - .:/app:cached db: - image: mysql:5.7 + image: mysql:8.0.34 environment: - MYSQL_ALLOW_EMPTY_PASSWORD=yes expose: From d8033fec887317cda58bb8578aecd2e006e83cba Mon Sep 17 00:00:00 2001 From: Rob Paskin Date: Wed, 5 Feb 2025 15:34:46 +0000 Subject: [PATCH 04/28] Fix error in spec_helper > uninitialized constant ActiveSupport::LoggerThreadSafeLevel::Logger --- spec/spec_helper.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a74a278..dfe7f98 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,6 +1,7 @@ require 'bundler/setup' require 'byebug' require 'mysql2' +require 'logger' require 'rails/all' require 'csv2db' require_relative '../app/models/concerns/csv2db/import' From abbb8b329a1dda2b0a95f900c563382c7dc2014f Mon Sep 17 00:00:00 2001 From: Rob Paskin Date: Wed, 5 Feb 2025 14:32:59 +0000 Subject: [PATCH 05/28] Add GH workflow for CI We use containers (rather than `setup-ruby`) since that's more representative of the environment in which we use the gem, even though it's presumably slower. Changes from Buildkite: - Use Docker healthcheck rather than waiting ourselves - Inline test script steps in workflows, rather than having a separate script (since we don't have the wait-for-MySQL part anymore) - Add GitHub-Actions-specific output grouping - Don't collect test failures via JUnit (it's overkill for the amount of tests we have). --- .github/workflows/ci.yml | 51 ++++++++++++++++++++++++++++++++++++++++ docker-entrypoint.sh | 20 ++++++++++++++-- 2 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..5b4cd1c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,51 @@ +name: Test Suite + +on: + push: + workflow_dispatch: + +jobs: + spec: + name: RSpec + runs-on: ubuntu-latest + + container: + image: ruby:2.7.8 + credentials: + username: ${{ secrets.ORG_DOCKERHUB_USERNAME }} + password: ${{ secrets.ORG_DOCKERHUB_TOKEN }} + env: + DB_HOST: db + DB_USERNAME: root + + services: # versions here should match those used in docker-compose.yml + db: + image: mysql:8.0.34 + env: + MYSQL_ALLOW_EMPTY_PASSWORD: "yes" + options: >- + --health-cmd="mysqladmin ping" + --health-interval=10s + --health-timeout=5s + --health-retries=3 + + steps: + - uses: actions/checkout@v4 + + - name: Run RSpec + shell: script -q -e -c "bash {0}" # force colour output - see https://github.com/actions/runner/issues/241 + run: | + set -euo pipefail + + ./docker-entrypoint.sh + + mkdir -p tmp + mkdir -p log + + bin/rspec + + - uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} + with: + name: "test.log" + path: log/test.log diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index e6f0441..a430d43 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,11 +1,27 @@ #!/usr/bin/env sh set -eu -echo "~~~ update RubyGems and Bundler" +# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#grouping-log-lines +group() { + echo "::group::${1}" +} + +endgroup() { + echo "::endgroup::" +} + +group "update RubyGems and Bundler" + +# latest supported versions for Ruby 2.x gem install bundler -v "~> 2.4.22" gem update --system 3.4.22 >/dev/null -echo "~~~ bundle install" +endgroup + +group "bundle install" + bundle install \ --jobs "$(getconf _NPROCESSORS_ONLN)" \ --retry 2 + +endgroup From 8fbd168a28e211b7f6c53de533bb49d1364f1e9d Mon Sep 17 00:00:00 2001 From: Rob Paskin Date: Wed, 5 Feb 2025 16:11:09 +0000 Subject: [PATCH 06/28] Remove Buildkite files Superseded by GitHub Actions workflow. --- .buildkite/pipeline.yml | 32 -------------------------------- .buildkite/test.sh | 26 -------------------------- 2 files changed, 58 deletions(-) delete mode 100644 .buildkite/pipeline.yml delete mode 100755 .buildkite/test.sh diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml deleted file mode 100644 index 8775da4..0000000 --- a/.buildkite/pipeline.yml +++ /dev/null @@ -1,32 +0,0 @@ -steps: - - label: ':rspec:' - key: spec - plugins: - - docker-compose#v3.9.0: - run: app - env: - # used for names of JUnit XML files - - BUILDKITE_JOB_ID - timeout_in_minutes: 5 - commands: - - './docker-entrypoint.sh' - - '.buildkite/test.sh' - env: - BYEBUG: '0' - DEBUGGER: '0' - artifact_paths: - - log/*.log - - tmp/rspec-junit-*.xml - - tmp/rspec/*.txt - - tmp/capybara/* - - tmp/screenshots/* - - - wait: ~ - continue_on_failure: true - - - label: ':junit:' - plugins: - - junit-annotate#v1.9.0: - artifacts: tmp/rspec-junit-*.xml - job-uuid-file-pattern: rspec-junit-([^.]+)\.xml - failure-format: file diff --git a/.buildkite/test.sh b/.buildkite/test.sh deleted file mode 100755 index 08e258c..0000000 --- a/.buildkite/test.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env sh -set -eu - -echo "~~~ Waiting for MySQL" -retries=5 - -until ruby -rsocket -e 'Socket.tcp(ENV["DB_HOST"], 3306).close' 2>/dev/null; do - retries="$(("$retries" - 1))" - - if [ "$retries" -eq 0 ]; then - echo "Failed to reach MySQL" >&2 - exit 1 - fi - - sleep 5 - echo "Waiting for MySQL ($retries retries left)" -done - -echo "+++ :rspec: Running specs" -mkdir -p tmp -mkdir -p log - -bin/rspec \ - --format RspecJunitFormatter \ - --out "tmp/rspec-junit-$BUILDKITE_JOB_ID.xml" \ - --format documentation From 94535973716f1662eb920b698f7f69dc0884e430 Mon Sep 17 00:00:00 2001 From: Rob Paskin Date: Wed, 5 Feb 2025 16:34:00 +0000 Subject: [PATCH 07/28] Remove no-longer-needed development gem --- csv2db.gemspec | 1 - 1 file changed, 1 deletion(-) diff --git a/csv2db.gemspec b/csv2db.gemspec index a2df913..49124ab 100644 --- a/csv2db.gemspec +++ b/csv2db.gemspec @@ -45,5 +45,4 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'mysql2', '~> 0.5.3' spec.add_development_dependency 'rake', '~> 12.3.3' spec.add_development_dependency 'rspec', '~> 3.0' - spec.add_development_dependency 'rspec_junit_formatter', '~> 0.4' end From 0667089eaf42f2d783fe43c1c5652a04d5d8484c Mon Sep 17 00:00:00 2001 From: Rob Paskin Date: Wed, 5 Feb 2025 16:44:36 +0000 Subject: [PATCH 08/28] Remove obsolete reference to CircleCI --- spec/spec_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index dfe7f98..27530a3 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,7 +22,7 @@ end db_config = { - database: "csv2db_test#{ENV['CIRCLE_NODE_INDEX']}", + database: 'csv2db_test', adapter: 'mysql2', encoding: 'utf8mb4', pool: 5, From 65e4b215a6c1c9bbbbeb3476de20ad8f5f0d3699 Mon Sep 17 00:00:00 2001 From: Lan Pham Date: Wed, 9 Apr 2025 10:53:54 +0100 Subject: [PATCH 09/28] Update rails constraints to 7.0 --- csv2db.gemspec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/csv2db.gemspec b/csv2db.gemspec index 49124ab..087c5ce 100644 --- a/csv2db.gemspec +++ b/csv2db.gemspec @@ -33,11 +33,11 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ['lib'] - spec.add_dependency 'activerecord', '>= 4.2', '< 6.2' - spec.add_dependency 'activesupport', '>= 4.2', '< 6.2' + spec.add_dependency 'activerecord', '>= 4.2', '< 7.1' + spec.add_dependency 'activesupport', '>= 4.2', '< 7.1' spec.add_dependency 'charlock_holmes', '~> 0.7.3' spec.add_dependency 'dragonfly', '~> 1' - spec.add_dependency 'railties', '>= 4.2', '< 6.2' + spec.add_dependency 'railties', '>= 4.2', '< 7.1' spec.add_dependency 'sidekiq', '>= 3' spec.add_development_dependency 'bundler', '>= 2.2.18', '< 3' From 37dcbaafe3fd0474c86324b43e85f6d0583043fa Mon Sep 17 00:00:00 2001 From: farisalamin Date: Wed, 9 Apr 2025 15:58:50 +0100 Subject: [PATCH 10/28] Fix autoloading for Rails 7.0 --- lib/csv2db/rails.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/csv2db/rails.rb b/lib/csv2db/rails.rb index 0434d4c..2207c1b 100644 --- a/lib/csv2db/rails.rb +++ b/lib/csv2db/rails.rb @@ -13,6 +13,8 @@ class Engine < Rails::Engine initializer 'csv2db.add_controller_helpers' do ActiveSupport.on_load(:action_controller) do + require_relative '../../app/controllers/concerns/csv2db/controller_helpers' + include Csv2db::ControllerHelpers end end From b334cb9d4684938877f9c4af6430b4549105cdb5 Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Thu, 15 May 2025 17:28:41 +0100 Subject: [PATCH 11/28] REW-2045 - implement storage adapters for active storage and dragonfly Enable gem configurables --- .../concerns/csv2db/active_storage_adapter.rb | 7 +++++++ .../concerns/csv2db/dragonfly_adapter.rb | 18 ++++++++++++++++++ app/models/concerns/csv2db/import.rb | 10 +--------- lib/csv2db.rb | 12 +++++++++++- lib/csv2db/config.rb | 13 +++++++++++++ 5 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 app/models/concerns/csv2db/active_storage_adapter.rb create mode 100644 app/models/concerns/csv2db/dragonfly_adapter.rb create mode 100644 lib/csv2db/config.rb diff --git a/app/models/concerns/csv2db/active_storage_adapter.rb b/app/models/concerns/csv2db/active_storage_adapter.rb new file mode 100644 index 0000000..ac94f7a --- /dev/null +++ b/app/models/concerns/csv2db/active_storage_adapter.rb @@ -0,0 +1,7 @@ +module Csv2db::ActiveStorageAdapter + extend ActiveSupport::Concern + + included do + has_one_attached :csv_upload + end +end diff --git a/app/models/concerns/csv2db/dragonfly_adapter.rb b/app/models/concerns/csv2db/dragonfly_adapter.rb new file mode 100644 index 0000000..44ae1d9 --- /dev/null +++ b/app/models/concerns/csv2db/dragonfly_adapter.rb @@ -0,0 +1,18 @@ +module Csv2db::DragonflyAdapter + extend ActiveSupport::Concern + require 'dragonfly' + + included do + extend Dragonfly::Model + + dragonfly_accessor :file + + validate :check_file_extension + validates :file, presence: true + end + + def check_file_extension + # very basic check of file extension + errors.add(:file, I18n.t('shared.file_processor.incorrect_file_type')) unless file.ext == 'csv' + end +end diff --git a/app/models/concerns/csv2db/import.rb b/app/models/concerns/csv2db/import.rb index e831e3f..2922aea 100644 --- a/app/models/concerns/csv2db/import.rb +++ b/app/models/concerns/csv2db/import.rb @@ -27,13 +27,9 @@ def around_process(*args, &block) end included do - extend Dragonfly::Model + include Module.const_get("Csv2db::#{Csv2db.config.storage_adapter}Adapter") - validates :file, presence: true validate :required_params_are_present - validate :check_file_extension - - dragonfly_accessor :file after_initialize :set_default_values, :set_required_params @@ -210,9 +206,5 @@ def str_to_utf_8(str) def set_required_params @required_params = [] end - - def check_file_extension - errors.add(:file, I18n.t('shared.file_processor.incorrect_file_type')) unless file.ext == 'csv' - end end end diff --git a/lib/csv2db.rb b/lib/csv2db.rb index 727c232..07a90d6 100644 --- a/lib/csv2db.rb +++ b/lib/csv2db.rb @@ -1,8 +1,18 @@ require 'csv2db/version' +require 'csv2db/config' module Csv2db class Error < StandardError; end - # Your code goes here... + + class << self + def config + Config.instance + end + + def configure + yield(config) + end + end end require 'csv2db/rails' if defined?(Rails) diff --git a/lib/csv2db/config.rb b/lib/csv2db/config.rb new file mode 100644 index 0000000..4930044 --- /dev/null +++ b/lib/csv2db/config.rb @@ -0,0 +1,13 @@ +require 'singleton' + +module Csv2db + class Config + include Singleton + + attr_writer :storage_adapter + + def storage_adapter + @storage_adapter ||= 'Dragonfly' + end + end +end From 257e5faa7f2560279351679645cb9663a009c35f Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Thu, 15 May 2025 17:45:26 +0100 Subject: [PATCH 12/28] REW-2045 - requires AS and Dragonfly adapters in spec helper --- spec/spec_helper.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 27530a3..0050175 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -6,6 +6,8 @@ require 'csv2db' require_relative '../app/models/concerns/csv2db/import' require_relative '../app/workers/csv2db/import_worker' +require_relative '../app/models/concerns/csv2db/dragonfly_adapter' +require_relative '../app/models/concerns/csv2db/active_storage_adapter' ENV['RAILS_ENV'] ||= 'test' From b411e87085d2324a1d78d81d538806a5a6c13213 Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Fri, 16 May 2025 18:26:35 +0100 Subject: [PATCH 13/28] REW-2045 - Basic upload of a file processor now in place Adds logic to ActiveStorageAdapter to handle uploading of CSV's (override file= method and save the uploaded tempfile using AS) Adds logic to parse AS uploaded file as CSV, handles byte order marking as users could still upload a file with a BOM. Moves out file_data method to each adapter Tweak check_file_contains_data method to check headers and count are present rather than checking data is inside csv (plays nicer with AS) Adds some temporary conditional logic to import table to show URL only if dragonfly (AS will be added at a later date) Adds StringEnquirer to storage_adapter config method --- .../concerns/csv2db/controller_helpers.rb | 2 +- .../concerns/csv2db/active_storage_adapter.rb | 26 +++++++++++++++++++ .../concerns/csv2db/dragonfly_adapter.rb | 9 ++++++- app/models/concerns/csv2db/import.rb | 20 +++++++------- app/views/csv2db/_csv_import_table.html.haml | 5 +++- lib/csv2db/config.rb | 3 ++- 6 files changed, 51 insertions(+), 14 deletions(-) diff --git a/app/controllers/concerns/csv2db/controller_helpers.rb b/app/controllers/concerns/csv2db/controller_helpers.rb index 4c9b07a..ad34ebb 100644 --- a/app/controllers/concerns/csv2db/controller_helpers.rb +++ b/app/controllers/concerns/csv2db/controller_helpers.rb @@ -36,7 +36,7 @@ def enqueue_csv_import_and_redirect(klass, options = {}, &block) end def enqueue_csv_import(klass, options = {}) - permitted_params = options.fetch(:params) do + permitted_params = options.fetch(:params) do params.require(klass.model_name.param_key).permit( :file, *options[:extra_params] diff --git a/app/models/concerns/csv2db/active_storage_adapter.rb b/app/models/concerns/csv2db/active_storage_adapter.rb index ac94f7a..184a94a 100644 --- a/app/models/concerns/csv2db/active_storage_adapter.rb +++ b/app/models/concerns/csv2db/active_storage_adapter.rb @@ -1,7 +1,33 @@ module Csv2db::ActiveStorageAdapter extend ActiveSupport::Concern + FILE_TYPE = 'text/csv'.freeze + included do has_one_attached :csv_upload end + + def file=(file) + # Override Dragonfly setter method + csv_upload.attach( + io: file.tempfile, + filename: file.original_filename, + content_type: FILE_TYPE + ) + end + + private + + def file_data + return @file_data if @file_data.present? + + csv_upload.blob.open do |blob| + @file_data = str_to_utf8(blob.read) + end + + byte_order_mark = Csv2db::Import::BYTE_ORDER_MARK + @file_data.sub!(byte_order_mark, '') if @file_data.starts_with?(byte_order_mark) + + @file_data + end end diff --git a/app/models/concerns/csv2db/dragonfly_adapter.rb b/app/models/concerns/csv2db/dragonfly_adapter.rb index 44ae1d9..d2a1f48 100644 --- a/app/models/concerns/csv2db/dragonfly_adapter.rb +++ b/app/models/concerns/csv2db/dragonfly_adapter.rb @@ -7,12 +7,19 @@ module Csv2db::DragonflyAdapter dragonfly_accessor :file - validate :check_file_extension validates :file, presence: true + validate :check_file_extension end def check_file_extension # very basic check of file extension errors.add(:file, I18n.t('shared.file_processor.incorrect_file_type')) unless file.ext == 'csv' end + + def file_data + file_data = str_to_utf8(file.data) + byte_order_mark = Csv2db::Import::BYTE_ORDER_MARK + file_data.sub!(byte_order_mark, '') if file_data.starts_with?(byte_order_mark) + file_data + end end diff --git a/app/models/concerns/csv2db/import.rb b/app/models/concerns/csv2db/import.rb index 2922aea..8584a94 100644 --- a/app/models/concerns/csv2db/import.rb +++ b/app/models/concerns/csv2db/import.rb @@ -27,7 +27,7 @@ def around_process(*args, &block) end included do - include Module.const_get("Csv2db::#{Csv2db.config.storage_adapter}Adapter") + include Module.const_get("Csv2db::#{Csv2db.config.storage_adapter.camelize.constantize}Adapter") validate :required_params_are_present @@ -127,7 +127,7 @@ def method_missing(method, *args, &block) private def check_file_contains_data - error(I18n.t('shared.file_processor.insufficient_rows')) unless file.data.present? && csv.count > 0 + error(I18n.t('shared.file_processor.insufficient_rows')) unless csv.headers.present? && csv.count.positive? stop if errors? end @@ -161,12 +161,6 @@ def csv @csv ||= CSV.parse(file_data, headers: true) end - def file_data - file_data = str_to_utf_8(file.data) - file_data.sub!(BYTE_ORDER_MARK, '') if file_data.starts_with?(BYTE_ORDER_MARK) - file_data - end - def required_params_are_present return if @required_params.empty? @@ -179,7 +173,7 @@ def required_params_are_present end def log(message, level = :info) - log_messages << { message: str_to_utf_8(message), level: level, time: Time.now } + log_messages << { message: str_to_utf8(message), level: level, time: Time.now } end def error(message) @@ -199,10 +193,16 @@ def set_default_values self.status ||= Status::PENDING end - def str_to_utf_8(str) + def str_to_utf8(str) + return if str_encoding(str) == 'UTF-8' + CharlockHolmes::Converter.convert(str, str.detect_encoding[:encoding], 'UTF-8') end + def str_encoding(str) + str.detect_encoding[:encoding] + end + def set_required_params @required_params = [] end diff --git a/app/views/csv2db/_csv_import_table.html.haml b/app/views/csv2db/_csv_import_table.html.haml index df87f42..ab3b758 100644 --- a/app/views/csv2db/_csv_import_table.html.haml +++ b/app/views/csv2db/_csv_import_table.html.haml @@ -15,7 +15,10 @@ %tr %td= import.id %td= import.created_at - %td= link_to import.file.name, import.file.url, target: '_blank' + - if Csv2db.config.storage_adapter.dragonfly? + %td= link_to import.file.name, import.file.url, target: '_blank' + - else + %td No File Yet %td .badge{ class: "badge-upload-#{import.status}" }= import.status %td diff --git a/lib/csv2db/config.rb b/lib/csv2db/config.rb index 4930044..aa64e0a 100644 --- a/lib/csv2db/config.rb +++ b/lib/csv2db/config.rb @@ -7,7 +7,8 @@ class Config attr_writer :storage_adapter def storage_adapter - @storage_adapter ||= 'Dragonfly' + @storage_adapter ||= :dragonfly + ActiveSupport::StringInquirer.new(@storage_adapter.to_s) end end end From 60ce0cae89df966033e9c3ce95b4e71bb46c7e44 Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Mon, 19 May 2025 16:10:47 +0100 Subject: [PATCH 14/28] REW-2045 - return str and not nil if string is UTF8 already ( was causing spec failures) --- app/models/concerns/csv2db/import.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/concerns/csv2db/import.rb b/app/models/concerns/csv2db/import.rb index 8584a94..99d3a9a 100644 --- a/app/models/concerns/csv2db/import.rb +++ b/app/models/concerns/csv2db/import.rb @@ -194,9 +194,9 @@ def set_default_values end def str_to_utf8(str) - return if str_encoding(str) == 'UTF-8' + return str if str_encoding(str) == 'UTF-8' - CharlockHolmes::Converter.convert(str, str.detect_encoding[:encoding], 'UTF-8') + CharlockHolmes::Converter.convert(str, str_encoding(str), 'UTF-8') end def str_encoding(str) From 4a1a655501c50a939e307195e55d19e542e968ed Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Tue, 20 May 2025 09:44:22 +0100 Subject: [PATCH 15/28] REW-2045 - always encode strings in csv2db/import.rb --- app/models/concerns/csv2db/import.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/concerns/csv2db/import.rb b/app/models/concerns/csv2db/import.rb index 99d3a9a..d2ae8a9 100644 --- a/app/models/concerns/csv2db/import.rb +++ b/app/models/concerns/csv2db/import.rb @@ -194,7 +194,6 @@ def set_default_values end def str_to_utf8(str) - return str if str_encoding(str) == 'UTF-8' CharlockHolmes::Converter.convert(str, str_encoding(str), 'UTF-8') end From c2ba05cbea148c1069cfb46e21a3030642486d54 Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Tue, 20 May 2025 22:25:36 +0100 Subject: [PATCH 16/28] REW-2045 - adds back in base check of file extension --- app/models/concerns/csv2db/active_storage_adapter.rb | 10 ++++++++-- app/models/concerns/csv2db/import.rb | 1 - 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/models/concerns/csv2db/active_storage_adapter.rb b/app/models/concerns/csv2db/active_storage_adapter.rb index 184a94a..079592f 100644 --- a/app/models/concerns/csv2db/active_storage_adapter.rb +++ b/app/models/concerns/csv2db/active_storage_adapter.rb @@ -1,10 +1,11 @@ module Csv2db::ActiveStorageAdapter extend ActiveSupport::Concern - FILE_TYPE = 'text/csv'.freeze included do has_one_attached :csv_upload + + validate :check_file_extension end def file=(file) @@ -12,12 +13,17 @@ def file=(file) csv_upload.attach( io: file.tempfile, filename: file.original_filename, - content_type: FILE_TYPE + content_type: file.content_type ) end private + def check_file_extension + # very basic check of file extension + errors.add(:file, I18n.t('shared.file_processor.incorrect_file_type')) unless csv_upload.blob.content_type == FILE_TYPE + end + def file_data return @file_data if @file_data.present? diff --git a/app/models/concerns/csv2db/import.rb b/app/models/concerns/csv2db/import.rb index d2ae8a9..6963b90 100644 --- a/app/models/concerns/csv2db/import.rb +++ b/app/models/concerns/csv2db/import.rb @@ -194,7 +194,6 @@ def set_default_values end def str_to_utf8(str) - CharlockHolmes::Converter.convert(str, str_encoding(str), 'UTF-8') end From d1fd92293fe1427edff1e1c07c224e95f0f9bfa3 Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Wed, 21 May 2025 16:57:40 +0100 Subject: [PATCH 17/28] REW-2045 - use File.open(file) instead of file.tempfile as was causing ActiveStorage Integrity errors --- app/models/concerns/csv2db/active_storage_adapter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/concerns/csv2db/active_storage_adapter.rb b/app/models/concerns/csv2db/active_storage_adapter.rb index 079592f..ba02952 100644 --- a/app/models/concerns/csv2db/active_storage_adapter.rb +++ b/app/models/concerns/csv2db/active_storage_adapter.rb @@ -11,7 +11,7 @@ module Csv2db::ActiveStorageAdapter def file=(file) # Override Dragonfly setter method csv_upload.attach( - io: file.tempfile, + io: File.open(file), filename: file.original_filename, content_type: file.content_type ) From 8c7fe934fa5c99277e95f9d11fefa81ac5995f65 Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Thu, 22 May 2025 14:36:06 +0100 Subject: [PATCH 18/28] REW-2045 - adds local_storage_host config option to csv2db gem --- lib/csv2db/config.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/csv2db/config.rb b/lib/csv2db/config.rb index aa64e0a..fbc3f2d 100644 --- a/lib/csv2db/config.rb +++ b/lib/csv2db/config.rb @@ -4,11 +4,15 @@ module Csv2db class Config include Singleton - attr_writer :storage_adapter + attr_writer :storage_adapter, :local_storage_host def storage_adapter @storage_adapter ||= :dragonfly ActiveSupport::StringInquirer.new(@storage_adapter.to_s) end + + def local_storage_host + @local_storage_host ||= '' + end end end From 9fe686fbce1e059b5c404ec81184517e70903808 Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Thu, 22 May 2025 16:26:52 +0100 Subject: [PATCH 19/28] REW-2045 - implement expiring link method and use on downloads table --- .../concerns/csv2db/active_storage_adapter.rb | 22 ++++++++++++++++++- app/views/csv2db/_csv_import_table.html.haml | 2 +- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/app/models/concerns/csv2db/active_storage_adapter.rb b/app/models/concerns/csv2db/active_storage_adapter.rb index ba02952..7a5dfb1 100644 --- a/app/models/concerns/csv2db/active_storage_adapter.rb +++ b/app/models/concerns/csv2db/active_storage_adapter.rb @@ -1,6 +1,7 @@ module Csv2db::ActiveStorageAdapter extend ActiveSupport::Concern FILE_TYPE = 'text/csv'.freeze + MAX_EXPIRY = 7.days.to_s.freeze included do has_one_attached :csv_upload @@ -10,15 +11,34 @@ module Csv2db::ActiveStorageAdapter def file=(file) # Override Dragonfly setter method + + filename = file.original_filename + csv_upload.attach( io: File.open(file), - filename: file.original_filename, + filename: filename, content_type: file.content_type ) + + self.file_name = filename + end + + def expiring_link(expires_in: MAX_EXPIRY) + return unless csv_upload.present? + + set_current_host_if_local + + csv_upload.service_url(expires_in: expires_in.to_i, disposition: 'attachment') end private + def set_current_host_if_local + return unless Rails.application.config.active_storage.service == :local + + ActiveStorage::Current.host = ReportGenerator.config.local_storage_host + end + def check_file_extension # very basic check of file extension errors.add(:file, I18n.t('shared.file_processor.incorrect_file_type')) unless csv_upload.blob.content_type == FILE_TYPE diff --git a/app/views/csv2db/_csv_import_table.html.haml b/app/views/csv2db/_csv_import_table.html.haml index ab3b758..a07a9e2 100644 --- a/app/views/csv2db/_csv_import_table.html.haml +++ b/app/views/csv2db/_csv_import_table.html.haml @@ -18,7 +18,7 @@ - if Csv2db.config.storage_adapter.dragonfly? %td= link_to import.file.name, import.file.url, target: '_blank' - else - %td No File Yet + %td= link_to import.file_name, import.expiring_link %td .badge{ class: "badge-upload-#{import.status}" }= import.status %td From dcb2076ca0a6d21d4664e522f7f479b8991cb639 Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Fri, 23 May 2025 00:01:12 +0100 Subject: [PATCH 20/28] REW-2045 - adds specs to gem base model --- .../concerns/csv2db/active_storage_adapter.rb | 3 ++ spec/models/concerns/csv2db/import_spec.rb | 38 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/app/models/concerns/csv2db/active_storage_adapter.rb b/app/models/concerns/csv2db/active_storage_adapter.rb index 7a5dfb1..cfa385d 100644 --- a/app/models/concerns/csv2db/active_storage_adapter.rb +++ b/app/models/concerns/csv2db/active_storage_adapter.rb @@ -1,4 +1,6 @@ module Csv2db::ActiveStorageAdapter + require 'active_support/all' + extend ActiveSupport::Concern FILE_TYPE = 'text/csv'.freeze MAX_EXPIRY = 7.days.to_s.freeze @@ -11,6 +13,7 @@ module Csv2db::ActiveStorageAdapter def file=(file) # Override Dragonfly setter method + return unless file.present? filename = file.original_filename diff --git a/spec/models/concerns/csv2db/import_spec.rb b/spec/models/concerns/csv2db/import_spec.rb index 64a43ed..ea6e6eb 100644 --- a/spec/models/concerns/csv2db/import_spec.rb +++ b/spec/models/concerns/csv2db/import_spec.rb @@ -104,4 +104,42 @@ class TestModel < ActiveRecord::Base expect(subject.errors?).to be_truthy end end + + context 'ActiveStorageAdapter' do + let(:file) do + Rack::Test::UploadedFile.new(Tempfile.new) + end + + let(:attachment_spy) do + spy('csv_upload') + end + + subject do + TestModel.new + end + + before do + allow(TestModel).to receive(:has_one_attached) + TestModel.include(Csv2db::ActiveStorageAdapter) + allow(subject).to receive(:csv_upload).and_return(attachment_spy) + end + + it 'calls correct attach methods' do + expect(file).to receive(:original_filename) + expect(file).to receive(:content_type) + expect(attachment_spy).to receive(:attach) + + subject.file = file + end + + it 'sets the file_name on the model' do + subject.file = file + + expect(subject.file_name).to eq(file.original_filename) + end + + it 'returns nil if no file passed' do + expect(subject.file = nil).to eq(nil) + end + end end From 8a3fa9b7db2f8eb4ac220e930dad06215b7d81e4 Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Fri, 23 May 2025 07:05:06 +0100 Subject: [PATCH 21/28] REW-2045 - update set_current_host method to include test environment Allow name of attachment to be dynamically set using config file --- .../concerns/csv2db/active_storage_adapter.rb | 20 ++++++++++--------- lib/csv2db/config.rb | 6 +++++- spec/models/concerns/csv2db/import_spec.rb | 4 ++-- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/app/models/concerns/csv2db/active_storage_adapter.rb b/app/models/concerns/csv2db/active_storage_adapter.rb index cfa385d..285c357 100644 --- a/app/models/concerns/csv2db/active_storage_adapter.rb +++ b/app/models/concerns/csv2db/active_storage_adapter.rb @@ -6,9 +6,11 @@ module Csv2db::ActiveStorageAdapter MAX_EXPIRY = 7.days.to_s.freeze included do - has_one_attached :csv_upload + has_one_attached Csv2db.config.file_attachment_name validate :check_file_extension + + alias_method :file_attachment, Csv2db.config.file_attachment_name end def file=(file) @@ -17,7 +19,7 @@ def file=(file) filename = file.original_filename - csv_upload.attach( + file_attachment.attach( io: File.open(file), filename: filename, content_type: file.content_type @@ -27,30 +29,30 @@ def file=(file) end def expiring_link(expires_in: MAX_EXPIRY) - return unless csv_upload.present? + return unless file_attachment.present? - set_current_host_if_local + set_current_host - csv_upload.service_url(expires_in: expires_in.to_i, disposition: 'attachment') + file_attachment.service_url(expires_in: expires_in.to_i, disposition: 'attachment') end private - def set_current_host_if_local - return unless Rails.application.config.active_storage.service == :local + def set_current_host + return unless %i[test local].include?(Rails.application.config.active_storage.service) ActiveStorage::Current.host = ReportGenerator.config.local_storage_host end def check_file_extension # very basic check of file extension - errors.add(:file, I18n.t('shared.file_processor.incorrect_file_type')) unless csv_upload.blob.content_type == FILE_TYPE + errors.add(:file, I18n.t('shared.file_processor.incorrect_file_type')) unless file_attachment.blob.content_type == FILE_TYPE end def file_data return @file_data if @file_data.present? - csv_upload.blob.open do |blob| + file_attachment.blob.open do |blob| @file_data = str_to_utf8(blob.read) end diff --git a/lib/csv2db/config.rb b/lib/csv2db/config.rb index fbc3f2d..3b7611b 100644 --- a/lib/csv2db/config.rb +++ b/lib/csv2db/config.rb @@ -4,7 +4,7 @@ module Csv2db class Config include Singleton - attr_writer :storage_adapter, :local_storage_host + attr_writer :storage_adapter, :local_storage_host, :file_attachment_name def storage_adapter @storage_adapter ||= :dragonfly @@ -14,5 +14,9 @@ def storage_adapter def local_storage_host @local_storage_host ||= '' end + + def file_attachment_name + @file_attachment_name ||= :csv_attachment + end end end diff --git a/spec/models/concerns/csv2db/import_spec.rb b/spec/models/concerns/csv2db/import_spec.rb index ea6e6eb..cb311b6 100644 --- a/spec/models/concerns/csv2db/import_spec.rb +++ b/spec/models/concerns/csv2db/import_spec.rb @@ -111,7 +111,7 @@ class TestModel < ActiveRecord::Base end let(:attachment_spy) do - spy('csv_upload') + spy('file_attachment') end subject do @@ -121,7 +121,7 @@ class TestModel < ActiveRecord::Base before do allow(TestModel).to receive(:has_one_attached) TestModel.include(Csv2db::ActiveStorageAdapter) - allow(subject).to receive(:csv_upload).and_return(attachment_spy) + allow(subject).to receive(:file_attachment).and_return(attachment_spy) end it 'calls correct attach methods' do From 4a9a7ce0e5648397bc63205069ef509338cb0d85 Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Fri, 23 May 2025 07:34:45 +0100 Subject: [PATCH 22/28] REW-2045 - fixes failing spec due to alias_method --- lib/csv2db/config.rb | 2 +- spec/models/concerns/csv2db/import_spec.rb | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/csv2db/config.rb b/lib/csv2db/config.rb index 3b7611b..960c78a 100644 --- a/lib/csv2db/config.rb +++ b/lib/csv2db/config.rb @@ -16,7 +16,7 @@ def local_storage_host end def file_attachment_name - @file_attachment_name ||= :csv_attachment + @file_attachment_name ||= :file_attachment end end end diff --git a/spec/models/concerns/csv2db/import_spec.rb b/spec/models/concerns/csv2db/import_spec.rb index cb311b6..2b43bbd 100644 --- a/spec/models/concerns/csv2db/import_spec.rb +++ b/spec/models/concerns/csv2db/import_spec.rb @@ -120,6 +120,8 @@ class TestModel < ActiveRecord::Base before do allow(TestModel).to receive(:has_one_attached) + allow(TestModel).to receive(:alias_method) + .with(:file_attachment, :file_attachment).and_return(nil) TestModel.include(Csv2db::ActiveStorageAdapter) allow(subject).to receive(:file_attachment).and_return(attachment_spy) end From 045e4e260d1ee6b376c8694abc970b4271b17a88 Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Fri, 23 May 2025 11:03:20 +0100 Subject: [PATCH 23/28] REW-2045 - adds responds to missing method into csv2db gem --- app/models/concerns/csv2db/import.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/models/concerns/csv2db/import.rb b/app/models/concerns/csv2db/import.rb index 6963b90..5d4f26a 100644 --- a/app/models/concerns/csv2db/import.rb +++ b/app/models/concerns/csv2db/import.rb @@ -124,6 +124,10 @@ def method_missing(method, *args, &block) end end + def respond_to_missing?(method, include_private = false) + method.to_s.start_with?('param_') || super + end + private def check_file_contains_data From 0b70347ba7fc5121cb086068ee52682549897b9b Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Fri, 23 May 2025 11:28:54 +0100 Subject: [PATCH 24/28] REW-2045 - rename MAX_EXPIRY to LINK_MAX_EXPIRY --- app/models/concerns/csv2db/active_storage_adapter.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/concerns/csv2db/active_storage_adapter.rb b/app/models/concerns/csv2db/active_storage_adapter.rb index 285c357..4dfc152 100644 --- a/app/models/concerns/csv2db/active_storage_adapter.rb +++ b/app/models/concerns/csv2db/active_storage_adapter.rb @@ -3,7 +3,7 @@ module Csv2db::ActiveStorageAdapter extend ActiveSupport::Concern FILE_TYPE = 'text/csv'.freeze - MAX_EXPIRY = 7.days.to_s.freeze + LINK_MAX_EXPIRY = 7.days.to_s.freeze included do has_one_attached Csv2db.config.file_attachment_name @@ -28,7 +28,7 @@ def file=(file) self.file_name = filename end - def expiring_link(expires_in: MAX_EXPIRY) + def expiring_link(expires_in: LINK_MAX_EXPIRY) return unless file_attachment.present? set_current_host From e403294fd487ce7fa060ed6334a7ff1bbb97e1b1 Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Fri, 23 May 2025 11:43:55 +0100 Subject: [PATCH 25/28] REW-2045 - adds private keyword to dragonfly adapter --- app/models/concerns/csv2db/dragonfly_adapter.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/concerns/csv2db/dragonfly_adapter.rb b/app/models/concerns/csv2db/dragonfly_adapter.rb index d2a1f48..4f588e1 100644 --- a/app/models/concerns/csv2db/dragonfly_adapter.rb +++ b/app/models/concerns/csv2db/dragonfly_adapter.rb @@ -11,6 +11,8 @@ module Csv2db::DragonflyAdapter validate :check_file_extension end + private + def check_file_extension # very basic check of file extension errors.add(:file, I18n.t('shared.file_processor.incorrect_file_type')) unless file.ext == 'csv' From 6d94812259c150dbfa0d1d7544b6c61899092b5e Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Sat, 24 May 2025 13:02:30 +0100 Subject: [PATCH 26/28] REW-2045 - switch round if statement logic --- app/views/csv2db/_csv_import_table.html.haml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/csv2db/_csv_import_table.html.haml b/app/views/csv2db/_csv_import_table.html.haml index a07a9e2..acc0bcc 100644 --- a/app/views/csv2db/_csv_import_table.html.haml +++ b/app/views/csv2db/_csv_import_table.html.haml @@ -15,10 +15,10 @@ %tr %td= import.id %td= import.created_at - - if Csv2db.config.storage_adapter.dragonfly? - %td= link_to import.file.name, import.file.url, target: '_blank' - - else + - if Csv2db.config.storage_adapter.active_storage? %td= link_to import.file_name, import.expiring_link + - else + %td= link_to import.file.name, import.file.url, target: '_blank' %td .badge{ class: "badge-upload-#{import.status}" }= import.status %td From c170ac0c5bd7ea6213a6c4cf93c8f9a9180df5f2 Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Fri, 6 Jun 2025 15:09:33 +0100 Subject: [PATCH 27/28] REW-2045 - rename expiring_link method to download_link (can then be over-ridden in MyRew) Correct typo --- app/models/concerns/csv2db/active_storage_adapter.rb | 4 ++-- app/views/csv2db/_csv_import_table.html.haml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/concerns/csv2db/active_storage_adapter.rb b/app/models/concerns/csv2db/active_storage_adapter.rb index 4dfc152..2b89cd6 100644 --- a/app/models/concerns/csv2db/active_storage_adapter.rb +++ b/app/models/concerns/csv2db/active_storage_adapter.rb @@ -28,7 +28,7 @@ def file=(file) self.file_name = filename end - def expiring_link(expires_in: LINK_MAX_EXPIRY) + def download_link(expires_in: LINK_MAX_EXPIRY) return unless file_attachment.present? set_current_host @@ -41,7 +41,7 @@ def expiring_link(expires_in: LINK_MAX_EXPIRY) def set_current_host return unless %i[test local].include?(Rails.application.config.active_storage.service) - ActiveStorage::Current.host = ReportGenerator.config.local_storage_host + ActiveStorage::Current.host = Csv2db.config.local_storage_host end def check_file_extension diff --git a/app/views/csv2db/_csv_import_table.html.haml b/app/views/csv2db/_csv_import_table.html.haml index acc0bcc..761eb89 100644 --- a/app/views/csv2db/_csv_import_table.html.haml +++ b/app/views/csv2db/_csv_import_table.html.haml @@ -16,7 +16,7 @@ %td= import.id %td= import.created_at - if Csv2db.config.storage_adapter.active_storage? - %td= link_to import.file_name, import.expiring_link + %td= link_to import.file_name, import.download_link - else %td= link_to import.file.name, import.file.url, target: '_blank' %td From 031fa7ced7bd2aa5143b2cb16db9517d23be1841 Mon Sep 17 00:00:00 2001 From: Reiss Johnson Date: Tue, 10 Jun 2025 09:41:46 +0100 Subject: [PATCH 28/28] REW-2045 - adds download_link method for dragonfly adapter and use this method on import table, this method can then be overwritten in file processor model's so custom logic can be added. --- app/models/concerns/csv2db/active_storage_adapter.rb | 9 ++++++--- app/models/concerns/csv2db/dragonfly_adapter.rb | 4 ++++ app/views/csv2db/_csv_import_table.html.haml | 5 +---- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/models/concerns/csv2db/active_storage_adapter.rb b/app/models/concerns/csv2db/active_storage_adapter.rb index 2b89cd6..993ccfe 100644 --- a/app/models/concerns/csv2db/active_storage_adapter.rb +++ b/app/models/concerns/csv2db/active_storage_adapter.rb @@ -28,12 +28,15 @@ def file=(file) self.file_name = filename end - def download_link(expires_in: LINK_MAX_EXPIRY) - return unless file_attachment.present? + def download_link + return unless file_attachment.present? && file_attachment.attached? set_current_host - file_attachment.service_url(expires_in: expires_in.to_i, disposition: 'attachment') + file_attachment.service_url( + expires_in: LINK_MAX_EXPIRY.to_i, + disposition: 'attachment' + ) end private diff --git a/app/models/concerns/csv2db/dragonfly_adapter.rb b/app/models/concerns/csv2db/dragonfly_adapter.rb index 4f588e1..f17fc71 100644 --- a/app/models/concerns/csv2db/dragonfly_adapter.rb +++ b/app/models/concerns/csv2db/dragonfly_adapter.rb @@ -11,6 +11,10 @@ module Csv2db::DragonflyAdapter validate :check_file_extension end + def download_link + file.url + end + private def check_file_extension diff --git a/app/views/csv2db/_csv_import_table.html.haml b/app/views/csv2db/_csv_import_table.html.haml index 761eb89..9db07f4 100644 --- a/app/views/csv2db/_csv_import_table.html.haml +++ b/app/views/csv2db/_csv_import_table.html.haml @@ -15,10 +15,7 @@ %tr %td= import.id %td= import.created_at - - if Csv2db.config.storage_adapter.active_storage? - %td= link_to import.file_name, import.download_link - - else - %td= link_to import.file.name, import.file.url, target: '_blank' + %td= link_to(import.file_name, import.download_link) %td .badge{ class: "badge-upload-#{import.status}" }= import.status %td