csv_pirate 2.4.4 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ Version 2.5.1 2009-10-01
2
+ - Fixed bug with handling of Rails.root & RAILS_ROOT
3
+
4
+ Version 2.5.0 2009-10-01
5
+ - Added northwest_passage to create all the directories in :chart
6
+
1
7
  Version 2.4.1 2009-10-01
2
8
  - Fixed critical typo
3
9
 
data/README.rdoc CHANGED
@@ -5,30 +5,33 @@ Easily create CSVs of any data that can be derived from your models.
5
5
  CsvPirate is the easy way to create a CSV of essentially anything in Rails, in full pirate regalia.
6
6
  It works better if you are wearing a tricorne!
7
7
 
8
+ My goal is to have it do EVERYTHING it possibly can for me, since almost every project I do needs CSV exports.
9
+
8
10
  CsvPirate only works for commissions of swag OR grub!
9
11
 
10
12
  Initialize method (a.k.a new()) takes a hash of params:
11
13
 
12
14
  # 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
15
+ # :swag the ARrr collection of swag to work on (optional)
16
+ # :grub the ARrr class that the spyglasses will be used on (optional)
17
+ # :spyglasses named scopes in your model that will refine the rows in the CSV according to conditions of the spyglasses,
18
+ # and order them according to the order of the spyglasses (optional)
19
+ # :booty booty (columns/methods) on your model that you want printed in the CSV, also used to create the figurehead (CSV header)
20
+ # :chart array of directory names (relative to rails root if using rails) which will be the filepath where you want to hide your loot
21
+ # :wagonner name of document where you will give detailed descriptions of the loot
22
+ # :aft filename extention ('.csv')
23
+ # :shrouds CSV column separator, default is ','. For tsv, tab-delimited, "\t"
24
+ # :chronometer keeps track of when you hunt for treasure
25
+ # :gibbet filename spacer after the date, and before the iterative counter/timestamp. MuST contain a '.'
26
+ # :swab can be :counter, :timestamp, or :none
25
27
  # :counter - default, each successive run will create a new file using a counter
26
28
  # :timestamp - each successive run will create a new file using a HHMMSS time stamp
27
29
  # :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
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
29
31
  # :clear - do not use :counter or :timestamp, and instead overwrite the file
30
32
  # :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!
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
+ # check the source to see if there anything else hiding in there!
32
35
 
33
36
  The create method has the same parameters, and actually creates the CSV.
34
37
 
@@ -71,6 +74,13 @@ Plugin using Git:
71
74
  ruby script/plugin install git://github.com/pboling/csv_pirate.git
72
75
 
73
76
 
77
+ == Upgrading
78
+
79
+ In older versions :chart was a string which indicated where you wanted to hide the loot (write the csv file)
80
+ Now it must be an array of directory names. So if you want your loot in "log/csv/pirates/model_name", then chart is:
81
+ ['log','csv','pirates','model_name']
82
+ CsvPirate ensures that whatever you choose as your chart exists in the filesystem, and creates the directories if need be.
83
+
74
84
  == Example & Usage
75
85
 
76
86
  Assuming a Make (as in manufacturers of automobiles) model like this:
@@ -152,7 +162,7 @@ The following two sets of code are identical:
152
162
  :spyglasses => [:active,:logged_in],
153
163
  :waggoner => 'active_users_logged_in',
154
164
  :booty => ["id","number","login","created_at"],
155
- :chart => 'log/csv/'
165
+ :chart => ['log','csv']
156
166
  })
157
167
  csv_pirate.hoist_mainstay() # creates CSV file and writes out the rows
158
168
 
@@ -161,7 +171,7 @@ The following two sets of code are identical:
161
171
  :spyglasses => [:active,:logged_in],
162
172
  :waggoner => 'active_users_logged_in',
163
173
  :booty => ["id","number","login","created_at"],
164
- :chart => 'log/csv/'
174
+ :chart => ['log','csv']
165
175
  })# creates CSV file and writes out the rows
166
176
 
167
177
  Another example using swag instead of grub:
@@ -171,7 +181,7 @@ Another example using swag instead of grub:
171
181
  :swag => users,
