csv_pirate 2.1.2 → 2.4.4

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/CHANGELOG CHANGED
@@ -1,3 +1,19 @@
1
+ Version 2.4.1 2009-10-01
2
+ - Fixed critical typo
3
+
4
+ Version 2.4.0 2009-10-01
5
+ - Added blindfold to pirate_ship
6
+ - Added say_your_last_words to pirate_ship which is hash for send_data
7
+
8
+ Version 2.3.0 2009-10-01
9
+ - No longer requires rails at all
10
+ - hoise_mainstay now returns the exported text
11
+ - Better documentation in Readme and source
12
+
13
+ Version 2.2.0 2009-10-01
14
+ - Use FasterCSV for all backend work
15
+ - Added shrouds for creating tsv and psv files
16
+
1
17
  Version 2.1.0 2009-10-01
2
18
  - Added handling of nested methods!
3
19
 
@@ -1,4 +1,4 @@
1
- == CsvPirate v2.0.1 (20091001)
1
+ == CsvPirate
2
2
 
3
3
  Easily create CSVs of any data that can be derived from your models.
4
4
 
@@ -9,22 +9,26 @@ CsvPirate only works for commissions of swag OR grub!
9
9
 
10
10
  Initialize method (a.k.a new()) takes a hash of params:
11
11
 
12
- swag: the ARrr collection of swag to work on (optional)
13
- grub: the ARrr class that the spyglasses will be used on (optional)
14
- spyglasses: named scopes in your model that will refine the rows in the CSV according to conditions of the spyglass,
15
- and order them according to the order of the spyglass (only used with grub, not swag)
16
- booty: booty on your model that you want printed in the CSV
17
- chart: name of directory where you want to hide your loot
18
- waggoner: name of document where you will give detailed descriptions of the loot
19
- chronometer: keeps track of when you hunt for treasure
20
- gibbet: filename spacer after the date, and before the iterative counter/timestamp. MuST contain a '.'
21
- swab: can be :counter, :timestamp, or :none
22
- :counter - default, each successive run will create a new file using a counter
23
- :timestamp - each successive run will create a new file using a HHMMSS time stamp
24
- :none - no iterative file naming convention, just use waggoner and aft
25
- mop: can be :clean or :dirty (:overwrite or :append) (only has an effect if :swab is :none) since overwriting is irrelevant for a new file
26
- :clear - do not use :counter or :timestamp, and instead overwrite the file
27
- :dirty - do not use :counter, or :timestamp, or :overwrite. Just keep adding on.
12
+ # CsvPirate only works for commissions of swag OR grub!
13
+ # :swag the ARrr collection of swag to work on (optional)
14
+ # :grub the ARrr class that the spyglasses will be used on (optional)
15
+ # :spyglasses named scopes in your model that will refine the rows in the CSV according to conditions of the spyglasses,
16
+ # and order them according to the order of the spyglasses (optional)
17
+ # :booty booty (columns/methods) on your model that you want printed in the CSV, also used to create the figurehead (CSV header)
18
+ # :chart name of directory where you want to hide your loot
19
+ # :wagonner name of document where you will give detailed descriptions of the loot
20
+ # :aft filename extention ('.csv')
21
+ # :shrouds CSV column separator, default is ','. For tsv, tab-delimited, "\t"
22
+ # :chronometer keeps track of when you hunt for treasure
23
+ # :gibbet filename spacer after the date, and before the iterative counter/timestamp. MuST contain a '.'
24
+ # :swab can be :counter, :timestamp, or :none
25
+ # :counter - default, each successive run will create a new file using a counter
26
+ # :timestamp - each successive run will create a new file using a HHMMSS time stamp
27
+ # :none - no iterative file naming convention, just use waggoner and aft
28
+ # :mop can be :clean or :dirty (:overwrite or :append) (only has an effect if :swab is :none) since overwriting is irrelevant for a new file
29
+ # :clear - do not use :counter or :timestamp, and instead overwrite the file
30
+ # :dirty - do not use :counter, or :timestamp, or :overwrite. Just keep adding on.
31
+ # There are others too, check the source for a complete picture!
28
32
 
29
33
  The create method has the same parameters, and actually creates the CSV.
30
34
 
