csv_pirate 3.3.2 → 3.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ Version 3.4.1 2009-10-12
2
+ - :blackjack option :join is now working.
3
+ - Added warnings, and improved Readme
4
+
5
+ Version 3.4.0 2009-10-12
6
+ - Now the auto generated columns based on the booty array print nicely, with customization options
7
+ - You are now able to specify your own array of strings to use as the CSV header, in case you don't want to use the booty methods.
8
+
1
9
  Version 3.3.2 2009-10-11
2
10
  - You can now declare has_csv_pirate_ship in a model whose migration has not been run yet without making the app barf.
3
11
  - Cleaned up Gem Dependency (faster_csv)
@@ -9,7 +9,7 @@ My goal is to have it do EVERYTHING it possibly can for me, since almost every p
9
9
 
10
10
  CsvPirate only works for commissions of swag OR grub!
11
11
 
12
- Initialize method (a.k.a new()) takes a hash of params:
12
+ Initialize method (a.k.a new()) takes a hash of parameters:
13
13
 
14
14
  # CsvPirate only works for commissions of swag OR grub!
15
15
  # :swag the ARrr collection of swag to work on (optional)
@@ -28,9 +28,13 @@ Initialize method (a.k.a new()) takes a hash of params:
28
28
  # :timestamp - each successive run will create a new file using a HHMMSS time stamp
29
29
  # :none - no iterative file naming convention, just use waggoner and aft
30
30
  # :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
31
- # :clean - do not use :counter or :timestamp, and instead overwrite the file
32
- # :dirty - do not use :counter, or :timestamp, or :overwrite. Just keep adding on.
31
+ # :clean - do not use :swab above (:counter or :timestamp), and instead overwrite the file
32
+ # :dirty - do not use :swab above (:counter, or :timestamp), and do not overwrite. Just keep adding on.
33
33
  # :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)?
34
+ # :blackjack Specify how you want your CSV header
35
+ # {:join => '-'} joins the method names called to get hte data for that column with '_' underscores.
36
+ # {:humanize =>'-'} first joins as above, then humanizes the string
37
+ # {:array => ['col1',col2','col3'] Uses the column names provided. If the array's length is less than the booty array's length it reverts to :humanize =>'_'
34
38
  # check the source to see if there anything else hiding in there!
35
39
 
36
40
  The create method has the same parameters, and actually creates the CSV.
@@ -63,7 +67,7 @@ Gem Using Git building from source:
63
67
  git clone git://github.com/pboling/csv_pirate.git
64
68
  cd csv_pirate
65
69
  gem build csv_pirate.gemspec
66
- sudo gem install csv_pirate-3.3.1.gem # (Or whatever version gets built)
70
+ sudo gem install csv_pirate-3.4.1.gem # (Or whatever version gets built)
67
71
 
68
72
  Then cd to your rails app to optionally freeze the gem into your app:
69
73
 
@@ -187,19 +191,23 @@ Assuming a Make (as in manufacturers of automobiles) model like this:
187
191
  :mop => :clean # Symbol: If we DO end up writing to a preexisting file (by design or accident) should we overwrite (:clean) or append (:dirty)?
188
192
  :shrouds => ',' # String: Delimiter for CSV. '\t' will create a tab delimited file (tsv), '|' will create a pipe delimited file.
189
193
  :bury_treasure => true # Boolean: Should the array of objects in :swag be stored in the CsvPirate object for later inspection?
194
+ :blackjack => {:humanize => '-'} # Hash: Specify how you want your CSV header
195
+ # {:join => '-'} joins the method names called to get hte data for that column with '_' underscores.
196
+ # {:humanize => '-'} first joins as above, then humanizes the string
197
+ # {:array => ['col1',col2','col3'] Uses the column names provided in the array. If the array provided is too short defaults to :humanize =>'_'
190
198
 
191
199
  # A customized version to create a tab delimited file for this class might look like this:
192
200
  # has_csv_pirate_ship :spyglasses => [:factory_in_germany],
