file_generator 0.0.2 → 0.0.3
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 +9 -0
- data/LICENSE +22 -0
- data/README.md +75 -13
- data/lib/file_generator/base.rb +41 -33
- data/lib/file_generator/version.rb +1 -1
- data/spec/lib/file_generator_spec.rb +15 -1
- data/spec/spec_helper.rb +5 -1
- data/spec/support/helpers.rb +4 -4
- metadata +4 -2
data/ChangeLog
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) Martin Aceto
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
22
|
+
|
data/README.md
CHANGED
@@ -2,34 +2,37 @@
|
|
2
2
|
|
3
3
|
## Description
|
4
4
|
|
5
|
-
Every time we need to
|
5
|
+
Every time we need to export information from your application as text files, we are
|
6
6
|
writing code for every format we need to generate.
|
7
7
|
|
8
|
-
FileGenerator tries to minimize the ammount of code needed to perform
|
9
|
-
this task.
|
8
|
+
FileGenerator tries to minimize the ammount of code needed to perform this task.
|
10
9
|
|
11
|
-
|
10
|
+
## How does it work?
|
12
11
|
|
13
12
|
FileGenerator takes the header, body, and footer file formats as input
|
14
13
|
and additionally a hash with the data we want to export.
|
15
14
|
|
16
15
|
The format is expressed as string as follows:
|
17
16
|
|
18
|
-
|
19
|
-
1 => longitud
|
20
|
-
2 => valor
|
21
|
-
3 => relleno
|
22
|
-
4 => alineado
|
17
|
+
each column has the next attributes
|
23
18
|
|
19
|
+
* Name: this name would match with the key in the hash
|
20
|
+
* Length: size of the column
|
21
|
+
* Value: dafult value in case that name doesn't match with any hash key
|
22
|
+
* Fill: for completing the space of length
|
23
|
+
* Align: align to Left or Right
|
24
24
|
|
25
25
|
as for instance:
|
26
26
|
|
27
|
-
|
28
|
-
|
27
|
+
<pre>
|
28
|
+
"id:3:0:0:D,name:30:: :I,region_id:3:0:0:D"
|
29
|
+
</pre>
|
29
30
|
|
30
31
|
and the data we want to export is:
|
31
32
|
|
33
|
+
<pre>
|
32
34
|
[{"id"=>1, "region_id"=>7, "name"=>"les Escaldes"},{"id"=>2, "region_id"=>7, "name"=>"Lima"}]
|
35
|
+
</pre>
|
33
36
|
|
34
37
|
FileGenerator will try to match the attribute names with the format
|
35
38
|
names, if they dont match, it will assign the value to the line of the
|
@@ -39,9 +42,68 @@ format.
|
|
39
42
|
It also has names for the format which stablishes a special field as for
|
40
43
|
instance:
|
41
44
|
|
42
|
-
time: puts the current date with the format "
|
45
|
+
time: puts the current date with the format "YYYYMMDD"·
|
43
46
|
|
44
|
-
nreg : put the
|
47
|
+
nreg : put the sum of records in the file in the body
|
45
48
|
|
46
49
|
## Usage
|
47
50
|
|
51
|
+
For example if you have a Ruby on Rails application and you need to export
|
52
|
+
diferents models like City, Region, Localities, Contacts, etc... you could define a controller Exports and for each model a method to export. Like the next example:
|
53
|
+
|
54
|
+
Add file_generator to your Gemfile.
|
55
|
+
|
56
|
+
<pre>
|
57
|
+
gem 'file_generation'
|
58
|
+
</pre>
|
59
|
+
|
60
|
+
Create the method in the Exports controller for generate the file
|
61
|
+
|
62
|
+
<pre>
|
63
|
+
class ExportsController
|
64
|
+
def cities
|
65
|
+
headerformat = "treg:2:CC::I,csuc:3:193::I,time:8:0::I"
|
66
|
+
bodyformat = "id:3:0:0:D,name:30:: :I,region_id:3:0:0:D"
|
67
|
+
footerformat = "pie:2:CC::I,csuc:3:193::I,nreg:10:0:0:D"
|
68
|
+
cities = [{"id"=>1, "region_id"=>7, "name"=>"les Escaldes"},{"id"=>2, "region_id"=>7, "name"=>"Lima"}]
|
69
|
+
content = FileGenerator::Base.generate_file(cities, headerformat, bodyformat, footerformat)
|
70
|
+
send_data content, :filename => "cities.txt"
|
71
|
+
end
|
72
|
+
|
73
|
+
def contacts
|
74
|
+
...
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
</pre>
|
79
|
+
|
80
|
+
Add the routes in config/routes.rb
|
81
|
+
|
82
|
+
<pre>
|
83
|
+
resources :exports do
|
84
|
+
get 'cities', :on => :collection
|
85
|
+
end
|
86
|
+
</pre>
|
87
|
+
|
88
|
+
and put the link in the view
|
89
|
+
|
90
|
+
<pre>
|
91
|
+
link_to("Export Cities", cities_exports_path)
|
92
|
+
</pre>
|
93
|
+
|
94
|
+
with this example you would get a file like this
|
95
|
+
|
96
|
+
<pre>
|
97
|
+
CC19320120206
|
98
|
+
001les Escaldes 007
|
99
|
+
002Lima 007
|
100
|
+
CC1930000000002
|
101
|
+
</pre>
|
102
|
+
|
103
|
+
|
104
|
+
# what next ?
|
105
|
+
|
106
|
+
* Make header and footer optional
|
107
|
+
* Add .csv format like a option
|
108
|
+
* Add more pre defined columns like "nreg" or "time"
|
109
|
+
* Add more format for the pre defined column "time"
|
data/lib/file_generator/base.rb
CHANGED
@@ -26,24 +26,8 @@ module FileGenerator
|
|
26
26
|
attributes = split_format(format)
|
27
27
|
attributes.each do |attrib|
|
28
28
|
behaviors = split_behaviors(attrib) # 0=>nombre, 1=>longitud, 2=> valor, 3=> relleno, 4 => alineado
|
29
|
-
value =
|
30
|
-
|
31
|
-
when 'nreg' then
|
32
|
-
value = records.size.to_s
|
33
|
-
when 'time' then
|
34
|
-
value = Time.now.strftime("%Y%m%d")
|
35
|
-
else
|
36
|
-
value = behaviors[2]
|
37
|
-
end
|
38
|
-
if (behaviors[3] != '')
|
39
|
-
if (behaviors[4] == 'I')
|
40
|
-
row << value.ljust(behaviors[1].to_i, behaviors[3])
|
41
|
-
else
|
42
|
-
row << value.rjust(behaviors[1].to_i, behaviors[3])
|
43
|
-
end
|
44
|
-
else
|
45
|
-
row << value
|
46
|
-
end
|
29
|
+
value = fixed_field(behaviors[0], behaviors[2], records)
|
30
|
+
row << justify_and_fill(value, behaviors[1],behaviors[3],behaviors[4])
|
47
31
|
end
|
48
32
|
row
|
49
33
|
end
|
@@ -57,26 +41,50 @@ module FileGenerator
|
|
57
41
|
if record.has_key?(behaviors[0])
|
58
42
|
value = record["#{behaviors[0]}"].to_s
|
59
43
|
else
|
60
|
-
|
61
|
-
when 'time' then
|
62
|
-
value = Time.now.strftime("%Y%m%d")
|
63
|
-
else
|
64
|
-
value = behaviors[2]
|
65
|
-
end
|
66
|
-
end
|
67
|
-
if (behaviors[3] != '')
|
68
|
-
if (behaviors[4] == 'I')
|
69
|
-
row << value.ljust(behaviors[1].to_i, behaviors[3])
|
70
|
-
else
|
71
|
-
row << value.rjust(behaviors[1].to_i, behaviors[3])
|
72
|
-
end
|
73
|
-
else
|
74
|
-
row << value
|
44
|
+
value = fixed_field(behaviors[0], behaviors[2])
|
75
45
|
end
|
46
|
+
row << justify_and_fill(value, behaviors[1],behaviors[3],behaviors[4])
|
76
47
|
end
|
77
48
|
row
|
78
49
|
end
|
79
50
|
|
51
|
+
# Justify and fill
|
52
|
+
#
|
53
|
+
# I = Left
|
54
|
+
#
|
55
|
+
# D = rgiht
|
56
|
+
#
|
57
|
+
# fill = character in the format
|
58
|
+
#
|
59
|
+
def justify_and_fill(value,lenght, fill, justify)
|
60
|
+
if !fill.empty?
|
61
|
+
if justify == 'I'
|
62
|
+
value.ljust(lenght.to_i, fill)
|
63
|
+
elsif justify == 'D'
|
64
|
+
value.rjust(lenght.to_i, fill)
|
65
|
+
end
|
66
|
+
else
|
67
|
+
value
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# take the name of the fixed_field and replace with the value
|
72
|
+
#
|
73
|
+
# time: replace with the date of the day in the formar %Y%m&d
|
74
|
+
#
|
75
|
+
# neg: if records is not nil count and replace with the value
|
76
|
+
#
|
77
|
+
def fixed_field(field, default, records = nil)
|
78
|
+
case field
|
79
|
+
when 'time'
|
80
|
+
Time.now.strftime("%Y%m%d")
|
81
|
+
when 'nreg' then
|
82
|
+
records.size.to_s unless records.nil?
|
83
|
+
else
|
84
|
+
default
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
80
88
|
# split the format in each behaviors
|
81
89
|
def split_format(format)
|
82
90
|
format.split(',')
|
@@ -7,7 +7,21 @@ describe FileGenerator do
|
|
7
7
|
records = [{"id"=>1, "region_id"=>7, "name"=>"les Escaldes"},{"id"=>2, "region_id"=>7, "name"=>"Lima"}]
|
8
8
|
format = load_formats.formats
|
9
9
|
FileGenerator::Base.generate_file(records,format['headerformat'],format['bodyformat'],format['footerformat'])
|
10
|
-
|
10
|
+
end
|
11
|
+
|
12
|
+
it "gets a good format path format should not be empty" do
|
13
|
+
format = load_formats.formats
|
14
|
+
format.should_not be_empty
|
15
|
+
end
|
16
|
+
|
17
|
+
it "gets a good format path format should match" do
|
18
|
+
format = load_formats.formats
|
19
|
+
format.should == {'headerformat'=>'treg:2:CC::I,csuc:3:193::I,time:8:0::I', 'bodyformat'=>'id:3:0:0:D,name:30:: :I,region_id:3:0:0:D', 'footerformat'=>'pie:2:CC::I,csuc:3:193::I,nreg:10:0:0:D'}
|
20
|
+
end
|
21
|
+
|
22
|
+
it "gets a bad format path shuold show up a message" do
|
23
|
+
format = load_formats("/spec/formt.yml")
|
24
|
+
format.should == "missing formats file."
|
11
25
|
end
|
12
26
|
|
13
27
|
it "should not be empty string" do
|
data/spec/spec_helper.rb
CHANGED
data/spec/support/helpers.rb
CHANGED
@@ -3,13 +3,13 @@ require "yaml"
|
|
3
3
|
|
4
4
|
module Helpers
|
5
5
|
|
6
|
-
def load_formats
|
7
|
-
formats_file = File.join(Dir.pwd,
|
6
|
+
def load_formats(path = "/spec/formats.yml")
|
7
|
+
formats_file = File.join(Dir.pwd, path)
|
8
8
|
if File.exists?(formats_file)
|
9
|
-
conf = YAML.load(File.read("#{Dir.pwd}
|
9
|
+
conf = YAML.load(File.read("#{Dir.pwd}#{path}"))
|
10
10
|
OpenStruct.new(conf)
|
11
11
|
else
|
12
|
-
|
12
|
+
"missing formats file."
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: file_generator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-20 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Generator of files using a format description
|
15
15
|
email:
|
@@ -19,7 +19,9 @@ extensions: []
|
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
21
|
- .gitignore
|
22
|
+
- ChangeLog
|
22
23
|
- Gemfile
|
24
|
+
- LICENSE
|
23
25
|
- README.md
|
24
26
|
- Rakefile
|
25
27
|
- file_generator.gemspec
|