odf-report 0.5.2 → 0.7.2

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.
Files changed (47) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/gem-push.yml +40 -0
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +62 -0
  5. data/README.md +220 -0
  6. data/bin/odt-extract +10 -0
  7. data/bin/odt-viewer +18 -0
  8. data/lib/odf-report.rb +11 -8
  9. data/lib/odf-report/data_source.rb +65 -0
  10. data/lib/odf-report/field.rb +7 -40
  11. data/lib/odf-report/image.rb +57 -0
  12. data/lib/odf-report/nestable.rb +65 -0
  13. data/lib/odf-report/report.rb +24 -28
  14. data/lib/odf-report/section.rb +15 -42
  15. data/lib/odf-report/table.rb +54 -59
  16. data/lib/odf-report/template.rb +88 -0
  17. data/lib/odf-report/text.rb +1 -3
  18. data/lib/odf-report/version.rb +1 -1
  19. data/odf-report.gemspec +4 -4
  20. data/spec/fields_spec.rb +4 -4
  21. data/spec/images/image_1.jpg +0 -0
  22. data/spec/images/image_2.jpg +0 -0
  23. data/spec/images/image_3.jpg +0 -0
  24. data/spec/images/piriapolis.jpg +0 -0
  25. data/spec/images/placeholder.jpg +0 -0
  26. data/spec/images/rails.png +0 -0
  27. data/spec/images_spec.rb +159 -0
  28. data/spec/sections_spec.rb +51 -0
  29. data/spec/spec_helper.rb +2 -4
  30. data/spec/tables_spec.rb +1 -1
  31. data/spec/template_spec.rb +45 -0
  32. data/spec/templates/images.odt +0 -0
  33. data/spec/templates/specs.odt +0 -0
  34. data/test/images_test.rb +32 -0
  35. data/test/templates/images/image_1.jpg +0 -0
  36. data/test/templates/images/image_2.jpg +0 -0
  37. data/test/templates/images/image_3.jpg +0 -0
  38. data/test/templates/images/placeholder.jpg +0 -0
  39. data/test/templates/images/placeholder.png +0 -0
  40. data/test/templates/test_images.odt +0 -0
  41. data/test/test.rb +262 -0
  42. metadata +77 -23
  43. data/README.textile +0 -223
  44. data/lib/odf-report/file.rb +0 -50
  45. data/lib/odf-report/images.rb +0 -44
  46. data/lib/odf-report/nested.rb +0 -62
  47. data/spec/specs.odt +0 -0
@@ -0,0 +1,88 @@
1
+ module ODFReport
2
+ class Template
3
+
4
+ CONTENT_FILES = ['content.xml', 'styles.xml']
5
+ MANIFEST_FILE = "META-INF/manifest.xml"
6
+
7
+ attr_accessor :output_stream
8
+
9
+ def initialize(template = nil, io: nil)
10
+ raise "You must provide either a filename or an io: string" unless template || io
11
+ raise "Template [#{template}] not found." unless template.nil? || ::File.exist?(template)
12
+
13
+ @template = template
14
+ @io = io
15
+ end
16
+
17
+ def update_content
18
+ @buffer = Zip::OutputStream.write_buffer do |out|
19
+ @output_stream = out
20
+ yield self
21
+ end
22
+ end
23
+
24
+ def update_files(&block)
25
+
26
+ get_template_entries.each do |entry|
27
+
28
+ next if entry.directory?
29
+
30
+ entry.get_input_stream do |is|
31
+
32
+ data = is.sysread
33
+
34
+ if CONTENT_FILES.include?(entry.name)
35
+ process_entry(data, &block)
36
+ end
37
+
38
+ update_file(entry.name, data) unless entry.name == MANIFEST_FILE
39
+
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ def update_manifest(&block)
46
+ entry = get_template_entries.find_entry(MANIFEST_FILE)
47
+
48
+ entry.get_input_stream do |is|
49
+
50
+ data = is.sysread
51
+
52
+ process_entry(data, &block)
53
+
54
+ update_file(MANIFEST_FILE, data)
55
+
56
+ end
57
+
58
+ end
59
+
60
+ def data
61
+ @buffer.string
62
+ end
63
+
64
+ def update_file(name, data)
65
+ @output_stream.put_next_entry(name)
66
+ @output_stream.write data
67
+ end
68
+
69
+ private
70
+
71
+ def get_template_entries
72
+
73
+ if @template
74
+ Zip::File.open(@template)
75
+ else
76
+ Zip::File.open_buffer(@io.force_encoding("ASCII-8BIT"))
77
+ end
78
+
79
+ end
80
+
81
+ def process_entry(entry)
82
+ doc = Nokogiri::XML(entry, &:noblanks)
83
+ yield doc
84
+ entry.replace(doc.to_xml(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML))
85
+ end
86
+
87
+ end
88
+ end
@@ -8,9 +8,7 @@ module ODFReport
8
8
 