193
201
  # :booty => [:id, :name],
194
202
  # :shrouds => '\t'
195
- # # kepping the rest of the options at the default values, so they don't need to be defined.
203
+ # # keeping the rest of the options at the default values, so they don't need to be defined.
196
204
  end
197
205
 
198
206
  To create a csv of the names and ids of makes with factories in germany and return the text of the export:
199
207
 
200
208
  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 :)
201
209
 
202
- The name of the csv that comes out will be (by defualt located in log directory):
210
+ The name of the csv that comes out will be (by default located in log directory):
203
211
 
204
212
  Make.20090930.export.13.csv
205
213
 
@@ -208,10 +216,10 @@ Where Make is the class, 20090930 is today's date, .export is the gibbet, and 13
208
216
  All of those filename parts are customizable to a degree. For example if you want to have the date NOT be today's date you can supply your own date:
209
217
 
210
218
  Make.walk_the_plank({:chronometer => Date.parse("December 21, 2012") })
211
- # Filename would be: Make.20121221.export.13.csv
219
+ # File name would be: Make.20121221.export.13.csv
212
220
 
213
221
  Make.walk_the_plank({:chronometer => false })
214
- # Filename would be: Make.export.13.csv
222
+ # File name would be: Make.export.13.csv
215
223
 
216
224
  What if you want the file name to be always the same and to always append to the end of it?
217
225
  #Example: I want the file to be named "data", with no extension, both of the following accomplish that:
@@ -364,7 +372,7 @@ Then check the output from the console:
364
372
 
365
373
  a.weigh_anchor
366
374
 
367
- id,name,year,makename,tiressizewidthinches
375
+ Id,Name,Year,Make name,Tires size width inches
368
376
  1,Cavalier,1999,Chevrolet,13
369
377
  2,Trailblazer,2006,Chevrolet,13
370
378
  3,Corvette,2010,Chevrolet,13
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ It works better if you are wearing a tricorne!}
10
10
  gemspec.email = "peter.boling@gmail.com"
11
11
  gemspec.homepage = "http://github.com/pboling/csv_pirate"
12
12
  gemspec.authors = ["Peter Boling"]
13
- gemspec.add_dependency 'faster_csv'
13
+ gemspec.add_dependency 'fastercsv'
14
14
  gemspec.files = ["README.rdoc",
15
15
  "csv_pirate.gemspec",
16
16
  "init.rb",
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 2
2
+ :patch: 1
3
3
  :major: 3
4
- :minor: 3
4
+ :minor: 4
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{csv_pirate}
8
- s.version = "3.3.2"
8
+ s.version = "3.4.1"
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"]
12
- s.date = %q{2009-10-11}
12
+ s.date = %q{2009-10-13}
13
13
  s.description = %q{CsvPirate is the easy way to create a CSV of essentially anything in Rails, in full pirate regalia.
14
14
  It works better if you are wearing a tricorne!}
15
15
  s.email = %q{peter.boling@gmail.com}
@@ -45,11 +45,11 @@ It works better if you are wearing a tricorne!}
45
45
  s.specification_version = 3
46
46
 
47
47
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
48
- s.add_runtime_dependency(%q<faster_csv>, [">= 0"])
48
+ s.add_runtime_dependency(%q<fastercsv>, [">= 0"])
49
49
  else
50
- s.add_dependency(%q<faster_csv>, [">= 0"])
50
+ s.add_dependency(%q<fastercsv>, [">= 0"])
51
51
  end
52
52
  else
53
- s.add_dependency(%q<faster_csv>, [">= 0"])
53
+ s.add_dependency(%q<fastercsv>, [">= 0"])
54
54
  end
55
55
  end
@@ -47,6 +47,10 @@ class CsvPirate
47
47
  attr_accessor :swabbie # value of the counter / timestamp
48
48
  attr_accessor :maroon # text of csv
49
49
  attr_accessor :nocturnal # basename of the filepath (i.e. filename)