172
182
  :waggoner => 'inactive_users_not_logged_in',
173
183
  :booty => ["id","number","login","created_at"],
174
- :chart => 'log/csv/'
184
+ :chart => ['log','csv']
175
185
  })
176
186
  csv_pirate.hoist_mainstay()
177
187
 
@@ -181,11 +191,11 @@ Then if you want to get your hands on the loot immediately:
181
191
 
182
192
  For those who can't help but copy/paste into console and then edit:
183
193
 
184
- csv_pirate = CsvPirate.new({:grub => User,:spyglasses => [:active,:logged_in],:waggoner => 'active_users_logged_in',:booty => ["id","number","login","created_at"],:chart => 'log/csv/'})
194
+ csv_pirate = CsvPirate.new({:grub => User,:spyglasses => [:active,:logged_in],:waggoner => 'active_users_logged_in',:booty => ["id","number","login","created_at"],:chart => ['log','csv']})
185
195
 
186
196
  OR
187
197
 
188
- csv_pirate = CsvPirate.new({:swag => users,:waggoner => 'inactive_users_not_logged_in',:booty => ["id","number","login","created_at"],:chart => 'log/csv/'})
198
+ csv_pirate = CsvPirate.new({:swag => users,:waggoner => 'inactive_users_not_logged_in',:booty => ["id","number","login","created_at"],:chart => ['log','csv']})
189
199
 
190
200
 
191
201
  == Downloading the CSV
@@ -257,7 +267,7 @@ You have a VehicleModel class and the same Make class as up above:
257
267
 
258
268
  Then to create the CSV:
259
269
 
260
- a = VehicleModel.walk_the_plank
270
+ a = VehicleModel.blindfold
261
271
 
262
272
  Then check the output from the console:
263
273
 
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 4
3
- :major: 2
4
- :minor: 4
2
+ :patch: 0
3
+ :major: 3
4
+ :minor: 1
data/csv_pirate.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{csv_pirate}
8
- s.version = "2.4.4"
8
+ s.version = "3.1.0"
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"]
data/lib/csv_pirate.rb CHANGED
@@ -15,7 +15,7 @@ class CsvPirate
15
15
  MOP_HEADS = [:clean, :dirty]
16
16
 
17
17
  attr_accessor :waggoner #filename
18
- attr_accessor :chart #directory, default is ('log/')
18
+ attr_accessor :chart #directory, default is (['log','csv'])
19
19
  attr_accessor :aft #extension, default is ('.csv')
20
20
  attr_accessor :gibbet #part of the filename after waggoner and date, before swabbie and aft
21
21
  attr_accessor :chronometer
@@ -56,7 +56,7 @@ class CsvPirate
56
56
  # :spyglasses named scopes in your model that will refine the rows in the CSV according to conditions of the spyglasses,
57
57
  # and order them according to the order of the spyglasses (optional)
58
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
59
+ # :chart array of directory names (relative to rails root if using rails) which will be the filepath where you want to hide your loot
60
60
  # :wagonner name of document where you will give detailed descriptions of the loot
61
61
  # :aft filename extention ('.csv')
62
62
  # :shrouds CSV column separator, default is ','. For tsv, tab-delimited, "\t"
@@ -92,13 +92,15 @@ class CsvPirate
92
92
  @gibbet = args.first[:gibbet] || '.export'
93
93
  raise ArgumentError, ":gibbet is #{args.first[:gibbet].inspect}, and does not contain a '.' character, which is required for iterative filenames" if args.first[:gibbet].nil? || !args.first[:gibbet].include?('.')
94
94
 
95
- @waggoner = args.first[:waggoner] || "#{self.grub}"
95
+ @waggoner = args.first[:waggoner] || "#{self.grub || self.swag}"
96
96
  raise ArgumentError, ":waggoner is #{args.first[:waggoner].inspect}, and must be a string at least one character long" if args.first[:waggoner].nil? || args.first[:waggoner].length < 1
97
97
 
98
98
  @booty = args.first[:booty] || []
