lib/csv_pirate.rb in csv_pirate-2.4.4 vs lib/csv_pirate.rb in csv_pirate-3.1.0

- old
+ new

@@ -13,11 +13,11 @@ BOOKIE = [:counter, :timestamp, :none] MOP_HEADS = [:clean, :dirty] attr_accessor :waggoner #filename - attr_accessor :chart #directory, default is ('log/') + attr_accessor :chart #directory, default is (['log','csv']) attr_accessor :aft #extension, default is ('.csv') attr_accessor :gibbet #part of the filename after waggoner and date, before swabbie and aft attr_accessor :chronometer # Must provide swag or grub (not both) @@ -54,11 +54,11 @@ # :swag the ARrr collection of swag to work on (optional) # :grub the ARrr class that the spyglasses will be used on (optional) # :spyglasses named scopes in your model that will refine the rows in the CSV according to conditions of the spyglasses, # and order them according to the order of the spyglasses (optional) # :booty booty (columns/methods) on your model that you want printed in the CSV, also used to create the figurehead (CSV header) - # :chart name of directory where you want to hide your loot + # :chart array of directory names (relative to rails root if using rails) which will be the filepath where you want to hide your loot # :wagonner name of document where you will give detailed descriptions of the loot # :aft filename extention ('.csv') # :shrouds CSV column separator, default is ','. For tsv, tab-delimited, "\t" # :chronometer keeps track of when you hunt for treasure # :gibbet filename spacer after the date, and before the iterative counter/timestamp. MuST contain a '.' @@ -90,17 +90,19 @@ raise ArgumentError, ":mop is #{args.first[:mop].inspect}, but must be one of #{CsvPirate::MOP_HEADS.inspect}" unless CsvPirate::MOP_HEADS.include?(args.first[:mop]) @gibbet = args.first[:gibbet] || '.export' 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?('.') - @waggoner = args.first[:waggoner] || "#{self.grub}" + @waggoner = args.first[:waggoner] || "#{self.grub || self.swag}" 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 @booty = args.first[:booty] || [] - 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? + 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? - @chart = args.first[:chart] || 'log/' + @chart = args.first[:chart] || ['log','csv'] + 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? + @aft = args.first[:aft] || '.csv' @chronometer = args.first[:chronometer] || Date.today @spyglasses = (args.first[:spyglasses] || [:all]) if self.grub @shrouds = args.first[:shrouds] || ',' # for tsv, tab-delimited, "\t" @@ -110,11 +112,11 @@ @bury_treasure = args.first[:astrolabe] || false @buried_treasure = [] # Initialize doesn't write anything to a CSV, # but does create the traverse_board and opens the waggoner for reading / writing - Dir.mkdir(self.traverse_board) if !self.astrolabe && Dir.glob(self.traverse_board).empty? + self.northwest_passage unless self.astrolabe # This will contain the text of the csv from this particular execution @maroon = "" # Once the traverse_board (dir) exists, then check if the rhumb_lines (file) already exists, and set our rhumb_lines counter @@ -230,32 +232,15 @@ csv << moidore # |x| marks the spot! self.buried_treasure << moidore if self.bury_treasure end end - def traverse_board - #If we have rails environment then we use rails root, otherwise self.chart stands on its own as a relative path - "#{defined?(Rails) ? Rails.root + '/' : defined?(RAILS_ROOT) ? RAILS_ROOT + '/' : ''}#{self.chart}" - end - - def sand_glass - "#{self.chronometer.respond_to?(:strftime) ? '.' + self.chronometer.strftime("%Y%m%d") : ''}" - end - #complete file path def poop_deck "#{self.analemma}#{self.swabbie}#{self.aft}" end - def merchantman - "#{self.waggoner}#{self.sand_glass}#{self.gibbet}" - end - - def analemma - "#{self.traverse_board}#{self.merchantman}" - end - # Swabs the poop_deck if the mop is clean. (!) def swab_poop_deck self.rhumb_lines.truncate(0) if self.swab == :none && self.mop == :clean && File.size(self.poop_deck) > 0 end @@ -272,10 +257,38 @@ end end protected + def traverse_board + #If we have rails environment then we use rails root, otherwise self.chart stands on its own as a relative path + "#{self.north_pole}#{self.chart.join('/')}/" + end + + def sand_glass + "#{self.chronometer.respond_to?(:strftime) ? '.' + self.chronometer.strftime("%Y%m%d") : ''}" + end + + def merchantman + "#{self.waggoner}#{self.sand_glass}#{self.gibbet}" + end + + def analemma + "#{self.traverse_board}#{self.merchantman}" + end + + def north_pole + "#{defined?(Rails) ? "#{Rails.root}/" : defined?(RAILS_ROOT) ? "#{RAILS_ROOT}/" : ''}" + end + + def northwest_passage + self.chart.length.times do |i| + north_star = self.north_pole + self.chart[0..i].join('/') + Dir.mkdir(north_star) if Dir.glob(north_star).empty? + end + end + def lantern "#{self.analemma}.*" end def filibuster(flotsam) @@ -370,36 +383,36 @@ # :swag => column index in CSV (0th, 1st, 2nd, etc. column?) # (swag OR spyglasses can be specified, but code defers to swag if provided) # :spyglasses => is the column to load ("find_by_#{booty}") the ARrr object for each row on the first CSV # (swag OR spyglasses can be specified, but code defers to swag if provided) # :waggoner => where the capn's loot was stashed (filename) - # :chart => directory where capn's waggoner is located + # :chart => array of directory names where capn's waggoner is located # :astrolabe => true (file is opened at top of file in read only mode when true) # The first_mate hash is: # :grub => is the class on which to make booty [method] calls, or # is a method (as a string) we call to get from the object loaded by capn, # to the object on which we'll make the first_mate booty [method] calls, or nil, if same object # :swag => is the method to call on first CSV row's object to find second CSV row's object (if grub is a class) # :spyglasses => is the column to load ("find_by_#{booty}") the ARrr object for each row on the second CSV (if grub is a class) # :booty => is the methods to call on the ARrr object for each row on the second CSV # :waggoner => where to stash the first mate's loot (filename) - # :chart => directory where first mate's waggoner is located + # :chart => array of directory names where first mate's waggoner is located # :astrolabe => false (false is the default for astrolabe, so we could leave it off the first_mate) # # Example: -# capn = {:grub => User,:spyglasses => [:inactive],:booty => ['id','login','status'],:waggoner => 'orig',:chart => 'log/csv/',:astrolabe => false} +# capn = {:grub => User,:spyglasses => [:inactive],:booty => ['id','login','status'],:waggoner => 'orig',:chart => ['log','csv'],:astrolabe => false} # make_orig = CsvPirate.new(capn) # make_orig.hoist_mainstay # make_orig.weigh_anchor # -# first_mate = {:grub => 'account',:booty => ["id","number","name","created_at"],:waggoner => 'fake',:chart => 'log/csv/'} +# first_mate = {:grub => 'account',:booty => ["id","number","name","created_at"],:waggoner => 'fake',:chart => ['log','csv']} # OR # # for same class, we re-use the object loaded from first CSV and make the booty [method] calls on it -# first_mate = {:grub => User,:booty => ["id","login","visits_count"],:waggoner => 'fake',:chart => 'log/csv/'} +# first_mate = {:grub => User,:booty => ["id","login","visits_count"],:waggoner => 'fake',:chart => ['log','csv']} # OR -# first_mate = {:grub => Account,:spyglasses => 'id',:swag=>'user_id',:booty => ["id","name","number"],:waggoner => 'fake',:chart => 'log/csv/'} +# first_mate = {:grub => Account,:spyglasses => 'id',:swag=>'user_id',:booty => ["id","name","number"],:waggoner => 'fake',:chart => ['log','csv']} # AND -# capn = {:grub => User,:spyglasses => 'login',:swag => 1,:waggoner => 'orig',:chart => 'log/csv/',:astrolabe => true} +# capn = {:grub => User,:spyglasses => 'login',:swag => 1,:waggoner => 'orig',:chart => ['log','csv'],:astrolabe => true} # after_mutiny = CsvPirate.mutiny(capn, first_mate) # def self.mutiny(capn, first_mate) carrack = CsvPirate.new(capn) cutthroat = CsvPirate.new(first_mate)