@@ -89,7 +93,7 @@ Assuming a Make (as in manufacturers of automobiles) model like this:
89
93
  :booty => [:id, :name]
90
94
  end
91
95
 
92
- To create a csv of the names and ids of makes with factories in germany:
96
+ To create a csv of the names and ids of makes with factories in germany and return the text of the export:
93
97
 
94
98
  Make.walk_the_plank # Get it? HA! If you can't believe I wrote this whole thing JUST to be able to make jokes like that... check ma sources :)
95
99
 
@@ -104,9 +108,24 @@ All of those filename parts are customizable to a degree.
104
108
  You can also customize the CSV, for example if you want to add a column to the csv:
105
109
 
106
110
  Make.walk_the_plank({:booty => [:id, :name, :sales]})
111
+
112
+ Youw want a timestamp file counter instead of the integer default:
113
+
107
114
  Make.walk_the_plank({:booty => [:id, :name, :sales], :spyglasses => [:all], :swab => :timestamp})
115
+
116
+ If you want to append each export to the end of the same file (on a per day basis):
117
+
108
118
  Make.walk_the_plank({:booty => [:id, :name, :sales], :spyglasses => [:all], :swab => :none, :mop => :dirty})
109
119
 
120
+ If you want to restrict the csv to a particular set of named scopes:
121
+
122
+ Make.walk_the_plank({:booty => [:id, :name, :sales], :spyglasses => [:with_abs, :with_esc, :with_heated_seats]})
123
+
124
+ If you want to create a tsv (tab-delimited) or psv (pipe-delimited) instead of a csv:
125
+
126
+ Make.walk_the_plank({:booty => [:id, :name, :sales], :shrouds => '\t'})
127
+ Make.walk_the_plank({:booty => [:id, :name, :sales], :shrouds => '|'})
128
+
110
129
  If you have a method in the Make class like this:
111
130
 
112
131
  def to_slug
@@ -117,29 +136,14 @@ getting it in the CSV is easy peasy:
117
136
 
118
137
  Make.walk_the_plank({:booty => [:id, :name, :to_slug]})
119
138
 
120
- Add whatever methods you want to the :booty array. Write new methods, and add them! Make lots of glorious CSVs full of data to impress the pointy ones in the office.
139
+ If you want to traverse Active Record Associations, or call a method on the return value of another method (unlimited nesting):
121
140
 
122
- You can also use the raw CsvPirate class itself directly wherever you want. These are the available options to methods:
123
- new, create, or walk_the_plank
141
+ Make.walk_the_plank({:booty => [:id, :name, :to_slug, {:to_slug => :hash}]}) #will call .hash on the result of make.to_slug
142
+ Make.walk_the_plank({:booty => [:id, :name, :to_slug, {:to_slug => {:hash => :abs}}]}) #returns make.to_slug.hash.abs
124
143
 
125
- # CsvPirate only works for commissions of swag OR grub!
126
- # :swag the ARrr collection of swag to work on (optional)
127
- # :grub the ARrr class that the spyglasses will be used on (optional)
128
- # :spyglasses named scopes in your model that will refine the rows in the CSV according to conditions of the spyglasses,
129
- # and order them according to the order of the spyglasses (optional)
130
- # :booty booty (columns/methods) on your model that you want printed in the CSV, also used to create the figurehead (CSV header)
131
- # :chart name of directory where you want to hide your loot
132
- # :wagonner name of document where you will give detailed descriptions of the loot
133
- # :aft filename extention ('.csv')
134
- # :chronometer keeps track of when you hunt for treasure
135
- # :gibbet filename spacer after the date, and before the iterative counter/timestamp. MuST contain a '.'
136
- # :swab can be :counter, :timestamp, or :none
137
- # :counter - default, each successive run will create a new file using a counter
138
- # :timestamp - each successive run will create a new file using a HHMMSS time stamp
139
- # :none - no iterative file naming convention, just use waggoner and aft
140
- # :mop can be :clean or :dirty (:overwrite or :append) (only has an effect if :swab is :none) since overwriting is irrelevant for a new file
141
- # :clear - do not use :counter or :timestamp, and instead overwrite the file
142
- # :dirty - do not use :counter, or :timestamp, or :overwrite. Just keep adding on.
144
+ Add whatever methods you want to the :booty array. Write new methods, and add them! Make lots of glorious CSVs full of data to impress the pointy ones in the office.
145
+
146
+ You can also use the raw CsvPirate class itself directly wherever you want.
143
147
 