50
+ attr_accessor :blackjack # Hash: Specify how you want your CSV header
51
+ # {:join => '-'} joins the method names called to get hte data for that column with '_' underscores.
52
+ # {:humanize => '-'} first joins as above, then humanizes the string
53
+ # {:array => ['col1',col2','col3'] Uses the column names provided in the array. If the array provided is too short defaults to :humanize =>'_'
50
54
 
51
55
  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
52
56
 
@@ -70,6 +74,10 @@ class CsvPirate
70
74
  # :clean - do not use :counter or :timestamp, and instead overwrite the file
71
75
  # :dirty - do not use :counter, or :timestamp, or :overwrite. Just keep adding on.
72
76
  # :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)?
77
+ # :blackjack Specify how you want your CSV header
78
+ # {:join => '-'} joins the method names called to get hte data for that column with '_' underscores.
79
+ # {:humanize =>'-'} first joins as above, then humanizes the string
80
+ # {:array => ['col1',col2','col3'] Uses the column names provided. If the array provided is too short defaults to :humanize =>'_'
73
81
  # See README for examples
74
82
 
75
83
  def initialize(*args)
@@ -113,6 +121,15 @@ class CsvPirate
113
121
  @bury_treasure = args.first[:astrolabe] || false
114
122
  @buried_treasure = []
115
123
 
124
+ #Default is different than default for has_csv_pirate because this might gem wants to be clean for use outside rails, and humanize may not always be defined for String class
125
+ @blackjack = args.first[:blackjack] || {:join => '_'}
126
+
127
+ #Make sure the header array is the same length as the booty columns
128
+ if self.blackjack.keys.first == :array && (self.blackjack.values.first.length != self.booty.length)
129
+ @blackjack = {:join => '_'}
130
+ puts "Warning: :blackjack reset to {:join => '_'} because the length of the :booty is different than the length of the array provided to :blackjack" if CsvPirate.parlance(2)
131
+ end
132
+
116
133
  # Initialize doesn't write anything to a CSV,
117
134
  # but does create the traverse_board and opens the waggoner for reading / writing
118
135
  self.northwest_passage unless self.astrolabe
@@ -144,6 +161,7 @@ class CsvPirate
144
161
  :spyglasses => args.first[:spyglasses],
145
162
  :booty => args.first[:booty],
146
163
  :astrolabe => args.first[:astrolabe],
164
+ :blackjack => args.first[:blackjack],
147
165
  :bury_treasure => args.first[:bury_treasure]
148
166
  })
149
167
  csv_pirate.hoist_mainstay()
@@ -225,8 +243,7 @@ class CsvPirate
225
243
  end
226
244
 
227
245
  def sounding(csv)
228
- # create the header of the CSV (column/method names)
229
- csv << self.booty
246
+ csv << self.block_and_tackle
230
247
  # create the data for the csv
231
248
  self.dig_for_treasure do |treasure|
232
249
  moidore = treasure.map {|x| "#{x}"}
@@ -235,6 +252,50 @@ class CsvPirate
235
252
  end
236
253
  end
237
254
 
255
+ # create the header of the CSV (column/method names)
256
+ # returns an array of strings for CSV header based on blackjack
257
+ def block_and_tackle
258
+ self.blackjack.map do |k,v|
259
+ case k
260
+ #Joining is only relevant when the booty contains a nested hash of method calls as at least one of the booty array elements
261
+ #Use the booty (methods) as the column headers
262
+ when :join then self.binnacle(v, false)
263
+ #Use the humanized booty (methods) as the column headers
264
+ when :humanize then self.binnacle(v, true)
265
+ when :array then v
266
+ end
267
+ end.first
268
+ end
269
+
270
+ #returns an array of strings for CSV header based on booty
271
+ def binnacle(join_value, humanize = true)
272
+ self.booty.map do |compass|
273
+ string = compass.is_a?(Hash) ?
274
+ self.run_through(compass, join_value) :
275
+ compass.is_a?(String) ?
276
+ compass :
277
+ compass.is_a?(Symbol) ?
278
+ compass.to_s :
279
+ compass.to_s
280
+ humanize ? string.humanize : string
281
+ end
282
+ end
283
+
284
+ #Takes a potentially nested hash element of a booty array and turns it into a string for a column header
285
+ # hash = {:a => {:b => {:c => {:d => {"e" => "fghi"}}}}}
286
+ # run_through(hash, '_')
287
+ # => "a_b_c_d_e_fghi"
288
+ # Ooooh so recursive!
289
+ def run_through(hash, join_value)
290
+ hash.map do |k,v|
291
+ if v.is_a?(Hash)
292
+ [k,run_through(v, join_value)].join(join_value)
293
+ else #works for Symbols and Strings
294
+ [k,v].join(join_value)
295
+ end
296
+ end.first
297
+ end
298
+
238
299
  #complete file path
