From a9d56cb202772eecaebb52cae7b031674be34c22 Mon Sep 17 00:00:00 2001 From: Warren Huang Date: Mon, 4 Mar 2024 17:08:59 -0800 Subject: [PATCH 1/4] Update the mass load to .csv restrict --- .../admin/commercials_controller.rb | 2 +- app/models/commercial.rb | 24 ++++++++++++++----- app/views/admin/events/index.html.haml | 8 +++---- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/app/controllers/admin/commercials_controller.rb b/app/controllers/admin/commercials_controller.rb index 073e135e4..ee4e07eee 100644 --- a/app/controllers/admin/commercials_controller.rb +++ b/app/controllers/admin/commercials_controller.rb @@ -55,7 +55,7 @@ def render_commercial # Received a file from user # Reads file and creates commercial for event # File content example: - # EventID:MyURL + # EventID, Title, URL def mass_upload errors = Commercial.read_file(params[:file]) if params[:file] diff --git a/app/models/commercial.rb b/app/models/commercial.rb index d5ac9a463..5e6deb75f 100644 --- a/app/models/commercial.rb +++ b/app/models/commercial.rb @@ -46,17 +46,29 @@ def self.read_file(file) errors[:no_event] = [] errors[:validation_errors] = [] + # Check if the file has a .csv extension + unless File.extname(file.original_filename).casecmp('.csv').zero? + errors[:validation_errors] << 'File must be a CSV.' + return errors + end + file.read.each_line do |line| - # Get the event id (text before :) - id = line.match(/:/).pre_match.to_i - # Get the commercial url (text after :) - url = line.match(/:/).post_match + # Split the line by comma + elements = line.strip.split(',') + id, title, url = elements[0].to_i, elements[1], elements[2] + + # Validate presence of all parts + if elements.size != 3 + errors[:validation_errors] << "Line format is incorrect. Should be ID, Title, URL." + next + end + event = Event.find_by(id: id) - # Go to next event, if the event is not found + # Go to next event if the event is not found (errors[:no_event] << id) && next unless event - commercial = event.commercials.new(url: url) + commercial = event.commercials.new(title: title, url: url) unless commercial.save errors[:validation_errors] << ("Could not create materials for event with ID #{event.id} (" + commercial.errors.full_messages.to_sentence + ')') end diff --git a/app/views/admin/events/index.html.haml b/app/views/admin/events/index.html.haml index 46429af29..2fe477909 100644 --- a/app/views/admin/events/index.html.haml +++ b/app/views/admin/events/index.html.haml @@ -35,12 +35,12 @@ .form-group = f.file_field 'file', as: :file %span.help-block - Upload your file with data in the following format: - %b Event_ID:Commercial_Link + Upload your file.csv with data in the following format: + %b Event_ID, Title, Commercial_Link for instance: %pre - 11:https://youtube.com/myvideo - 23:https://vimeo.com/myvideo + 1, title, https://youtube.com/myvideo + 2, title, https://vimeo.com/myvideo .modal-footer = f.submit nil, class: 'btn btn-primary' .row From e3819e8bc371eb7554664cd984d2f8a1f34094dc Mon Sep 17 00:00:00 2001 From: Warren Huang Date: Sun, 10 Mar 2024 15:08:52 -0700 Subject: [PATCH 2/4] Update mass upload to use csv parser --- app/models/commercial.rb | 18 ++++++++---------- app/views/admin/events/index.html.haml | 7 ++++--- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/app/models/commercial.rb b/app/models/commercial.rb index 5e6deb75f..fd55c3589 100644 --- a/app/models/commercial.rb +++ b/app/models/commercial.rb @@ -14,6 +14,9 @@ # commercial_id :string # commercialable_id :integer # +require 'csv' + + class Commercial < ApplicationRecord require 'oembed' @@ -52,16 +55,11 @@ def self.read_file(file) return errors end - file.read.each_line do |line| - # Split the line by comma - elements = line.strip.split(',') - id, title, url = elements[0].to_i, elements[1], elements[2] - - # Validate presence of all parts - if elements.size != 3 - errors[:validation_errors] << "Line format is incorrect. Should be ID, Title, URL." - next - end + CSV.foreach(file.path, headers: true) do |row| + # You can access columns by their names if headers are included in the file + id = row['Event_ID'].to_i + title = row['Title'] + url = row['URL'] event = Event.find_by(id: id) diff --git a/app/views/admin/events/index.html.haml b/app/views/admin/events/index.html.haml index 2fe477909..93c369c79 100644 --- a/app/views/admin/events/index.html.haml +++ b/app/views/admin/events/index.html.haml @@ -36,11 +36,12 @@ = f.file_field 'file', as: :file %span.help-block Upload your file.csv with data in the following format: - %b Event_ID, Title, Commercial_Link + %b Event_ID,Title,URL for instance: %pre - 1, title, https://youtube.com/myvideo - 2, title, https://vimeo.com/myvideo + Event_ID,Title,URL + 1,title,https://youtube.com/myvideo + 2,title,https://vimeo.com/myvideo .modal-footer = f.submit nil, class: 'btn btn-primary' .row From 853899564833b2a9f95c751220a6b5d0b6d44d8d Mon Sep 17 00:00:00 2001 From: Warren Huang Date: Mon, 18 Mar 2024 18:12:32 -0700 Subject: [PATCH 3/4] Handle 4 kbyte error cap for upload materias --- .../admin/commercials_controller.rb | 30 +++++++++++++------ app/models/commercial.rb | 1 - 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/app/controllers/admin/commercials_controller.rb b/app/controllers/admin/commercials_controller.rb index ee4e07eee..0b7c8af3f 100644 --- a/app/controllers/admin/commercials_controller.rb +++ b/app/controllers/admin/commercials_controller.rb @@ -61,22 +61,34 @@ def mass_upload if !params[:file] flash[:error] = 'Empty file detected while adding materials to Event' - elsif errors.all? { |_k, v| v.blank? } - flash[:notice] = 'Successfully added materials.' - else - errors_text = '' - errors_text += 'Unable to find event with ID: ' + errors[:no_event].join(', ') + '. ' if errors[:no_event].any? - if errors[:validation_errors].any? - errors_text += 'There were some errors: ' + errors[:validation_errors].join('. ') - end + elsif errors.present? + errors_text = aggregate_errors(errors) + flash[:notice] = if errors_text.length > 4096 + 'Errors are too long to be displayed. Please check the logs.' + else + errors_text + end - flash[:error] = errors_text + else + flash[:notice] = 'Successfully added materials.' end redirect_back(fallback_location: root_path) end private + # Aggregate errors and ensure that they do not exceed 4 KB in total size + def aggregate_errors(errors) + errors_text = '' + if errors[:no_event].any? + errors_text += 'Unable to find events with IDs: ' + errors[:no_event].join(', ') + '. ' + end + if errors[:validation_errors].any? + errors_text += 'Validation errors: ' + errors[:validation_errors].join('. ') + end + errors_text + end + def commercial_params params.require(:commercial).permit(:title, :url) end diff --git a/app/models/commercial.rb b/app/models/commercial.rb index fd55c3589..1fcc0a45a 100644 --- a/app/models/commercial.rb +++ b/app/models/commercial.rb @@ -16,7 +16,6 @@ # require 'csv' - class Commercial < ApplicationRecord require 'oembed' From b3543681df4e632dbc77b548d866ad498865405e Mon Sep 17 00:00:00 2001 From: Michael Ball Date: Thu, 4 Apr 2024 17:17:08 -0700 Subject: [PATCH 4/4] Minor tweak to example text --- app/views/admin/events/index.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/admin/events/index.html.haml b/app/views/admin/events/index.html.haml index 93c369c79..6f68faee1 100644 --- a/app/views/admin/events/index.html.haml +++ b/app/views/admin/events/index.html.haml @@ -40,8 +40,8 @@ for instance: %pre Event_ID,Title,URL - 1,title,https://youtube.com/myvideo - 2,title,https://vimeo.com/myvideo + 1,Session Recording,https://youtube.com/myvideo + 2,Demo Video,https://vimeo.com/myvideo .modal-footer = f.submit nil, class: 'btn btn-primary' .row