9
9
  return unless node = find_text_node(doc)
10
10
 
11
- text_value = get_value(data_item)
12
-
13
- @parser = Parser::Default.new(text_value, node)
11
+ @parser = Parser::Default.new(@data_source.value, node)
14
12
 
15
13
  @parser.paragraphs.each do |p|
16
14
  node.before(p)
@@ -1,3 +1,3 @@
1
1
  module ODFReport
2
- VERSION = "0.5.2"
2
+ VERSION = "0.7.2"
3
3
  end
@@ -9,7 +9,6 @@ Gem::Specification.new do |s|
9
9
  s.authors = ["Sandro Duarte"]
10
10
  s.description = %q{Generates ODF files, given a template (.odt) and data, replacing tags}
11
11
  s.email = %q{sandrods@gmail.com}
12
- s.has_rdoc = false
13
12
  s.homepage = %q{http://sandrods.github.com/odf-report/}
14
13
  s.rubygems_version = %q{1.3.7}
15
14
  s.summary = %q{Generates ODF files, given a template (.odt) and data, replacing tags}
@@ -19,13 +18,14 @@ Gem::Specification.new do |s|
19
18
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
20
19
  s.require_paths = ["lib"]
21
20
 
22
- s.add_development_dependency "bundler", "~> 1.6"
21
+ s.add_development_dependency "bundler"
23
22
  s.add_development_dependency "rake"
24
23
  s.add_development_dependency "rspec", "~> 3.0.0"
25
24
  s.add_development_dependency "faker"
26
25
  s.add_development_dependency "launchy"
27
26
 
28
- s.add_runtime_dependency('rubyzip', "~> 1.2.0")
29
- s.add_runtime_dependency('nokogiri', ">= 1.5.0")
27
+ s.add_runtime_dependency('rubyzip', ">= 1.3.0")
28
+ s.add_runtime_dependency('nokogiri', ">= 1.10.0")
29
+ s.add_runtime_dependency('mime-types')
30
30
 
31
31
  end
@@ -7,7 +7,7 @@ RSpec.describe "Fields" do
7
7
 
8
8
  @itens_01 = Item.get_list(3)
9
9
 
10
- report = ODFReport::Report.new("spec/specs.odt") do |r|
10
+ report = ODFReport::Report.new("spec/templates/specs.odt") do |r|
11
11
 
12
12
  r.add_field(:field_01, @field_01)
13
13
  r.add_field(:field_02, @field_02)
@@ -51,7 +51,7 @@ RSpec.describe "Fields" do
51
51
  expect(table).not_to match(/\[COLUMN_02\]/)
52
52
  expect(table).to match(/\[COLUMN_03\]/)
53
53
 
54
- expect(table).to match(item.id)
54
+ expect(table).to match(item.id.to_s)
55
55
  expect(table).to match(item.name)
56
56
 
57
57
  end
@@ -65,9 +65,9 @@ RSpec.describe "Fields" do
65
65
 
66
66
  @itens_01.each_with_index do |item, idx|
67
67
 
68
- section = @data.xml.xpath(".//text:section[@text:name='SECTION_01_#{idx+1}']").to_s
68
+ section = @data.xml.at_xpath(".//text:section[#{idx+1}]").to_s
69
69
 
70
- expect(section).to match(item.id)
70
+ expect(section).to match(item.id.to_s)
71
71
  expect(section).to match(item.name)
72
72
 
73
73
  end
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,159 @@
1
+ RSpec.describe "Images" do
2
+
3
+ context('Adding Images') do
4
+
5
+ before(:context) do
6
+
7
+ @list = []
8
+ @list << OpenStruct.new({ name: "IMG - [1, 1]", path: 'spec/images/image_1.jpg', path2: 'spec/images/image_1.jpg' })
9
+ @list << OpenStruct.new({ name: "IMG - [2, 1]", path: 'spec/images/image_2.jpg', path2: 'spec/images/image_1.jpg' })
10
+ @list << OpenStruct.new({ name: "IMG - [3, 2]", path: 'spec/images/image_3.jpg', path2: 'spec/images/image_2.jpg' })
11
+ @list << OpenStruct.new({ name: "IMG - [1, 3]", path: 'spec/images/image_1.jpg', path2: 'spec/images/image_3.jpg' })
12
+ @list << OpenStruct.new({ name: "IMG - [2, 2]", path: 'spec/images/image_2.jpg', path2: 'spec/images/image_2.jpg' })
13
+
14
+
15
+ report = ODFReport::Report.new("spec/templates/images.odt") do |r|
16
+
17
+ r.add_image("IMAGE_01", 'spec/images/rails.png')
18
+ r.add_image("IMAGE_02", 'spec/images/piriapolis.jpg')
19
+
20
+ r.add_table('IMAGE_TABLE', @list) do |t|
21
+ t.add_column(:image_name, :name)
22
+ t.add_image('IMAGE_IN_TABLE_01', :path)
23
+ t.add_image('IMAGE_IN_TABLE_02', :path2)
24
+ end
25
+
26
+ r.add_section('SECTION', @list) do |t|
27
+ t.add_field(:image_name, :name)
28
+ t.add_image('IMAGE_IN_SECTION_01', :path2)
29
+ t.add_image('IMAGE_IN_SECTION_02', :path)
30
+ end
31
+
32
+ end
33
+
34
+ report.generate("spec/result/images.odt")
35
+
36
+ @data = Inspector.new("spec/result/images.odt")
37
+
38
+ end
39
+
40
+
41
+ it "simple image replacement" do
42
+
43
+ images = @data.xml.xpath("//draw:image")
44
+
45
+ expect(images[0].attribute('href').value).to eq "Pictures/rails.png"
46
+ expect(images[1].attribute('href').value).to eq "Pictures/piriapolis.jpg"
47
+
48
+ end
49
+
50
+ it "table columns replacement" do
51
+
52
+ table = @data.xml.at_xpath(".//table:table[@table:name='IMAGE_TABLE']")
53
+
54
+ @list.each_with_index do |item, idx|
55
+
56
+ row = table.xpath(".//table:table-row[#{idx+1}]")
57
+
58
+ images = row.xpath(".//draw:image")
59
+
60
+ expect(File.basename(images[0].attribute('href').value)).to eq File.basename(item.path)
61
+ expect(File.basename(images[1].attribute('href').value)).to eq File.basename(item.path2)
62
+
63
+ end
64
+
65
+ end
66
+
67
+ it "section fields replacement" do
68
+
69
+ @list.each_with_index do |item, idx|
70
+
71
+ section = @data.xml.at_xpath(".//text:section[#{idx+1}]")
72
+
73
+ images = section.xpath(".//draw:image")
74
+
75
+ expect(File.basename(images[0].attribute('href').value)).to eq File.basename(item.path)
76
+ expect(File.basename(images[1].attribute('href').value)).to eq File.basename(item.path2)
77
+
78
+ end
79
+
80
+ end
81
+ end
82
+
83
+ context "Removing Images" do
84
+
85
+ before(:context) do
86
+
87
+ @list = []
88
+ @list << OpenStruct.new({ name: "IMG - both ok", path: 'spec/images/image_1.jpg', path2: 'spec/images/image_1.jpg' })
89
+ @list << OpenStruct.new({ name: "IMG - 1 ok", path: 'spec/images/image_2.jpg', path2: nil })
90
+ @list << OpenStruct.new({ name: "IMG - 2 ok", path: nil, path2: 'spec/images/image_3.jpg' })
91
+ # @list << OpenStruct.new({ name: "IMG - 2 invalid", path: nil, path2: 'spec/images/invalid.jpg' })
92
+
93
+ report = ODFReport::Report.new("spec/templates/images.odt") do |r|
94
+
95
+ # r.add_image("IMAGE_01")
96
+ r.add_image("IMAGE_02", nil)
97
+
98
+ r.add_table('IMAGE_TABLE', @list) do |t|
99
+ t.add_column(:image_name, :name)
100
+ t.add_image('IMAGE_IN_TABLE_01', :path)
101
+ t.add_image('IMAGE_IN_TABLE_02', :path2)
102
+ end
103
+
104
+ r.add_section('SECTION', @list) do |t|
105
+ t.add_field(:image_name, :name)
106
+ t.add_image('IMAGE_IN_SECTION_01', :path2)
107
+ t.add_image('IMAGE_IN_SECTION_02', :path)
108
+ end
109
+
110
+ end
111
+
112
+ report.generate("spec/result/images.odt")
113
+
114
+ @data = Inspector.new("spec/result/images.odt")
115
+
116
+ end
117
+
118
+ it "removes nil images in report" do
119
+ expect(@data.xml.at_css("draw|frame[@draw|name='IMAGE_01']")).to be
120
+ expect(@data.xml.at_css("draw|frame[@draw|name='IMAGE_02']")).to be_nil
121
+ end
122
+
123
+ it "removes nil images in tables" do
124
+
125
+ table = @data.xml.at_xpath(".//table:table[@table:name='IMAGE_TABLE']")
126
+
127
+ images = table.xpath(".//table:table-row[1]//draw:image")
128
+ expect(File.basename(images[0].attribute('href').value)).to eq File.basename(@list[0].path)
129
+ expect(File.basename(images[1].attribute('href').value)).to eq File.basename(@list[0].path2)
130
+
131
+ images = table.xpath(".//table:table-row[2]//draw:image")
132
+ expect(File.basename(images[0].attribute('href').value)).to eq File.basename(@list[1].path)
133
+ expect(images[1]).to be_nil
134
+
135
+ images = table.xpath(".//table:table-row[3]//draw:image")
136
+ expect(File.basename(images[0].attribute('href').value)).to eq File.basename(@list[2].path2)
137
+ expect(images[1]).to be_nil
138
+
139
+ end
140
+
141
+ it "removes nil images in sections " do
142
+
143
+ images = @data.xml.xpath(".//text:section[1]//draw:image")
144
+ expect(File.basename(images[0].attribute('href').value)).to eq File.basename(@list[0].path)
145
+ expect(File.basename(images[1].attribute('href').value)).to eq File.basename(@list[0].path2)
146
+
147
+ images = @data.xml.xpath(".//text:section[2]//draw:image")
148
+ expect(File.basename(images[0].attribute('href').value)).to eq File.basename(@list[1].path)
149
+ expect(images[1]).to be_nil
150
+
151
+ images = @data.xml.xpath(".//text:section[3]//draw:image")
152
+ expect(File.basename(images[0].attribute('href').value)).to eq File.basename(@list[2].path2)
153
+ expect(images[1]).to be_nil
154
+
155
+ end
156
+
157
+ end
158
+
159
+ end
@@ -0,0 +1,51 @@
1
+ RSpec.describe "Sections" do
2
+
3
+ before(:context) do
4
+ @itens = Item.get_list(3)
5
+
6
+ report = ODFReport::Report.new("spec/templates/specs.odt") do |r|
7
+
8
+ r.add_section('SECTION_01', @itens) do |t|
9
+ t.add_field(:s01_field_01, :id)
10
+ t.add_field(:s01_field_02, :name)
11
+ end
12
+
13
+ r.add_section('SECTION_02', []) do |t|
14
+ t.add_field(:s02_field_01, :id)
15
+ t.add_field(:s02_field_02, :name)
16
+ end
17
+
18
+ r.add_section('SECTION_03', nil) do |t|
19
+ t.add_field(:s03_field_01, :id)
20
+ t.add_field(:s03_field_02, :name)
21
+ end
22
+
23
+ end
24
+
25
+ report.generate("spec/result/specs.odt")
26
+
27
+ @data = Inspector.new("spec/result/specs.odt")
28
+
29
+ end
30
+
31
+ it "should render section with collection" do
32
+ @itens.each_with_index do |item, idx|
33
+ section = @data.xml.at_xpath(".//text:section[#{idx+1}]").to_s
34
+
35
+ expect(section).to match(item.id.to_s)
36
+ expect(section).to match(item.name)
37
+ end
38
+ end
39
+
40
+ it "should remove section with empty collection" do
41
+ section = @data.xml.at_css("text|section[@text|name='SECTION_02']")
42
+ expect(section).to be_nil
43
+ end
44
+
45
+ it "should remove section with nil collection" do
46
+ section = @data.xml.at_css("text|section[@text|name='SECTION_03']")
47
+ expect(section).to be_nil
48
+ end
49
+
50
+
51
+ end
@@ -12,11 +12,9 @@ class Item
12
12
  end
13
13
 
14
14
  def self.get_list(quant = 3)
15
- r = []
16
- (1..quant).each do |i|
17
- r << Item.new(Faker::Number.number(10), Faker::Name.name)
15
+ (1..quant).map do |i|
16
+ Item.new(Faker::Number.number(digits: 10), Faker::Name.name)
18
17
  end
19
- r
20
18
  end
21
19
 
22
20
  end
@@ -2,7 +2,7 @@ RSpec.describe "Tables" do
2
2
 
3
3
  before(:context) do
4
4
 
5
- report = ODFReport::Report.new("spec/specs.odt") do |r|
5
+ report = ODFReport::Report.new("spec/templates/specs.odt") do |r|
6
6
 
7
7
  r.add_table('TABLE_02', []) do |t|
8
8
  t.add_column(:column_01, :id)
@@ -0,0 +1,45 @@
1
+ RSpec.describe "Templates Types" do
2
+
3
+ before(:each) do
4
+
5
+ @field_01 = Faker::Company.name
6
+ @field_02 = Faker::Name.name
7
+
8
+ report.add_field(:field_01, @field_01)
9
+ report.add_field(:field_02, @field_02)
10
+
11
+ report.generate("spec/result/specs.odt")
12
+
13
+ @data = Inspector.new("spec/result/specs.odt")
14
+
15
+ end
16
+
17
+ context "template from file" do
18
+ let(:report) { ODFReport::Report.new("spec/templates/specs.odt") }
19
+
20
+ it "works" do
21
+
22
+ expect(@data.text).not_to match(/\[FIELD_01\]/)
23
+ expect(@data.text).not_to match(/\[FIELD_02\]/)
24
+
25
+ expect(@data.text).to match @field_01
26
+ expect(@data.text).to match @field_02
27
+
28
+ end
29
+ end
30
+
31
+ context "template from a String" do
32
+ let(:report) { ODFReport::Report.new(io: File.open("spec/templates/specs.odt").read) }
33
+
34
+ it "works" do
35
+
36
+ expect(@data.text).not_to match(/\[FIELD_01\]/)
37
+ expect(@data.text).not_to match(/\[FIELD_02\]/)
38
+
39
+ expect(@data.text).to match @field_01
40
+ expect(@data.text).to match @field_02
41
+
42
+ end
43
+ end
44
+
45
+ end