csv_pirate 3.1.1 → 3.3.0
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 +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
|
|