144
148
  The following two sets of code are identical:
145
149
 
@@ -183,6 +187,35 @@ OR
183
187
 
184
188
  csv_pirate = CsvPirate.new({:swag => users,:waggoner => 'inactive_users_not_logged_in',:booty => ["id","number","login","created_at"],:chart => 'log/csv/'})
185
189
 
190
+
191
+ == Downloading the CSV
192
+
193
+ You have the same Make class as above, and you have a MakeController:
194
+
195
+ class MakeController < ApplicationController
196
+
197
+ def download_csv
198
+ send_data Make.say_your_last_words # "utf-8" is default, and uses options from has_csv_pirate_ship
199
+ end
200
+
201
+ # OR you can customize it just like walk_the_plank
202
+
203
+ def download_csv
204
+ send_data Make.say_your_last_words("iso-8859-1", {:booty => [:id, :name]})
205
+ end
206
+
207
+ end
208
+
209
+ Too easy? I wrote this for two reasons... pirate jokes and to make my life easier. If you need more flexibility then:
210
+
211
+ def download_csv
212
+ csv_pirate = Make.blindfold
213
+ send_data csv_pirate.maroon,
214
+ :type => 'text/csv; charset=iso-8859-1; header=present',
215
+ :disposition => "attachment; filename=#{csv_pirate.nocturnal}"
216
+ end
217
+
218
+
186
219
  == Advanced Example with Nested Methods
187
220
 
188
221
  You have a VehicleModel class and the same Make class as up above:
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 2
2
+ :patch: 4
3
3
  :major: 2
4
- :minor: 1
4
+ :minor: 4
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{csv_pirate}
8
- s.version = "2.1.2"
8
+ s.version = "2.4.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Peter Boling"]
@@ -32,7 +32,7 @@ class CsvPirate
32
32
  attr_accessor :booty # methods / columns
33
33
 
34
34
  attr_accessor :bury_treasure # should we store the csv data in an array for later inspection, or just write the CSV?
35
- # default is true
35
+ # default is false
36
36
  # The array that gets built as we write the CSV... could be useful?
37
37
  attr_accessor :buried_treasure # info array
38
38
 
@@ -40,41 +40,48 @@ class CsvPirate
40
40
 
41
41
  attr_accessor :astrolabe # when true then read only CsvPirate instance for loading of CSVs
42
42
 
43
+ attr_accessor :shrouds # CSV column separator
44
+
43
45
  attr_accessor :swab # default is :counter
44
46
  attr_accessor :mop # default is :clean (only has an effect if :swab is :none) since overwriting is irrelevant for a new file
45
47
  attr_accessor :swabbie # value of the counter / timestamp
48
+ attr_accessor :maroon # text of csv
49
+ attr_accessor :nocturnal # basename of the filepath (i.e. filename)
46
50
 
47
51
  cattr_accessor :parlay # verbosity on a scale of 0 - 3 (0=:none, 1=:error, 2=:info, 3=:debug, 0 being no screen output, 1 is default
48
52
 
49
53
  # CsvPirate only works for commissions of swag OR grub!