99
- raise ArgumentError, ":booty is #{args.first[:booty].inspect}, and must be an array of methods to call on a class for CSV data" if args.first[:booty].nil? || args.first[:booty].empty?
99
+ raise ArgumentError, ":booty is #{args.first[:booty].inspect}, and must be an array of methods to call on a class for CSV data" if args.first[:booty].nil? || !args.first[:booty].is_a?(Array) || args.first[:booty].empty?
100
+
101
+ @chart = args.first[:chart] || ['log','csv']
102
+ raise ArgumentError, ":chart is #{args.first[:chart].inspect}, and must be an array of directory names, which will become the filepath for the csv file" if args.first[:chart].nil? || !args.first[:chart].is_a?(Array) || args.first[:booty].empty?
100
103
 
101
- @chart = args.first[:chart] || 'log/'
102
104
  @aft = args.first[:aft] || '.csv'
103
105
  @chronometer = args.first[:chronometer] || Date.today
104
106
 
@@ -112,7 +114,7 @@ class CsvPirate
112
114
 
113
115
  # Initialize doesn't write anything to a CSV,
114
116
  # but does create the traverse_board and opens the waggoner for reading / writing
115
- Dir.mkdir(self.traverse_board) if !self.astrolabe && Dir.glob(self.traverse_board).empty?
117
+ self.northwest_passage unless self.astrolabe
116
118
 
117
119
  # This will contain the text of the csv from this particular execution
118
120
  @maroon = ""
@@ -232,28 +234,11 @@ class CsvPirate
232
234
  end
233
235
  end
234
236
 
235
- def traverse_board
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}"
238
- end
239
-
240
- def sand_glass
241
- "#{self.chronometer.respond_to?(:strftime) ? '.' + self.chronometer.strftime("%Y%m%d") : ''}"
242
- end
243
-
244
237
  #complete file path
245
238
  def poop_deck
246
239
  "#{self.analemma}#{self.swabbie}#{self.aft}"
247
240
  end
248
241
 
249
- def merchantman
250
- "#{self.waggoner}#{self.sand_glass}#{self.gibbet}"
251
- end
252
-
253
- def analemma
254
- "#{self.traverse_board}#{self.merchantman}"
255
- end
256
-
257
242
  # Swabs the poop_deck if the mop is clean. (!)
258
243
  def swab_poop_deck
259
244
  self.rhumb_lines.truncate(0) if self.swab == :none && self.mop == :clean && File.size(self.poop_deck) > 0
@@ -274,6 +259,34 @@ class CsvPirate
274
259
 
275
260
  protected
276
261
 
262
+ def traverse_board
263
+ #If we have rails environment then we use rails root, otherwise self.chart stands on its own as a relative path
264
+ "#{self.north_pole}#{self.chart.join('/')}/"
265
+ end
266
+
267
+ def sand_glass
268
+ "#{self.chronometer.respond_to?(:strftime) ? '.' + self.chronometer.strftime("%Y%m%d") : ''}"
269
+ end
270
+
271
+ def merchantman
272
+ "#{self.waggoner}#{self.sand_glass}#{self.gibbet}"
273
+ end
274
+
275
+ def analemma
276
+ "#{self.traverse_board}#{self.merchantman}"
277
+ end
278
+
279
+ def north_pole
280
+ "#{defined?(Rails) ? "#{Rails.root}/" : defined?(RAILS_ROOT) ? "#{RAILS_ROOT}/" : ''}"
281
+ end
282
+
283
+ def northwest_passage
284
+ self.chart.length.times do |i|
285
+ north_star = self.north_pole + self.chart[0..i].join('/')
286
+ Dir.mkdir(north_star) if Dir.glob(north_star).empty?
287
+ end
288
+ end
289
+
277
290
  def lantern
278
291
  "#{self.analemma}.*"
279
292
  end
@@ -372,7 +385,7 @@ class CsvPirate
372
385
  # :spyglasses => is the column to load ("find_by_#{booty}") the ARrr object for each row on the first CSV
373
386
  # (swag OR spyglasses can be specified, but code defers to swag if provided)
374
387
  # :waggoner => where the capn's loot was stashed (filename)
375
- # :chart => directory where capn's waggoner is located
388
+ # :chart => array of directory names where capn's waggoner is located
376
389
  # :astrolabe => true (file is opened at top of file in read only mode when true)