239
300
  def poop_deck
240
301
  "#{self.analemma}#{self.swabbie}#{self.aft}"
@@ -25,6 +25,7 @@ module NinthBit
25
25
  # Have to protect against model definitions pre-migration, since column names will fail if
26
26
  options[:booty] ||= check_booty ? self.column_names : []
27
27
  options[:bury_treasure] ||= true
28
+ options[:blackjack] ||= {:humanize => '_'}
28
29
  options[:parlay] ||= 1
29
30
 
30
31
  # if they provide both
@@ -38,6 +39,7 @@ module NinthBit
38
39
  raise ArgumentError, ":booty is #{options[:booty].inspect}, and must be an array of methods to call on a class for CSV data" if check_booty && (options[:booty].nil? || !options[:booty].is_a?(Array) || options[:booty].empty?)
39
40
  raise ArgumentError, ":chart is #{options[:chart].inspect}, and must be an array of directory names, which will become the filepath for the csv file" if options[:chart].nil? || !options[:chart].is_a?(Array) || options[:chart].empty?
40
41
  raise ArgumentError, ":shrouds is #{options[:shrouds].inspect}, and must be a string (e.g. ',' or '\t'), which will be used as the delimeter for the csv file" if options[:shrouds].nil? || !options[:shrouds].is_a?(String)
42
+ raise ArgumentError, ":blackjack is #{options[:blackjack].inspect}, and must be a hash (e.g. {:humanize => '_'}), which defines how the header of the CSV will be created" if options[:blackjack].nil? || !options[:blackjack].is_a?(Hash)
41
43
 
42
44
  extend ClassMethods unless (class << self; included_modules; end).include?(ClassMethods)
43
45
 
@@ -54,7 +56,7 @@ module NinthBit
54
56
 
55
57
  # intended for use with send_data for downloading the text of the csv:
56
58
  # send_data Make.say_your_last_words
57
- # TODO: Fix say_yourr_last_words so it works! Use send_data args for real
59
+ # TODO: Fix say_your_last_words so it works! Use send_data args for real
58
60
  #def say_your_last_words(charset = 'utf-8', args = {})
59
61
  # csv_pirate = self.blindfold(args)
60
62
  # return [ csv_pirate.maroon,
@@ -109,6 +111,7 @@ module NinthBit
109
111
  :grub => args[:grub] || self.piratey_options[:grub],
110
112
  :spyglasses => args[:spyglasses] || self.piratey_options[:spyglasses],
111
113
  :booty => args[:booty] || self.piratey_options[:booty],
114
+ :blackjack => args[:blackjack] || self.piratey_options[:blackjack],
112
115
  :bury_treasure => args[:bury_treasure] || self.piratey_options[:bury_treasure] }
113
116
  end
114
117
 
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: 3.3.2
4
+ version: 3.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Boling
@@ -9,11 +9,11 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-11 00:00:00 -04:00
12
+ date: 2009-10-13 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: faster_csv
16
+ name: fastercsv
17
17
  type: :runtime
18
18
  version_requirement:
19
19
  version_requirements: !ruby/object:Gem::Requirement