50
- # :swag the ARrr collection of swag to work on (optional)
51
- # :grub the ARrr class that the spyglasses will be used on (optional)
52
- # :spyglasses named scopes in your model that will refine the rows in the CSV according to conditions of the spyglasses,
53
- # and order them according to the order of the spyglasses (optional)
54
- # :booty booty (columns/methods) on your model that you want printed in the CSV, also used to create the figurehead (CSV header)
55
- # :chart name of directory where you want to hide your loot
56
- # :wagonner name of document where you will give detailed descriptions of the loot
57
- # :aft filename extention ('.csv')
58
- # :chronometer keeps track of when you hunt for treasure
59
- # :gibbet filename spacer after the date, and before the iterative counter/timestamp. MuST contain a '.'
60
- # :swab can be :counter, :timestamp, or :none
54
+ # :swag the ARrr collection of swag to work on (optional)
55
+ # :grub the ARrr class that the spyglasses will be used on (optional)
56
+ # :spyglasses named scopes in your model that will refine the rows in the CSV according to conditions of the spyglasses,
57
+ # and order them according to the order of the spyglasses (optional)
58
+ # :booty booty (columns/methods) on your model that you want printed in the CSV, also used to create the figurehead (CSV header)
59
+ # :chart name of directory where you want to hide your loot
60
+ # :wagonner name of document where you will give detailed descriptions of the loot
61
+ # :aft filename extention ('.csv')
62
+ # :shrouds CSV column separator, default is ','. For tsv, tab-delimited, "\t"
63
+ # :chronometer keeps track of when you hunt for treasure
64
+ # :gibbet filename spacer after the date, and before the iterative counter/timestamp. MuST contain a '.'
65
+ # :swab can be :counter, :timestamp, or :none
61
66
  # :counter - default, each successive run will create a new file using a counter
62
67
  # :timestamp - each successive run will create a new file using a HHMMSS time stamp
63
68
  # :none - no iterative file naming convention, just use waggoner and aft
64
- # :mop can be :clean or :dirty (:overwrite or :append) (only has an effect if :swab is :none) since overwriting is irrelevant for a new file
69
+ # :mop can be :clean or :dirty (:overwrite or :append) (only has an effect if :swab is :none) since overwriting is irrelevant for a new file
65
70
  # :clear - do not use :counter or :timestamp, and instead overwrite the file
66
71
  # :dirty - do not use :counter, or :timestamp, or :overwrite. Just keep adding on.
72
+ # :bury_treasure should we store the csv data as it is collected in an array in Ruby form for later use (true), or just write the CSV (false)?
67
73
  # See README for examples
68
74
 
69
75
  def initialize(*args)
76
+ raise ArgumentError, "must provide required options" if args.blank?
70
77
 
71
78
  @swag = args.first[:swag]
72
79
  @grub = args.first[:grub]
73
80
 
74
81
  # if they provide both
75
- raise ArgumentError, "must provide either specify :swag or :grub" if !args.first[:swag].blank? && !args.first[:grub].blank?
82
+ raise ArgumentError, "must provide either :swag or :grub" if !args.first[:swag].blank? && !args.first[:grub].blank?
76
83
  # if they provide neither
77
- raise ArgumentError, "must provide either specify :swag or :grub, not both" if args.first[:swag].blank? && args.first[:grub].blank?
84
+ raise ArgumentError, "must provide either :swag or :grub, not both" if args.first[:swag].blank? && args.first[:grub].blank?
78
85
 
79
86
  @swab = args.first[:swab] || :counter
80
87
  raise ArgumentError, ":swab is #{args.first[:swab].inspect}, but must be one of #{CsvPirate::BOOKIE.inspect}" unless CsvPirate::BOOKIE.include?(args.first[:swab])
@@ -96,19 +103,25 @@ class CsvPirate
96
103
  @chronometer = args.first[:chronometer] || Date.today
97
104
 
98
105
  @spyglasses = (args.first[:spyglasses] || [:all]) if self.grub
99
-
106
+ @shrouds = args.first[:shrouds] || ',' # for tsv, tab-delimited, "\t"
100
107
 
101
108
  @astrolabe = args.first[:astrolabe] || false
102
109
 
103
- @bury_treasure = args.first[:astrolabe] || true
110
+ @bury_treasure = args.first[:astrolabe] || false
104
111
  @buried_treasure = []
105
112
 
106
113
  # Initialize doesn't write anything to a CSV,
107
114
  # but does create the traverse_board and opens the waggoner for reading / writing
108
115
  Dir.mkdir(self.traverse_board) if !self.astrolabe && Dir.glob(self.traverse_board).empty?
109
116
 
117
+ # This will contain the text of the csv from this particular execution
118
+ @maroon = ""
119
+
110
120
  # Once the traverse_board (dir) exists, then check if the rhumb_lines (file) already exists, and set our rhumb_lines counter
111
121
  @swabbie = self.insult_swabbie
122
+
123
+ @nocturnal = File.basename(self.poop_deck)
124
+
112
125
  # Then open the rhumb_lines
