csv_pirate 3.1.1 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +13 -0
- data/README.rdoc +131 -9
- data/VERSION.yml +2 -2
- data/csv_pirate.gemspec +2 -2
- data/lib/csv_pirate.rb +38 -32
- data/lib/ninth_bit/pirate_ship.rb +24 -13
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
Version 3.3.0 2009-10-05
|
2
|
+
- Fixed ArgumentError bugs in Initializer and has_csv_pirate_ship
|
3
|
+
- Fixed typo in piratey_args
|
4
|
+
- Major enhancements to documentation
|
5
|
+
- Now complete control over filename is possible
|
6
|
+
|
7
|
+
Version 3.2.1 2009-10-04
|
8
|
+
- Fixed bug in parlay by creating method parlance
|
9
|
+
|
10
|
+
Version 3.2.0 2009-10-01
|
11
|
+
- Fixed typo in documentation
|
12
|
+
- Added land_ho method!
|
13
|
+
|
1
14
|
Version 3.1.1 2009-10-01
|
2
15
|
- Readme Cleanup
|
3
16
|
- Removing broken say_your_last_words method
|
data/README.rdoc
CHANGED
@@ -28,7 +28,7 @@ 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
|
-
# :
|
31
|
+
# :clean - do not use :counter or :timestamp, and instead overwrite the file
|
32
32
|
# :dirty - do not use :counter, or :timestamp, or :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
34
|
# check the source to see if there anything else hiding in there!
|
@@ -52,6 +52,10 @@ Release Announcement:
|
|
52
52
|
|
53
53
|
== Installation
|
54
54
|
|
55
|
+
Gem from Gemcutter (after setting up your machine to use the gemcutter repo, see http://gemcutter.org):
|
56
|
+
|
57
|
+
sudo gem install csv_pirate
|
58
|
+
|
55
59
|
Gem Using Git building from source:
|
56
60
|
|
57
61
|
mkdir -p ~/src
|
@@ -59,7 +63,7 @@ Gem Using Git building from source:
|
|
59
63
|
git clone git://github.com/pboling/csv_pirate.git
|
60
64
|
cd csv_pirate
|
61
65
|
gem build csv_pirate.gemspec
|
62
|
-
sudo gem install csv_pirate-
|
66
|
+
sudo gem install csv_pirate-3.3.0.gem # (Or whatever version gets built)
|
63
67
|
|
64
68
|
Then cd to your rails app to optionally freeze the gem into your app:
|
65
69
|
|
@@ -73,6 +77,7 @@ Plugin using Git:
|
|
73
77
|
|
74
78
|
ruby script/plugin install git://github.com/pboling/csv_pirate.git
|
75
79
|
|
80
|
+
If installed as a gem load it with config.gem 'csv_pirate' # or 'pboling-csv_pirate' if from github
|
76
81
|
|
77
82
|
== Upgrading
|
78
83
|
|
@@ -81,7 +86,73 @@ Plugin using Git:
|
|
81
86
|
['log','csv','pirates','model_name']
|
82
87
|
CsvPirate ensures that whatever you choose as your chart exists in the filesystem, and creates the directories if need be.
|
83
88
|
|
84
|
-
==
|
89
|
+
== Usage with ActiveRecord
|
90
|
+
|
91
|
+
What's the simplest thing that'll work?
|
92
|
+
|
93
|
+
class MyClass < ActiveRecord::Base
|
94
|
+
has_csv_pirate_ship # defaults to csv of all columns of all records
|
95
|
+
end
|
96
|
+
|
97
|
+
MyClass.blindfold # creates the csv, and returns the CsvPirate instance
|
98
|
+
MyClass.walk_the_plank # creates the csv, and returns contents of the exported data (that was written into the csv) (as a string)
|
99
|
+
MyClass.land_ho # Does Not create the csv, sets up the CsvPirate instance. You can manipulate it and then call .hoist_mainstay on it to create the csv
|
100
|
+
|
101
|
+
== Usage without ActiveRecord
|
102
|
+
|
103
|
+
Since the defaults assume an active record class you need to override some of them:
|
104
|
+
|
105
|
+
class Star
|
106
|
+
extend NinthBit::PirateShip::ActMethods
|
107
|
+
has_csv_pirate_ship :booty => [:name, :distance, :spectral_type, {:name => :hash}, {:name => :next}, {:name => :upcase}, :star_vowels],
|
108
|
+
:spyglasses => [:get_stars]
|
109
|
+
|
110
|
+
attr_accessor :name, :distance, :spectral_type
|
111
|
+
|
112
|
+
def initialize(*args)
|
113
|
+
@name = args.first[:name]
|
114
|
+
@distance = args.first[:distance]
|
115
|
+
@spectral_type = args.first[:spectral_type]
|
116
|
+
end
|
117
|
+
|
118
|
+
def star_vowels
|
119
|
+
self.name.tr('aeiou', '*')
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.get_stars
|
123
|
+
[
|
124
|
+
Star.new(:name => "Proxima Centauri", :distance => "4.2 LY", :spectral_type => "M5.5Vc"),
|
125
|
+
Star.new(:name => "Rigil Kentaurus", :distance => "4.3 LY", :spectral_type => "G2V"),
|
126
|
+
Star.new(:name => "Barnard's Star", :distance => "5.9 LY", :spectral_type => "M3.8V"),
|
127
|
+
Star.new(:name => "Wolf 359", :distance => "7.7 LY", :spectral_type => "M5.8Vc"),
|
128
|
+
Star.new(:name => "Lalande 21185", :distance => "8.26 LY", :spectral_type => "M2V"),
|
129
|
+
Star.new(:name => "Luyten 726-8A and B", :distance => "8.73 LY", :spectral_type => "M5.5 de & M6 Ve"),
|
130
|
+
Star.new(:name => "Sirius A and B", :distance => "8.6 LY", :spectral_type => "A1Vm"),
|
131
|
+
Star.new(:name => "Ross 154", :distance => "9.693 LY", :spectral_type => "M3.5"),
|
132
|
+
Star.new(:name => "Ross 248", :distance => "10.32 LY", :spectral_type => "M5.5V"),
|
133
|
+
Star.new(:name => "Epsilon Eridani", :distance => "10.5 LY", :spectral_type => "K2V")
|
134
|
+
]
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
rails development >a = Star.blindfold
|
140
|
+
=> #<CsvPirate:0x2209098 @buried_treasure=[], @mop=:clean, @spyglasses=[:get_stars], @swabbie=".3", @booty=[:name, :distance, :spectral_type, {:name=>:hash}, {:name=>:next}, {:name=>:upcase}, :star_vowels], @bury_treasure=false, @swab=:counter, @chronometer=Sun, 04 Oct 2009, @maroon="name,distance,spectral_type,namehash,namenext,nameupcase,star_vowels\nProxima Centauri,4.2 LY,M5.5Vc,971295636,Proxima Centaurj,PROXIMA CENTAURI,Pr*x*m* C*nt**r*\nRigil Kentaurus,4.3 LY,G2V,-231389024,Rigil Kentaurut,RIGIL KENTAURUS,R*g*l K*nt**r*s\nBarnard's Star,5.9 LY,M3.8V,1003964756,Barnard's Stas,BARNARD'S STAR,B*rn*rd's St*r\nWolf 359,7.7 LY,M5.8Vc,429493790,Wolf 360,WOLF 359,W*lf 359\nLalande 21185,8.26 LY,M2V,466625069,Lalande 21186,LALANDE 21185,L*l*nd* 21185\nLuyten 726-8A and B,8.73 LY,M5.5 de & M6 Ve,-886693495,Luyten 726-8A and C,LUYTEN 726-8A AND B,L*yt*n 726-8A *nd B\nSirius A and B,8.6 LY,A1Vm,-969980943,Sirius A and C,SIRIUS A AND B,S*r**s A *nd B\nRoss 154,9.693 LY,M3.5,-26506942,Ross 155,ROSS 154,R*ss 154\nRoss 248,10.32 LY,M5.5V,-18054910,Ross 249,ROSS 248,R*ss 248\nEpsilon Eridani,10.5 LY,K2V,931307088,Epsilon Eridanj,EPSILON ERIDANI,Eps*l*n Er*d*n*\n", @waggoner="Star", @astrolabe=false, @grub=Star, @rhumb_lines=#<File:/Users/pboling/RubymineProjects/empty_csv_pirate_app/log/csv/Star.20091004.export.3.csv (closed)>, @nocturnal="Star.20091004.export.3.csv", @aft=".csv", @gibbet=".export", @shrouds=",", @swag=[#<Star:0x2202db0 @spectral_type="M5.5Vc", @distance="4.2 LY", @name="Proxima Centauri">, #<Star:0x2202d10 @spectral_type="G2V", @distance="4.3 LY", @name="Rigil Kentaurus">, #<Star:0x2202c98 @spectral_type="M3.8V", @distance="5.9 LY", @name="Barnard's Star">, #<Star:0x2202c20 @spectral_type="M5.8Vc", @distance="7.7 LY", @name="Wolf 359">, #<Star:0x2202ba8 @spectral_type="M2V", @distance="8.26 LY", @name="Lalande 21185">, #<Star:0x2202b30 @spectral_type="M5.5 de & M6 Ve", @distance="8.73 LY", @name="Luyten 726-8A and B">, #<Star:0x2202ab8 @spectral_type="A1Vm", @distance="8.6 LY", @name="Sirius A and B">, #<Star:0x2202a40 @spectral_type="M3.5", @distance="9.693 LY", @name="Ross 154">, #<Star:0x22029c8 @spectral_type="M5.5V", @distance="10.32 LY", @name="Ross 248">, #<Star:0x2202950 @spectral_type="K2V", @distance="10.5 LY", @name="Epsilon Eridani">], @chart=["log", "csv"]>
|
141
|
+
rails development >a.weigh_anchor
|
142
|
+
name,distance,spectral_type,namehash,namenext,nameupcase,star_vowels
|
143
|
+
Proxima Centauri,4.2 LY,M5.5Vc,971295636,Proxima Centaurj,PROXIMA CENTAURI,Pr*x*m* C*nt**r*
|
144
|
+
Rigil Kentaurus,4.3 LY,G2V,-231389024,Rigil Kentaurut,RIGIL KENTAURUS,R*g*l K*nt**r*s
|
145
|
+
Barnard's Star,5.9 LY,M3.8V,1003964756,Barnard's Stas,BARNARD'S STAR,B*rn*rd's St*r
|
146
|
+
Wolf 359,7.7 LY,M5.8Vc,429493790,Wolf 360,WOLF 359,W*lf 359
|
147
|
+
Lalande 21185,8.26 LY,M2V,466625069,Lalande 21186,LALANDE 21185,L*l*nd* 21185
|
148
|
+
Luyten 726-8A and B,8.73 LY,M5.5 de & M6 Ve,-886693495,Luyten 726-8A and C,LUYTEN 726-8A AND B,L*yt*n 726-8A *nd B
|
149
|
+
Sirius A and B,8.6 LY,A1Vm,-969980943,Sirius A and C,SIRIUS A AND B,S*r**s A *nd B
|
150
|
+
Ross 154,9.693 LY,M3.5,-26506942,Ross 155,ROSS 154,R*ss 154
|
151
|
+
Ross 248,10.32 LY,M5.5V,-18054910,Ross 249,ROSS 248,R*ss 248
|
152
|
+
Epsilon Eridani,10.5 LY,K2V,931307088,Epsilon Eridanj,EPSILON ERIDANI,Eps*l*n Er*d*n*
|
153
|
+
=> #<File:/Users/pboling/RubymineProjects/empty_csv_pirate_app/log/csv/Star.20091004.export.3.csv (closed)>
|
154
|
+
|
155
|
+
== Advanced Usage & Examples
|
85
156
|
|
86
157
|
Assuming a Make (as in manufacturers of automobiles) model like this:
|
87
158
|
|
@@ -99,8 +170,29 @@ Assuming a Make (as in manufacturers of automobiles) model like this:
|
|
99
170
|
has_many :vehicle_models
|
100
171
|
named_scope :factory_in_germany, :conditions => ["factory = ?", "Germany"]
|
101
172
|
|
102
|
-
|
103
|
-
|
173
|
+
# Showing all available options with their default values
|
174
|
+
has_csv_pirate_ship :chart => ['log','csv'] # Array of Strings: directory where csv will be created (Yes, it creates all of them if they do not already exist)
|
175
|
+
:aft => '.csv' # String: filename extension, usually this would be '.csv', but can be whatever you want.
|
176
|
+
:gibbet => '.export' # String: Middle part of the filename {the '.' is required for iterative filenames, set :swab => :none to turn off iterative filenames}
|
177
|
+
# Comes after waggoner and chronometer, before swabbie and aft
|
178
|
+
:waggoner => "#{Make}" # String: First part of filename
|
179
|
+
|
180
|
+
# Must provide :swag or :grub (not both)
|
181
|
+
:swag => nil # Array of objects: to use to create the CSV (i.e. you've already done the query and have the results you want a CSV of)
|
182
|
+
:grub => Make # Class: on which to call the method chain in :spyglasses that will return the array of objects to be placed in :swag by CsvPirate (See description of swag above).
|
183
|
+
:spyglasses => [:all] # Array of symbols/strings: Methods that will be chained together and called on :grub in order to get the :swag records which will become the rows of the CSV.
|
184
|
+
:booty => Make.column_names # Array of symbols/strings or nested hashes of symbols/strings: Methods to call on each object in :swag. These become the columns of the CSV. The method names become the CSV column headings. Methods can be chained to dig deep (e.g. traverse several ActiveRecord associations) to get at a value for the CSV.
|
185
|
+
|
186
|
+
:swab => :counter # Symbol: What kind of file counter to use to avoid overwtiting the CSV file, :counter is Integer, :timestamp is HHMMSS, :none is no file counter, increasing the liklihood of duplicate filenames on successive csv exports.
|
187
|
+
: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
|
+
:shrouds => ',' # String: Delimiter for CSV. '\t' will create a tab delimited file (tsv), '|' will create a pipe delimited file.
|
189
|
+
:bury_treasure => true # Boolean: Should the array of objects in :swag be stored in the CsvPirate object for later inspection?
|
190
|
+
|
191
|
+
# A customized version to create a tab delimited file for this class might look like this:
|
192
|
+
# has_csv_pirate_ship :spyglasses => [:factory_in_germany],
|
193
|
+
# :booty => [:id, :name],
|
194
|
+
# :shrouds => '\t'
|
195
|
+
# # kepping the rest of the options at the default values, so they don't need to be defined.
|
104
196
|
end
|
105
197
|
|
106
198
|
To create a csv of the names and ids of makes with factories in germany and return the text of the export:
|
@@ -113,15 +205,28 @@ The name of the csv that comes out will be (by defualt located in log directory)
|
|
113
205
|
|
114
206
|
Where Make is the class, 20090930 is today's date, .export is the gibbet, and 13 is the iterative file counter, meaning I've run this export 13 times today.
|
115
207
|
|
116
|
-
All of those filename parts are customizable to a degree.
|
208
|
+
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
|
+
|
210
|
+
Make.walk_the_plank({:chronometer => Date.parse("December 21, 2012") })
|
211
|
+
# Filename would be: Make.20121221.export.13.csv
|
212
|
+
|
213
|
+
Make.walk_the_plank({:chronometer => false })
|
214
|
+
# Filename would be: Make.export.13.csv
|
215
|
+
|
216
|
+
What if you want the file name to be always the same and to always append to the end of it?
|
217
|
+
#Example: I want the file to be named "data", with no extension, both of the following accomplish that:
|
218
|
+
Make.walk_the_plank({:chronometer => false, :gibbet => "", :aft => "", :swab => :none, :waggoner => 'data'})
|
219
|
+
Make.blindfold(:chronometer => false, :gibbet => "", :aft => "", :swab => :none, :waggoner => 'data')
|
220
|
+
|
221
|
+
All of the options to has_csv_pirate_ship are available to walk_the_plank, land_ho, and blindfold, as well as to the raw class methods CsvPirate.new and CsvPirate.create, but not neccessarily the other way around.
|
117
222
|
|
118
|
-
You can also customize the CSV, for example if you want to
|
223
|
+
You can also customize the CSV, for example if you want to customize which columns are in the csv:
|
119
224
|
|
120
225
|
Make.walk_the_plank({:booty => [:id, :name, :sales]})
|
121
226
|
|
122
|
-
|
227
|
+
You want a timestamp file counter instead of the integer default:
|
123
228
|
|
124
|
-
Make.walk_the_plank({:booty => [:id, :name, :sales], :
|
229
|
+
Make.walk_the_plank({:booty => [:id, :name, :sales], :swab => :timestamp})
|
125
230
|
|
126
231
|
If you want to append each export to the end of the same file (on a per day basis):
|
127
232
|
|
@@ -270,6 +375,23 @@ Then check the output from the console:
|
|
270
375
|
|
271
376
|
Joy to recursive code everywhere!
|
272
377
|
|
378
|
+
If you wanted to create the CsvPirate object and then modify it before creating the csv you can do that too.
|
379
|
+
Does not actually create the csv, so you need to do this in your code:
|
380
|
+
|
381
|
+
csv_pirate = VehicleModel.land_ho({:booty => [:id, :name, :year, :horsepower, :price]})
|
382
|
+
|
383
|
+
This allows you to modify the csv_pirate object before creating the csv like this:
|
384
|
+
|
385
|
+
csv_pirate.booty -= [:id, :name]
|
386
|
+
csv_pirate.hoist_mainstay()
|
387
|
+
|
388
|
+
== Thanks
|
389
|
+
|
390
|
+
Thanks go to
|
391
|
+
9thBit LLC (http://www.9thBit.net)
|
392
|
+
Sagebit LLC (http://www.sagebit.com) - Sagebit has been very supportive of my open source efforts, thanks Ben!
|
393
|
+
TimePerks LLC (http://www.timeperks.com) - Many useful enhancements were requested and paid for by TimePerks
|
394
|
+
|
273
395
|
----------------------------------------------------------------------------------
|
274
396
|
Author: Peter Boling, peter.boling at gmail dot com
|
275
397
|
Copyright (c) 2009 Peter H. Boling of 9thBit LLC, released under the MIT license. See LICENSE for details.
|
data/VERSION.yml
CHANGED
data/csv_pirate.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{csv_pirate}
|
8
|
-
s.version = "3.
|
8
|
+
s.version = "3.3.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"]
|
12
|
-
s.date = %q{2009-10-
|
12
|
+
s.date = %q{2009-10-05}
|
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}
|
data/lib/csv_pirate.rb
CHANGED
@@ -14,15 +14,15 @@ class CsvPirate
|
|
14
14
|
BOOKIE = [:counter, :timestamp, :none]
|
15
15
|
MOP_HEADS = [:clean, :dirty]
|
16
16
|
|
17
|
-
attr_accessor :waggoner #filename
|
18
|
-
attr_accessor :chart #directory, default is (['log','csv'])
|
19
|
-
attr_accessor :aft #extension, default is ('.csv')
|
20
|
-
attr_accessor :gibbet #part of the filename after waggoner and date, before swabbie and aft
|
21
|
-
attr_accessor :chronometer
|
17
|
+
attr_accessor :waggoner # First part of filename
|
18
|
+
attr_accessor :chart # directory, default is (['log','csv'])
|
19
|
+
attr_accessor :aft # extension, default is ('.csv')
|
20
|
+
attr_accessor :gibbet # part of the filename after waggoner and date, before swabbie and aft
|
21
|
+
attr_accessor :chronometer # Date object or false
|
22
22
|
|
23
23
|
# Must provide swag or grub (not both)
|
24
|
-
attr_accessor :swag #
|
25
|
-
attr_accessor :grub #
|
24
|
+
attr_accessor :swag # Array of objects
|
25
|
+
attr_accessor :grub # Class
|
26
26
|
# spyglasses is only used with grub, not swag
|
27
27
|
attr_accessor :spyglasses # named_scopes
|
28
28
|
|
@@ -60,14 +60,14 @@ class CsvPirate
|
|
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"
|
63
|
-
# :chronometer keeps track of when you hunt for treasure
|
63
|
+
# :chronometer keeps track of when you hunt for treasure, can be false if you don't want to keep track.
|
64
64
|
# :gibbet filename spacer after the date, and before the iterative counter/timestamp. MuST contain a '.'
|
65
65
|
# :swab can be :counter, :timestamp, or :none
|
66
66
|
# :counter - default, each successive run will create a new file using a counter
|
67
67
|
# :timestamp - each successive run will create a new file using a HHMMSS time stamp
|
68
|
-
# :none - no iterative file naming convention, just use waggoner and
|
68
|
+
# :none - no iterative file naming convention, just use waggoner, aft and gibbet
|
69
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
|
70
|
-
# :
|
70
|
+
# :clean - do not use :counter or :timestamp, and instead overwrite the file
|
71
71
|
# :dirty - do not use :counter, or :timestamp, or :overwrite. Just keep adding on.
|
72
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)?
|
73
73
|
# See README for examples
|
@@ -79,33 +79,34 @@ class CsvPirate
|
|
79
79
|
@grub = args.first[:grub]
|
80
80
|
|
81
81
|
# if they provide both
|
82
|
-
raise ArgumentError, "must provide either :swag or :grub" if !
|
82
|
+
raise ArgumentError, "must provide either :swag or :grub, not both" if !self.swag.blank? && !self.grub.blank?
|
83
83
|
# if they provide neither
|
84
|
-
raise ArgumentError, "must provide either :swag or :grub
|
84
|
+
raise ArgumentError, "must provide either :swag or :grub" if self.swag.blank? && self.grub.blank?
|
85
85
|
|
86
86
|
@swab = args.first[:swab] || :counter
|
87
|
-
raise ArgumentError, ":swab is #{
|
87
|
+
raise ArgumentError, ":swab is #{self.swab.inspect}, but must be one of #{CsvPirate::BOOKIE.inspect}" unless CsvPirate::BOOKIE.include?(self.swab)
|
88
88
|
|
89
89
|
@mop = args.first[:mop] || :clean
|
90
|
-
raise ArgumentError, ":mop is #{
|
90
|
+
raise ArgumentError, ":mop is #{self.mop.inspect}, but must be one of #{CsvPirate::MOP_HEADS.inspect}" unless CsvPirate::MOP_HEADS.include?(self.mop)
|
91
91
|
|
92
92
|
@gibbet = args.first[:gibbet] || '.export'
|
93
|
-
raise ArgumentError, ":gibbet is #{
|
93
|
+
raise ArgumentError, ":gibbet is #{self.gibbet.inspect}, and does not contain a '.' character, which is required when using iterative filenames (set :swab => :none to turn off iterative filenames)" if self.swab != :none && (self.gibbet.nil? || !self.gibbet.include?('.'))
|
94
94
|
|
95
95
|
@waggoner = args.first[:waggoner] || "#{self.grub || self.swag}"
|
96
|
-
raise ArgumentError, ":waggoner is #{
|
96
|
+
raise ArgumentError, ":waggoner is #{self.waggoner.inspect}, and must be a string at least one character long" if self.waggoner.nil? || self.waggoner.length < 1
|
97
97
|
|
98
98
|
@booty = args.first[:booty] || []
|
99
|
-
raise ArgumentError, ":booty is #{
|
99
|
+
raise ArgumentError, ":booty is #{self.booty.inspect}, and must be an array of methods to call on a class for CSV data" if self.booty.nil? || !self.booty.is_a?(Array) || self.booty.empty?
|
100
100
|
|
101
101
|
@chart = args.first[:chart] || ['log','csv']
|
102
|
-
raise ArgumentError, ":chart is #{
|
102
|
+
raise ArgumentError, ":chart is #{self.chart.inspect}, and must be an array of directory names, which will become the filepath for the csv file" if self.chart.nil? || !self.chart.is_a?(Array) || self.chart.empty?
|
103
103
|
|
104
104
|
@aft = args.first[:aft] || '.csv'
|
105
|
-
@chronometer = args.first[:chronometer] || Date.today
|
105
|
+
@chronometer = args.first[:chronometer] == false ? false : args.first[:chronometer] || Date.today
|
106
106
|
|
107
107
|
@spyglasses = (args.first[:spyglasses] || [:all]) if self.grub
|
108
108
|
@shrouds = args.first[:shrouds] || ',' # for tsv, tab-delimited, "\t"
|
109
|
+
raise ArgumentError, ":shrouds is #{self.shrouds.inspect}, and must be a string (e.g. ',' or '\t'), which will be used as the delimeter for the csv file" if self.shrouds.nil? || !self.shrouds.is_a?(String)
|
109
110
|
|
110
111
|
@astrolabe = args.first[:astrolabe] || false
|
111
112
|
|
@@ -198,7 +199,7 @@ class CsvPirate
|
|
198
199
|
|
199
200
|
self.rhumb_lines.close
|
200
201
|
|
201
|
-
self.jolly_roger if CsvPirate.parlay
|
202
|
+
self.jolly_roger if CsvPirate.parlay && CsvPirate.parlance(1)
|
202
203
|
|
203
204
|
# returns the text of this CSV export
|
204
205
|
return self.maroon
|
@@ -215,10 +216,10 @@ class CsvPirate
|
|
215
216
|
def jolly_roger
|
216
217
|
if self.bury_treasure
|
217
218
|
if self.buried_treasure.is_a?(Array)
|
218
|
-
puts "Found #{self.buried_treasure.length} deniers buried here: '#{self.poop_deck}'" if CsvPirate.parlay
|
219
|
-
puts "You must weigh_anchor to review your plunder!" if CsvPirate.parlay
|
219
|
+
puts "Found #{self.buried_treasure.length} deniers buried here: '#{self.poop_deck}'" if CsvPirate.parlay && CsvPirate.parlance(1)
|
220
|
+
puts "You must weigh_anchor to review your plunder!" if CsvPirate.parlay && CsvPirate.parlance(1)
|
220
221
|
else
|
221
|
-
puts "Failed to locate treasure" if CsvPirate.parlay
|
222
|
+
puts "Failed to locate treasure" if CsvPirate.parlay && CsvPirate.parlance(1)
|
222
223
|
end
|
223
224
|
end
|
224
225
|
end
|
@@ -371,7 +372,7 @@ class CsvPirate
|
|
371
372
|
return false unless block_given?
|
372
373
|
count = 1 if report_kills
|
373
374
|
FasterCSV.foreach(galley, {:headers => :first_row, :return_headers => false}) do |gun|
|
374
|
-
puts "Galleys sunk: #{count+=1}" if CsvPirate.
|
375
|
+
puts "Galleys sunk: #{count+=1}" if CsvPirate.parlance(1)
|
375
376
|
yield gun
|
376
377
|
end
|
377
378
|
end
|
@@ -421,13 +422,13 @@ class CsvPirate
|
|
421
422
|
cutthroat.figurehead
|
422
423
|
|
423
424
|
carrack.scuttle do |cutlass|
|
424
|
-
puts "CUTLASS: #{cutlass.inspect}" if CsvPirate.
|
425
|
-
puts "CARRACK.SWAG: #{carrack.swag.inspect}" if CsvPirate.
|
425
|
+
puts "CUTLASS: #{cutlass.inspect}" if CsvPirate.parlance(2)
|
426
|
+
puts "CARRACK.SWAG: #{carrack.swag.inspect}" if CsvPirate.parlance(2)
|
426
427
|
backstaff = cutlass[carrack.swag] || cutlass["#{carrack.spyglasses}"]
|
427
|
-
puts "BACKSTAFF: #{backstaff}" if CsvPirate.
|
428
|
-
puts "CARRACK.SPYGLASSES: #{carrack.spyglasses.inspect}" if CsvPirate.
|
428
|
+
puts "BACKSTAFF: #{backstaff}" if CsvPirate.parlance(2)
|
429
|
+
puts "CARRACK.SPYGLASSES: #{carrack.spyglasses.inspect}" if CsvPirate.parlance(2)
|
429
430
|
gully = carrack.grub.send("find_by_#{carrack.spyglasses}".to_sym, backstaff)
|
430
|
-
puts "GULLY: #{gully.inspect}" if CsvPirate.
|
431
|
+
puts "GULLY: #{gully.inspect}" if CsvPirate.parlance(2)
|
431
432
|
if gully
|
432
433
|
flotsam = cutthroat.grub.is_a?(String) ?
|
433
434
|
gully.send(cutthroat.grub.to_sym) :
|
@@ -438,16 +439,16 @@ class CsvPirate
|
|
438
439
|
cutthroat.grub.class == Class ?
|
439
440
|
cutthroat.grub.send("find_by_#{cutthroat.swag}", gully.send(cutthroat.spyglasses)) :
|
440
441
|
nil
|
441
|
-
puts "FLOTSAM: #{flotsam.inspect}" if CsvPirate.
|
442
|
+
puts "FLOTSAM: #{flotsam.inspect}" if CsvPirate.parlance(2)
|
442
443
|
if flotsam
|
443
444
|
plunder = cutthroat.prize(flotsam)
|
444
445
|
cutthroat.buried_treasure << plunder
|
445
446
|
cutthroat.scrivener(plunder.map {|bulkhead| "#{bulkhead}"}.join(','))
|
446
447
|
else
|
447
|
-
puts "Unable to locate: #{cutthroat.grub} related to #{carrack.grub}.#{carrack.spyglasses} '#{gully.send(carrack.spyglasses)}'" if CsvPirate.
|
448
|
+
puts "Unable to locate: #{cutthroat.grub} related to #{carrack.grub}.#{carrack.spyglasses} '#{gully.send(carrack.spyglasses)}'" if CsvPirate.parlance(1)
|
448
449
|
end
|
449
450
|
else
|
450
|
-
puts "Unable to locate: #{carrack.grub}.#{carrack.spyglasses} '#{gully.send(carrack.spyglasses)}'" if CsvPirate.
|
451
|
+
puts "Unable to locate: #{carrack.grub}.#{carrack.spyglasses} '#{gully.send(carrack.spyglasses)}'" if CsvPirate.parlance(1)
|
451
452
|
end
|
452
453
|
end
|
453
454
|
|
@@ -460,4 +461,9 @@ class CsvPirate
|
|
460
461
|
return cutthroat
|
461
462
|
end
|
462
463
|
|
464
|
+
# verbosity on a scale of 0 - 3 (0=:none, 1=:error, 2=:info, 3=:debug, 0 being no screen output, 1 is default
|
465
|
+
def self.parlance(level = 1)
|
466
|
+
self.parlay.is_a?(Numeric) && self.parlay >= level
|
467
|
+
end
|
468
|
+
|
463
469
|
end
|
@@ -23,15 +23,16 @@ module NinthBit
|
|
23
23
|
options[:parlay] ||= 1
|
24
24
|
|
25
25
|
# if they provide both
|
26
|
-
raise ArgumentError, "must provide either :swag or :grub" if !options[:swag].blank? && !options[:grub].blank?
|
26
|
+
raise ArgumentError, "must provide either :swag or :grub, not both" if !options[:swag].blank? && !options[:grub].blank?
|
27
27
|
# if they provide neither
|
28
|
-
raise ArgumentError, "must provide either :swag or :grub
|
28
|
+
raise ArgumentError, "must provide either :swag or :grub" 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
|
-
raise ArgumentError, ":gibbet is #{options[:gibbet].inspect}, and does not contain a '.' character, which is required
|
31
|
+
raise ArgumentError, ":gibbet is #{options[:gibbet].inspect}, and does not contain a '.' character, which is required when using iterative filenames (set :swab => :none to turn off iterative filenames)" if options[:swab] != :none && (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
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
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?
|
35
|
+
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)
|
35
36
|
|
36
37
|
extend ClassMethods unless (class << self; included_modules; end).include?(ClassMethods)
|
37
38
|
|
@@ -48,48 +49,58 @@ module NinthBit
|
|
48
49
|
|
49
50
|
# intended for use with send_data for downloading the text of the csv:
|
50
51
|
# send_data Make.say_your_last_words
|
51
|
-
# TODO: Fix say_yourr_last_words so it works! Use send_data args
|
52
|
+
# TODO: Fix say_yourr_last_words so it works! Use send_data args for real
|
52
53
|
#def say_your_last_words(charset = 'utf-8', args = {})
|
53
54
|
# csv_pirate = self.blindfold(args)
|
54
55
|
# return [ csv_pirate.maroon,
|
55
56
|
# {:type => "text/csv; charset=#{charset}; header=present"},
|
56
57
|
# {:disposition => "attachment; filename=#{csv_pirate.nocturnal}"} ]
|
57
58
|
#end
|
58
|
-
|
59
|
-
#returns the text of the csv export (not the file - this is important if you are appending)
|
59
|
+
|
60
|
+
# returns the text of the csv export (not the file - this is important if you are appending)
|
60
61
|
# warning if using from console: if you are exporting a large csv this will all print in your console.
|
61
62
|
# intended for use with send_data for downloading the text of the csv:
|
62
63
|
# send_data Make.walk_the_plank,
|
63
64
|
# :type => 'text/csv; charset=iso-8859-1; header=present',
|
64
65
|
# :disposition => "attachment; filename=Data.csv"
|
65
66
|
def walk_the_plank(args = {})
|
66
|
-
|
67
|
-
csv_pirate.hoist_mainstay()
|
67
|
+
self.land_ho(args).hoist_mainstay()
|
68
68
|
end
|
69
69
|
|
70
|
-
#returns the csv_pirate object so you have access to everything
|
70
|
+
# returns the csv_pirate object so you have access to everything
|
71
|
+
# warning if using from console: if you are exporting a large csv this will all print in your console.
|
71
72
|
# If using in a download action it might look like this:
|
72
73
|
# csv_pirate = Make.blindfold
|
73
74
|
# send_data csv_pirate.maroon,
|
74
75
|
# :type => 'text/csv; charset=iso-8859-1; header=present',
|
75
76
|
# :disposition => "attachment; filename=#{csv_pirate.nocturnal}"
|
76
77
|
def blindfold(args = {})
|
77
|
-
CsvPirate.parlay = args[:parlay] || self.piratey_options[:parlay]
|
78
78
|
CsvPirate.create(self.piratey_args(args))
|
79
79
|
end
|
80
80
|
|
81
|
+
# returns the csv_pirate object so you have access to everything
|
82
|
+
# Does not actually create the csv, so you need to do this in your code:
|
83
|
+
# csv_pirate = Klass.land_ho({:booty => [:id, :name, :dragons, :created_at]})
|
84
|
+
# This allows you to modify the csv_pirate object before creating the csv like this:
|
85
|
+
# csv_pirate.booty -= [:id, :name]
|
86
|
+
# csv_pirate.hoist_mainstay()
|
87
|
+
def land_ho(args = {})
|
88
|
+
CsvPirate.new(self.piratey_args(args))
|
89
|
+
end
|
90
|
+
|
81
91
|
protected
|
82
92
|
|
83
93
|
def piratey_args(args = {})
|
84
|
-
|
94
|
+
CsvPirate.parlay = args[:parlay] || self.piratey_options[:parlay]
|
95
|
+
return { :chart => args[:chart] || self.piratey_options[:chart],
|
85
96
|
:aft => args[:aft] || self.piratey_options[:aft],
|
86
97
|
:gibbet => args[:gibbet] || self.piratey_options[:gibbet],
|
87
|
-
:chronometer => args[:chronometer] || Date.today,
|
98
|
+
:chronometer => args[:chronometer] == false ? false : args[:chronometer] || Date.today,
|
88
99
|
:waggoner => args[:waggoner] || self.piratey_options[:waggoner] || "#{self}",
|
89
100
|
:swag => args[:swag] || self.piratey_options[:swag],
|
90
101
|
:swab => args[:swab] || self.piratey_options[:swab],
|
91
102
|
:mop => args[:mop] || self.piratey_options[:mop],
|
92
|
-
:shrouds => args[:
|
103
|
+
:shrouds => args[:shrouds] || self.piratey_options[:shrouds],
|
93
104
|
:grub => args[:grub] || self.piratey_options[:grub],
|
94
105
|
:spyglasses => args[:spyglasses] || self.piratey_options[:spyglasses],
|
95
106
|
:booty => args[:booty] || self.piratey_options[:booty],
|
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.
|
4
|
+
version: 3.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Boling
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-10-
|
12
|
+
date: 2009-10-05 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|