eco-helpers 3.2.12 → 3.2.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/eco/csv/split.rb CHANGED
@@ -3,14 +3,17 @@ module Eco
3
3
  class Split
4
4
  include Eco::Language::AuxiliarLogger
5
5
 
6
+ MAX_ROWS_DEFAULT = 1_000_000
7
+
6
8
  attr_reader :filename
7
9
 
8
- def initialize(filename, max_rows:, start_at: nil, **kargs)
10
+ def initialize(filename, max_rows: :unused, start_at: nil, **kargs)
9
11
  msg = "File '#{filename}' does not exist"
10
12
  raise ArgumentError, msg unless ::File.exist?(filename)
11
13
 
12
14
  @filename = filename
13
15
  @max_rows = max_rows
16
+ @max_rows = MAX_ROWS_DEFAULT if max_rows == :unused
14
17
  @start_at = start_at
15
18
  @params = kargs
16
19
 
@@ -34,16 +37,17 @@ module Eco
34
37
  @out_files ||= []
35
38
  end
36
39
 
37
- # @yield [idx, file] a block to spot the filename
40
+ # @yield [row, ridx, fidx, file] block to spot if the row should be included
38
41
  # @yieldparam idx [Integer] the number of the file
39
42
  # @yieldparam file [String] the default name of the file
40
- # @yieldreturn [String] the filename of the file `idx`.
41
- # - If `nil` it will create its own filename convention
43
+ # @yieldparam fidx [Integer] the number of the file
44
+ # @yieldparam file [String] the default name of the file
45
+ # @yieldreturn [Bollean] whether the row should be included
42
46
  # @return [Array<String>] names of the generated files
43
- def call(&block)
47
+ def call(&filter)
44
48
  stream.for_each(start_at_idx: start_at) do |row, ridx|
45
49
  self.total_count += 1
46
- copy_row(row, ridx, &block)
50
+ copy_row(row, ridx, &filter)
47
51
  end
48
52
 
49
53
  out_files
@@ -56,33 +60,42 @@ module Eco
56
60
 
57
61
  attr_reader :params
58
62
  attr_reader :idx, :max_rows, :start_at
59
- attr_reader :headers, :row_idx
63
+ attr_reader :headers, :row_idx, :out_row_idx
64
+ attr_reader :last_cut_desc
60
65
 
61
66
  attr_accessor :exception
62
67
 
63
- def copy_row(row, ridx, &block)
68
+ def copy_row(row, ridx)
64
69
  @headers ||= row.headers
65
70
  @row_idx = ridx
66
71
 
67
- current_csv(ridx) do |csv, fidx, file_out|
72
+ current_csv(row) do |csv, fidx, file_out|
68
73
  included = true
69
- included &&= !block || yield(row, ridx, fidx, file_out)
74
+ included &&= yield(row, ridx, fidx, file_out) if block_given?
70
75
  next unless included
71
76
 
77
+ @out_row_idx += 1
72
78
  self.copy_count += 1
73
79
  csv << row.fields
74
80
  end
75
81
  end
76
82
 
77
- def current_csv(ridx)
78
- if split?(ridx) || @csv.nil?
79
- puts "Split at row #{row_idx}"
83
+ def current_csv(row)
84
+ if (cut = split?(row, &splitter)) || @csv.nil?
85
+ cut = nil if cut.is_a?(TrueClass) || cut.to_s.empty? || !cut
86
+ msg = "Split at row #{row_idx}"
87
+ msg << " (cut: #{cut})" unless cut.nil?
88
+ puts msg
89
+
90
+ @last_cut_desc = cut unless cut.nil?
91
+
80
92
  @csv&.close
81
93
 
82
- out_filename = generate_name(next_idx)
94
+ out_filename = generate_name(next_idx, desc: last_cut_desc)
83
95
  @csv = ::CSV.open(out_filename, "w")
84
96
  @csv << headers
85
97
  out_files << out_filename
98
+ @out_row_idx = 0
86
99
  end
87
100
 
88
101
  yield(@csv, idx, out_files.last) if block_given?
@@ -90,8 +103,19 @@ module Eco
90
103
  @csv
91
104
  end
92
105
 
93
- def split?(ridx)
94
- ((ridx + 1) % max_rows).zero?
106
+ # @note client scripts can tweak this method.
107
+ def split?(row)
108
+ return yield(row, row_idx) if block_given?
109
+
110
+ ((row_idx + 1) % max_rows).zero?
111
+ end
112
+
113
+ def splitter
114
+ @splitter ||= params[:splitter]
115
+ end
116
+
117
+ def splitter?
118
+ splitter.is_a?(Proc)
95
119
  end