113
126
  self.rhumb_lines = File.open(File.expand_path(self.poop_deck),self.astrolabe ? "r" : "a")
114
127
  end
@@ -122,6 +135,7 @@ class CsvPirate
122
135
  :waggoner => args.first[:waggoner],
123
136
  :swag => args.first[:swag],
124
137
  :swab => args.first[:swab],
138
+ :shrouds => args.first[:shrouds],
125
139
  :mop => args.first[:mop],
126
140
  :grub => args.first[:grub],
127
141
  :spyglasses => args.first[:spyglasses],
@@ -178,40 +192,49 @@ class CsvPirate
178
192
 
179
193
  self.swab_poop_deck
180
194
 
181
- self.figurehead
182
-
183
- self.bury_treasure ? self.buried_treasure = self.dead_mans_chest : self.dead_mans_chest
195
+ self.dead_mans_chest
184
196
 
185
197
  self.rhumb_lines.close
186
198
 
187
199
  self.jolly_roger if CsvPirate.parlay > 1
188
200
 
189
- # returns the array that was created before exporting it to CSV
190
- return self.bury_treasure ? self.buried_treasure : true
201
+ # returns the text of this CSV export
202
+ return self.maroon
191
203
  end
192
204
 
193
205
  def dead_mans_chest
194
- self.dig_for_treasure do |treasure|
195
- self.scrivener(treasure.map {|x| "#{x}"}.to_csv) # |x| marks the spot!
206
+ self.maroon = FasterCSV.generate(:col_sep => self.shrouds) do |csv|
207
+ self.sounding(csv)
196
208
  end
209
+ self.scrivener(self.maroon)
210
+ self.maroon
197
211
  end
198
212
 
199
213
  def jolly_roger
200
- if self.buried_treasure.is_a?(Array)
201
- puts "Found #{self.buried_treasure.length} deniers buried here: '#{self.poop_deck}'" if CsvPirate.parlay > 1
202
- puts "You must weigh_anchor to review your plunder!" if CsvPirate.parlay > 1
203
- else
204
- puts "Failed to locate treasure" if CsvPirate.parlay > 1
214
+ if self.bury_treasure
215
+ if self.buried_treasure.is_a?(Array)
216
+ puts "Found #{self.buried_treasure.length} deniers buried here: '#{self.poop_deck}'" if CsvPirate.parlay > 1
217
+ puts "You must weigh_anchor to review your plunder!" if CsvPirate.parlay > 1
218
+ else
219
+ puts "Failed to locate treasure" if CsvPirate.parlay > 1
220
+ end
205
221
  end
206
222
  end
207
223
 
208
- # write the header of the CSV (column/method names)
209
- def figurehead
210
- self.scrivener(self.booty.to_csv)
224
+ def sounding(csv)
225
+ # create the header of the CSV (column/method names)
226
+ csv << self.booty
227
+ # create the data for the csv
228
+ self.dig_for_treasure do |treasure|
229
+ moidore = treasure.map {|x| "#{x}"}
230
+ csv << moidore # |x| marks the spot!
231
+ self.buried_treasure << moidore if self.bury_treasure
232
+ end
211
233
  end
212
-
234
+
213
235
  def traverse_board
214
- "#{RAILS_ROOT}/#{self.chart}"
236
+ #If we have rails environment then we use rails root, otherwise self.chart stands on its own as a relative path
237
+ "#{defined?(Rails) ? Rails.root + '/' : defined?(RAILS_ROOT) ? RAILS_ROOT + '/' : ''}#{self.chart}"
215
238
  end
216
239
 
217
240
  def sand_glass
@@ -223,14 +246,38 @@ class CsvPirate
223
246
  "#{self.analemma}#{self.swabbie}#{self.aft}"
224
247
  end
225
248
 
249
+ def merchantman
250
+ "#{self.waggoner}#{self.sand_glass}#{self.gibbet}"
251
+ end
252
+
226
253
  def analemma