377
390
  # The first_mate hash is:
378
391
  # :grub => is the class on which to make booty [method] calls, or
@@ -382,23 +395,23 @@ class CsvPirate
382
395
  # :spyglasses => is the column to load ("find_by_#{booty}") the ARrr object for each row on the second CSV (if grub is a class)
383
396
  # :booty => is the methods to call on the ARrr object for each row on the second CSV
384
397
  # :waggoner => where to stash the first mate's loot (filename)
385
- # :chart => directory where first mate's waggoner is located
398
+ # :chart => array of directory names where first mate's waggoner is located
386
399
  # :astrolabe => false (false is the default for astrolabe, so we could leave it off the first_mate)
387
400
  #
388
401
  # Example:
389
- # capn = {:grub => User,:spyglasses => [:inactive],:booty => ['id','login','status'],:waggoner => 'orig',:chart => 'log/csv/',:astrolabe => false}
402
+ # capn = {:grub => User,:spyglasses => [:inactive],:booty => ['id','login','status'],:waggoner => 'orig',:chart => ['log','csv'],:astrolabe => false}
390
403
  # make_orig = CsvPirate.new(capn)
391
404
  # make_orig.hoist_mainstay
392
405
  # make_orig.weigh_anchor
393
406
  #
394
- # first_mate = {:grub => 'account',:booty => ["id","number","name","created_at"],:waggoner => 'fake',:chart => 'log/csv/'}
407
+ # first_mate = {:grub => 'account',:booty => ["id","number","name","created_at"],:waggoner => 'fake',:chart => ['log','csv']}
395
408
  # OR
396
409
  # # for same class, we re-use the object loaded from first CSV and make the booty [method] calls on it
397
- # first_mate = {:grub => User,:booty => ["id","login","visits_count"],:waggoner => 'fake',:chart => 'log/csv/'}
410
+ # first_mate = {:grub => User,:booty => ["id","login","visits_count"],:waggoner => 'fake',:chart => ['log','csv']}
398
411
  # OR
399
- # first_mate = {:grub => Account,:spyglasses => 'id',:swag=>'user_id',:booty => ["id","name","number"],:waggoner => 'fake',:chart => 'log/csv/'}
412
+ # first_mate = {:grub => Account,:spyglasses => 'id',:swag=>'user_id',:booty => ["id","name","number"],:waggoner => 'fake',:chart => ['log','csv']}
400
413
  # AND
401
- # capn = {:grub => User,:spyglasses => 'login',:swag => 1,:waggoner => 'orig',:chart => 'log/csv/',:astrolabe => true}
414
+ # capn = {:grub => User,:spyglasses => 'login',:swag => 1,:waggoner => 'orig',:chart => ['log','csv'],:astrolabe => true}
402
415
  # after_mutiny = CsvPirate.mutiny(capn, first_mate)
403
416
  #
404
417
  def self.mutiny(capn, first_mate)
@@ -6,7 +6,7 @@ module NinthBit
6
6
  def has_csv_pirate_ship(options = {})
7
7
  raise ArgumentError, "must provide required options" if options.blank?
8
8
 
9
- options[:chart] ||= 'log/'
9
+ options[:chart] ||= ['log','csv']
10
10
  options[:aft] ||= '.csv'
11
11
  options[:gibbet] ||= '.export'
12
12
  #Needs to be defined at runtime, doesn't make sense here
@@ -30,7 +30,8 @@ module NinthBit
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?('.')
32
32
  raise ArgumentError, ":waggoner is #{options[:waggoner].inspect}, and must be a string at least one character long" if options[:waggoner].nil? || options[:waggoner].length < 1
33
- raise ArgumentError, ":booty is #{options[:booty].inspect}, and must be an array of methods to call on a class for CSV data" if options[:booty].nil? || options[:booty].empty?
33
+ raise ArgumentError, ":booty is #{options[:booty].inspect}, and must be an array of methods to call on a class for CSV data" if options[:booty].nil? || !options[:booty].is_a?(Array) || options[:booty].empty?
34
+ 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?
34
35
 
35
36
  extend ClassMethods unless (class << self; included_modules; end).include?(ClassMethods)
36
37
 
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.4.4
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Boling