96
120
 
97
121
  def next_idx
@@ -103,11 +127,15 @@ module Eco
103
127
  end
104
128
 
105
129
  def stream
106
- @stream ||= Eco::CSV::Stream.new(filename, **params)
130
+ @stream ||= Eco::CSV::Stream.new(
131
+ filename,
132
+ **params
133
+ )
107
134
  end
108
135
 
109
- def generate_name(fidx)
110
- File.join(input_dir, "#{input_name}_#{file_number(fidx)}#{input_ext}")
136
+ def generate_name(fidx, desc: nil)
137
+ desc = "_#{desc}" unless desc.nil?
138
+ File.join(input_dir, "#{input_name}_#{file_number(fidx)}#{desc}#{input_ext}")
111
139
  end
112
140
 
113
141
  def file_number(num)
@@ -3,6 +3,16 @@ module Eco
3
3
  class Stream
4
4
  include Eco::Language::AuxiliarLogger
5
5
 
6
+ CSV_PARAMS = %i[
7
+ col_sep row_sep quote_char
8
+ headers skip_blanks skip_lines
9
+ nil_value empty_value
10
+ converters unconverted_fields
11
+ return_headers header_converters
12
+ liberal_parsing
13
+ field_size_limit
14
+ ].freeze
15
+
6
16
  attr_reader :filename
7
17
 
8
18
  def initialize(filename, **kargs)
@@ -16,9 +26,42 @@ module Eco
16
26
  init
17
27
  end
18
28
 
29
+ def eof?
30
+ started? && !row
31
+ end
32
+
33
+ def started?
34
+ @started ||= false
35
+ end
36
+
37
+ def shift
38
+ raise ArgumentError, 'Expecting block, but not given.' unless block_given?
39
+
40
+ @started = true
41
+ yield(row, next_idx) if (self.row = csv.shift)
42
+ rescue StandardError => err
43
+ self.exception = err
44
+ raise
45
+ ensure
46
+ unless row || !fd.is_a?(::File)
47
+ fd.close
48
+ @fd = nil
49
+ end
50
+
51
+ if exception
52
+ # Give some feedback if it crashes
53
+ msg = []
54
+ msg << "Last row IDX: #{idx}"
55
+ msg << "Last row content: #{row.to_h.pretty_inspect}"
56
+ puts msg
57
+ log(:debug) { msg.join("\n") }
58
+ end
59
+ end
60
+
19
61
  def for_each(start_at_idx: 0)
20
62
  raise ArgumentError, 'Expecting block, but not given.' unless block_given?
21
63
 
64
+ @started = true
22
65
  move_to_idx(start_at_idx)
23
66
 
24
67
  yield(row, next_idx) while (self.row = csv.shift)
@@ -38,6 +81,7 @@ module Eco
38
81
  end
39
82
 
40
83
  def move_to_idx(start_at_idx)
84
+ @started = true
41
85
  start_at_idx ||= 0
42
86
  next_idx while (idx < start_at_idx) && (self.row = csv.shift)
43
87
  end
@@ -58,12 +102,18 @@ module Eco
58
102
  return @csv if instance_variable_defined?(:@csv)
59
103
 
60
104
  @fd = ::File.open(filename, 'r')
61
- @csv = Eco::CSV.new(fd, **params)
105
+ @csv = Eco::CSV.new(fd, **params.slice(*csv_params))
62
106
  end
63
107
 
64
108
  def init
65
109
  @idx ||= 0 # rubocop:disable Naming/MemoizedInstanceVariableName
66
110
  end
111
+
112
+ def csv_params
113
+ return self.class::CSV_PARAMS if self.class.const_defined?(:CSV_PARAMS)
114
+
115
+ CSV_PARAMS
116
+ end
67
117
  end
68
118
  end
69
119
  end
data/lib/eco/csv.rb CHANGED
@@ -19,7 +19,7 @@ module Eco
19
19
  end
20
20
 
21
21
  # Splits the csv `filename` into `max_rows`
22
- # @yield [row, ridx, fidx, file]
22
+ # @yield [row, ridx, fidx, file] block to spot if the row should be included
23
23
  # @yieldparam row [Integer] the row
24
24
  # @yieldparam ridx [Integer] the index of the row in the source file