227
- "#{self.traverse_board}#{self.waggoner}#{self.sand_glass}#{self.gibbet}"
254
+ "#{self.traverse_board}#{self.merchantman}"
255
+ end
256
+
257
+ # Swabs the poop_deck if the mop is clean. (!)
258
+ def swab_poop_deck
259
+ self.rhumb_lines.truncate(0) if self.swab == :none && self.mop == :clean && File.size(self.poop_deck) > 0
260
+ end
261
+
262
+ # Must be done on order to rummage through the loot found by the pirate ship
263
+ def weigh_anchor
264
+ CsvPirate.rinse(self.poop_deck)
228
265
  end
229
266
 
267
+ # Sink your own ship! Or run a block of code on each row of the current CSV
268
+ def scuttle(&block)
269
+ return false unless block_given?
270
+ CsvPirate.broadside(self.poop_deck) do |careen|
271
+ yield careen
272
+ end
273
+ end
274
+
275
+ protected
276
+
230
277
  def lantern
231
278
  "#{self.analemma}.*"
232
279
  end
233
-
280
+
234
281
  def filibuster(flotsam)
235
282
  base = File.basename(flotsam, self.aft)
236
283
  index = base.rindex('.')
@@ -238,7 +285,7 @@ class CsvPirate
238
285
  # Ensure numbers
239
286
  counter = tail.nil? ? 0 : tail[/\d*/].to_i
240
287
  end
241
-
288
+
242
289
  def boatswain
243
290
  return self.swabbie unless self.swabbie.nil?
244
291
  counter = 0
@@ -249,17 +296,12 @@ class CsvPirate
249
296
  highval = ((highval <=> counter) == 1) ? highval : counter
250
297
  counter = 0
251
298
  end
252
- self.swabbie = ".#{highval + 1}"
299
+ ".#{highval + 1}"
253
300
  end
254
301
 
255
302
  def coxswain
256
303
  return self.swabbie unless self.swabbie.nil?
257
- self.swabbie = ".#{Time.now.strftime("%I%M%S")}"
258
- end
259
-
260
- # Swabs the poop_deck if the mop is clean. (!)
261
- def swab_poop_deck
262
- self.rhumb_lines.truncate(0) if self.swab == :none && self.mop == :clean && File.size(self.poop_deck) > 0
304
+ ".#{Time.now.strftime("%I%M%S")}"
263
305
  end
264
306
 
265
307
  # Sets the swabby file counter
@@ -270,22 +312,11 @@ class CsvPirate
270
312
  when :timestamp
271
313
  self.coxswain
272
314
  else
273
- self.swabbie = ""
315
+ ""
274
316
  end
275
317
  end
276
318
 
277
- # Must be done on order to rummage through the loot found by the pirate ship
278
- def weigh_anchor
279
- CsvPirate.rinse(self.poop_deck)
280
- end
281
-
282
- # Sink your own ship! Or run a block of code on each row of the current CSV
283
- def scuttle(&block)
284
- return false unless block_given?
285
- CsvPirate.broadside(self.poop_deck) do |careen|
286
- yield careen
287
- end
288
- end
319
+ public
289
320
 
290
321
  ########################################
291
322
  ############ CLASS METHODS #############
@@ -4,9 +4,8 @@ module NinthBit
4
4
  module ActMethods
5
5
  #coding tyle is adopted from attachment_fu
6
6
  def has_csv_pirate_ship(options = {})
7
- if options.blank?
8
- raise ArgumentError, "must provide required options"
9
- end
7
+ raise ArgumentError, "must provide required options" if options.blank?
8
+
10
9
  options[:chart] ||= 'log/'
11
10
  options[:aft] ||= '.csv'
12
11
  options[:gibbet] ||= '.export'
@@ -16,6 +15,7 @@ module NinthBit
16
15
  options[:swag] ||= nil
17
16
  options[:swab] ||= :counter
18
17
  options[:mop] ||= :clean
18
+ options[:shrouds] ||= ','
19
19
  options[:grub] ||= self if options[:swag].nil?
20
20
  options[:spyglasses] ||= [:all]
21
21
  options[:booty] ||= self.column_names
@@ -23,9 +23,9 @@ module NinthBit
23
23
  options[:parlay] ||= 1
24
24
 
25
25
  # if they provide both
26
- raise ArgumentError, "must provide either specify :swag or :grub" if !options[:swag].blank? && !options[:grub].blank?
26
+ raise ArgumentError, "must provide either :swag or :grub" if !options[:swag].blank? && !options[:grub].blank?
27
27
  # if they provide neither
