@@ -15,32 +15,23 @@ class SiteUpload
1515 ] . freeze
1616 MAX_FILE_SIZE = 5 . megabytes
1717 REQUIRED_HEADERS = [ "url" ] . freeze
18- SUPPORTED_SEPARATORS = [ "," , ";" ] . freeze
19- BOM = /^\xEF \xBB \xBF /
2018
21- attr_accessor :file , :team , :tag_ids , :tags , :new_sites , :existing_sites
19+ attr_accessor :file , :team , :tag_ids
2220
2321 validates :file , :team , presence : true
2422 validate :valid_file_size , :valid_file_format , :valid_headers , if : :file
2523
26- delegate :create! , :transaction , :human , to : :Site
27-
2824 def initialize ( attributes = { } )
2925 super
3026 @tag_ids ||= [ ]
31- @new_sites = { }
32- @existing_sites = { }
3327 end
3428
3529 def save
3630 return false unless valid?
31+ sites_data = parser . parse
3732
38- parse_sites
33+ ProcessSiteUploadJob . perform_later ( sites_data , team . id , tag_ids )
3934
40- transaction do
41- create! ( new_sites . values ) if new_sites . any?
42- existing_sites . values . each { |site | site . save && site . audit! }
43- end
4435 true
4536 end
4637
@@ -58,43 +49,13 @@ def assign_attributes(attributes)
5849 end
5950
6051 def count
61- ( new_sites &.length || 0 ) + ( existing_sites &.length || 0 )
62- end
63-
64- def parse_sites
65- require "csv"
66-
67- CSV . foreach ( file . path , headers : true , encoding : "bom|utf-8" , col_sep :) do |row |
68- row = row . to_h . transform_keys { |header | header . to_s . downcase } # Case-insensitive headers
69-
70- url = Link . normalize ( row [ "url" ] )
71- name = row [ "nom" ] || row [ "name" ]
72- tag_names = row [ "tags" ] . present? ? row [ "tags" ] . split ( "," ) . map ( &:strip ) . compact_blank . uniq : [ ]
73-
74- row_tag_ids = tag_names . map { |n | team . tags . find_or_create_by ( name : n ) . id }
75- combined_tag_ids = ( tag_ids + row_tag_ids ) . uniq
76- existing_site = team . sites . find_by_url ( url :)
77-
78- if existing_site
79- existing_site . assign_attributes ( tag_ids : combined_tag_ids . union ( existing_site . tag_ids ) )
80- existing_site . assign_attributes ( name :) unless existing_site . name
81- self . existing_sites [ url ] = existing_site
82- else
83- self . new_sites [ url ] = { url :, team :, name :, tag_ids : combined_tag_ids }
84- end
85- end
52+ file ? parser . count : 0
8653 end
8754
8855 private
8956
90- def first_line
91- @first_line ||= File . open ( file . path , &:gets ) &.strip &.sub ( BOM , "" ) || ""
92- end
93-
94- def col_sep
95- SUPPORTED_SEPARATORS . max_by { |sep | first_line . count ( sep ) }
96- rescue StandardError
97- SUPPORTED_SEPARATORS . first
57+ def parser
58+ @parser ||= CsvSiteParser . new ( file )
9859 end
9960
10061 def valid_file_size
@@ -107,10 +68,7 @@ def valid_file_format
10768 end
10869
10970 def valid_headers
110- headers = CSV . parse_line ( first_line , col_sep :) || [ ]
111- missing_headers = REQUIRED_HEADERS - headers . compact . collect ( &:downcase )
71+ missing_headers = REQUIRED_HEADERS - parser . headers
11272 errors . add ( :file , :invalid_headers ) unless missing_headers . empty?
113- rescue CSV ::MalformedCSVError , StandardError
114- errors . add ( :file , :invalid_headers )
11573 end
11674end
0 commit comments