25
25
  # @yieldparam fidx [Integer] the number of the file
@@ -29,15 +29,18 @@ module Eco
29
29
  # @param max_rows [Integer] number of rows per file
30
30
  # @param start_at [Integer] row that sets the starting point.
31
31
  # Leave empty for the full set of rows.
32
+ # @param kargs [Hash] additional parameters
33
+ # - `:splitter` [Proc] custom splitter (criteria)
34
+ # - Receives the row idx and the row itself
32
35
  # @return [Eco::CSV::Split]
33
- def split(filename, max_rows:, start_at: nil, **kargs, &block)
36
+ def split(filename, max_rows: :unused, start_at: nil, **kargs, &filter)
34
37
  Eco::CSV::Split.new(
35
38
  filename,
36
39
  max_rows: max_rows,
37
40
  start_at: start_at,
38
41
  **kargs
39
42
  ).tap do |splitter|
40
- splitter.call(&block)
43
+ splitter.call(&filter)
41
44
  end
42
45
  end
43
46
 
data/lib/eco/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Eco
2
- VERSION = '3.2.12'.freeze
2
+ VERSION = '3.2.14'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eco-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.12
4
+ version: 3.2.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oscar Segura
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-01-19 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: byebug
@@ -536,7 +535,6 @@ dependencies:
536
535
  - - "~>"
537
536
  - !ruby/object:Gem::Version
538
537
  version: 6.7.0
539
- description:
540
538
  email:
541
539
  - oscar@ecoportal.co.nz
542
540
  executables: []
@@ -796,18 +794,25 @@ files:
796
794
  - lib/eco/api/usecases/default/people/utils/switch_supervisor_case.rb
797
795
  - lib/eco/api/usecases/default/people/utils/transfer_account_case.rb
798
796
  - lib/eco/api/usecases/default/utils.rb
797
+ - lib/eco/api/usecases/default/utils/add_page_id_case.rb
798
+ - lib/eco/api/usecases/default/utils/cli/add_page_id_cli.rb
799
799
  - lib/eco/api/usecases/default/utils/cli/entries_to_csv_cli.rb
800
800
  - lib/eco/api/usecases/default/utils/cli/group_csv_cli.rb
801
801
  - lib/eco/api/usecases/default/utils/cli/json_to_csv_cli.rb
802
+ - lib/eco/api/usecases/default/utils/cli/merge_csv_cli.rb
802
803
  - lib/eco/api/usecases/default/utils/cli/sort_csv_cli.rb
803
804
  - lib/eco/api/usecases/default/utils/cli/split_csv_cli.rb
804
805
  - lib/eco/api/usecases/default/utils/cli/split_json_cli.rb
806
+ - lib/eco/api/usecases/default/utils/cli/track_files_cli.rb
805
807
  - lib/eco/api/usecases/default/utils/entries_to_csv_case.rb
806
808
  - lib/eco/api/usecases/default/utils/group_csv_case.rb
809
+ - lib/eco/api/usecases/default/utils/group_csv_case/file_handler.rb
807
810
  - lib/eco/api/usecases/default/utils/json_to_csv_case.rb
811
+ - lib/eco/api/usecases/default/utils/merge_csv_case.rb
808
812
  - lib/eco/api/usecases/default/utils/sort_csv_case.rb
809
813
  - lib/eco/api/usecases/default/utils/split_csv_case.rb
810
814
  - lib/eco/api/usecases/default/utils/split_json_case.rb
815
+ - lib/eco/api/usecases/default/utils/track_files_case.rb
811
816
  - lib/eco/api/usecases/default_cases.rb
812
817
  - lib/eco/api/usecases/default_cases/create_case.rb
813
818
  - lib/eco/api/usecases/default_cases/delete_sync_case.rb
@@ -1083,7 +1088,6 @@ licenses:
1083
1088
  - MIT
1084
1089
  metadata:
1085
1090
  rubygems_mfa_required: 'true'
1086
- post_install_message:
1087
1091
  rdoc_options: []
1088
1092
  require_paths:
1089
1093
  - lib
@@ -1098,8 +1102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1098
1102
  - !ruby/object:Gem::Version
1099
1103
  version: '0'
1100
1104
  requirements: []
1101
- rubygems_version: 3.5.23
1102
- signing_key:
1105
+ rubygems_version: 4.0.8
1103
1106
  specification_version: 4
1104
1107
  summary: eco-helpers to manage people api cases
1105
1108
  test_files: []