28
- raise ArgumentError, "must provide either specify :swag or :grub, not both" if options[:swag].blank? && options[:grub].blank?
28
+ raise ArgumentError, "must provide either :swag or :grub, not both" if options[:swag].blank? && options[:grub].blank?
29
29
  raise ArgumentError, ":swab is #{options[:swab].inspect}, but must be one of #{CsvPirate::BOOKIE.inspect}" unless CsvPirate::BOOKIE.include?(options[:swab])
30
30
  raise ArgumentError, ":mop is #{options[:mop].inspect}, but must be one of #{CsvPirate::MOP_HEADS.inspect}" unless CsvPirate::MOP_HEADS.include?(options[:mop])
31
31
  raise ArgumentError, ":gibbet is #{options[:gibbet].inspect}, and does not contain a '.' character, which is required for iterative filenames" if options[:gibbet].nil? || !options[:gibbet].include?('.')
@@ -45,10 +45,41 @@ module NinthBit
45
45
  base.class_inheritable_accessor :piratey_options
46
46
  end
47
47
 
48
+ # intended for use with send_data for downloading the text of the csv:
49
+ # send_data Make.say_your_last_words
50
+ def say_your_last_words(charset = 'utf-8', args = {})
51
+ csv_pirate = self.blindfold(args)
52
+ return [ csv_pirate.maroon,
53
+ {:type => "text/csv; charset=#{charset}; header=present"},
54
+ {:disposition => "attachment; filename=#{csv_pirate.nocturnal}"} ]
55
+ end
56
+
57
+ #returns the text of the csv export (not the file - this is important if you are appending)
58
+ # warning if using from console: if you are exporting a large csv this will all print in your console.
59
+ # intended for use with send_data for downloading the text of the csv:
60
+ # send_data Make.walk_the_plank,
61
+ # :type => 'text/csv; charset=iso-8859-1; header=present',
62
+ # :disposition => "attachment; filename=Data.csv"
48
63
  def walk_the_plank(args = {})
64
+ csv_pirate = CsvPirate.new(self.piratey_args(args))
65
+ csv_pirate.hoist_mainstay()
66
+ end
67
+
68
+ #returns the csv_pirate object so you have access to everything
69
+ # If using in a download action it might look like this:
70
+ # csv_pirate = Make.blindfold
71
+ # send_data csv_pirate.maroon,
72
+ # :type => 'text/csv; charset=iso-8859-1; header=present',
73
+ # :disposition => "attachment; filename=#{csv_pirate.nocturnal}"
74
+ def blindfold(args = {})
49
75
  CsvPirate.parlay = args[:parlay] || self.piratey_options[:parlay]
50
- CsvPirate.create({
51
- :chart => args[:chart] || self.piratey_options[:chart],
76
+ CsvPirate.create(self.piratey_args(args))
77
+ end
78
+
79
+ protected
80
+
81
+ def piratey_args(args = {})
82
+ { :chart => args[:chart] || self.piratey_options[:chart],
52
83
  :aft => args[:aft] || self.piratey_options[:aft],
53
84
  :gibbet => args[:gibbet] || self.piratey_options[:gibbet],
54
85
  :chronometer => args[:chronometer] || Date.today,
@@ -56,11 +87,11 @@ module NinthBit
56
87
  :swag => args[:swag] || self.piratey_options[:swag],
57
88
  :swab => args[:swab] || self.piratey_options[:swab],
58
89
  :mop => args[:mop] || self.piratey_options[:mop],
90
+ :shrouds => args[:swab] || self.piratey_options[:shrouds],
59
91
  :grub => args[:grub] || self.piratey_options[:grub],
60
92
  :spyglasses => args[:spyglasses] || self.piratey_options[:spyglasses],
61
93
  :booty => args[:booty] || self.piratey_options[:booty],
62
- :bury_treasure => args[:bury_treasure] || self.piratey_options[:bury_treasure]
63
- })
94
+ :bury_treasure => args[:bury_treasure] || self.piratey_options[:bury_treasure] }
64
95
  end
65
96
 
66
97
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: csv_pirate
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
4
+ version: 2.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Boling