pdf_editor 0.0.1

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.
@@ -0,0 +1,55 @@
1
+ require 'support/spec_helper'
2
+
3
+ module PdfEditor
4
+ describe RemovePages do
5
+
6
+ before do
7
+ file_path = ::File.join(::File.dirname(__FILE__), 'support', 'docs', 'five_page.pdf')
8
+ ::File.open(file_path, 'r') do |f|
9
+ ::Tempfile.open(['', '.pdf']) do |tf|
10
+ tf.write f.read
11
+ @resource = PdfEditor::Resource.new(tf)
12
+ end
13
+ end
14
+ end
15
+
16
+ describe '#call' do
17
+
18
+ it 'returns a document with the pages removed' do
19
+ ret = PdfEditor::RemovePages.call(resource: @resource, page_order: [2,1,5])
20
+ contents = []
21
+ ret.open_file do |f|
22
+ PDF::Reader.new(f).pages.each {|page| contents << page.text}
23
+ end
24
+ contents = contents.join(' ')
25
+ expect(contents).to eq 'Page 1 Page 2 Page 5'
26
+ end
27
+
28
+ end
29
+
30
+ describe '#find_consecutives' do
31
+
32
+ it 'returns consecutives in the proper format' do
33
+ service = PdfEditor::RemovePages.new(resource: @resource, page_order: [1,5,6,2,10,11,3])
34
+ expected_format = [[1,2,3], [5,6], [10,11]]
35
+ expect(service.send(:find_consecutives)).to eq expected_format
36
+ end
37
+
38
+ end
39
+
40
+ describe '#format_command' do
41
+
42
+ it 'returns the proper format' do
43
+ expected_format = [
44
+ {:pdf => @resource.path, :start => 1, :end => 3},
45
+ {:pdf => @resource.path, :start => 5, :end => 6},
46
+ {:pdf => @resource.path, :start => 10, :end => 11}
47
+ ]
48
+ service = PdfEditor::RemovePages.new(resource: @resource, page_order: [1,5,6,2,10,11,3])
49
+ expect(service.send(:format_command)).to eq expected_format
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,7 @@
1
+ require 'support/spec_helper'
2
+
3
+ module PdfEditor
4
+ describe Reorder do
5
+
6
+ end
7
+ end
@@ -0,0 +1,129 @@
1
+ require 'support/spec_helper'
2
+
3
+ module PdfEditor
4
+ describe Resource do
5
+
6
+ before :each do
7
+ tempfile = ::Tempfile.new(['', '.pdf'])
8
+ @resource = Resource.new(tempfile, 'open file test')
9
+ end
10
+
11
+ describe '#read' do
12
+
13
+ it 'calls open file' do
14
+ @resource.stub(:open_file) { @resource.file }
15
+ expect(@resource).to receive(:open_file)
16
+ @resource.read
17
+ end
18
+
19
+ it 'rewinds before reading' do
20
+ contents = 'Move the buffer position'
21
+ @resource << contents
22
+ expect(@resource.read).to eq contents
23
+ end
24
+
25
+ end
26
+
27
+ describe '#open_file' do
28
+
29
+ context 'when file is closed' do
30
+
31
+ it 'opens file' do
32
+ @resource.open_file do |f|
33
+ expect(f).to_not be_closed
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ context 'when file is open' do
40
+
41
+ it 'yields open file' do
42
+ @resource.close
43
+ @resource.open_file do |f|
44
+ expect(f).to_not be_closed
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+ it 'closes file after yield' do
51
+ @resource.open_file do |f|
52
+ f.write "yippee!"
53
+ end
54
+ expect(@resource).to be_closed
55
+ end
56
+
57
+ end
58
+
59
+ describe '#write' do
60
+
61
+ it 'writes the contents to the file' do
62
+ contents = 'ABCDEF'
63
+ @resource.open
64
+ @resource.write(contents)
65
+ @resource.rewind
66
+ expect(@resource.file.read).to eq contents
67
+ end
68
+
69
+ end
70
+
71
+ describe '#page_count' do
72
+
73
+ context 'when file is a pdf' do
74
+
75
+ it 'returns the number of pages of the file' do
76
+ file_path = File.join(File.dirname(__FILE__), 'support', 'docs', 'two_page.pdf')
77
+
78
+ File.open(file_path, 'r') do |file|
79
+ resource = Resource.new(file, 'pdf test')
80
+ expect(resource.page_count).to eq 2
81
+ end
82
+ end
83
+
84
+ end
85
+
86
+ context 'when file is not a pdf' do
87
+
88
+ it 'raises an error' do
89
+ file_path = File.join(File.dirname(__FILE__), 'support', 'docs', 'not_a_pdf.txt')
90
+
91
+ File.open(file_path, 'r') do |file|
92
+ resource = Resource.new(file, 'pdf test')
93
+ expect{resource.page_count}.to raise_error PdfEditor::Errors::InvalidPDFError
94
+ end
95
+ end
96
+
97
+ end
98
+
99
+ end
100
+
101
+ describe '#method_missing' do
102
+
103
+ it 'delegates messages to file when it responds to them' do
104
+ [:delete, :open, :path, :size, :read, :close, :close!].each do |io_interface|
105
+ expect(@resource).to respond_to io_interface
106
+ end
107
+ end
108
+
109
+ it 'does not delegate when file does not respond to a message' do
110
+ messages = [:goofy, :mickey, :bigbird]
111
+ @resource.file.stub(:goofy) { 'goofy' }
112
+ @resource.file.stub(:mickey) { 'mickey' }
113
+ @resource.file.stub(:bigbird) { 'bigbird' }
114
+ messages.each do |bunk_message|
115
+ @resource.send(bunk_message)
116
+ end
117
+ messages.each do |bunk_message|
118
+ expect(@resource.file).to_not receive(bunk_message)
119
+ end
120
+ end
121
+
122
+ end
123
+
124
+ after :each do
125
+ @resource.close!
126
+ end
127
+
128
+ end
129
+ end
@@ -0,0 +1,85 @@
1
+ require 'support/spec_helper'
2
+
3
+ module PdfEditor
4
+ describe RotatePage do
5
+
6
+ before do
7
+ @resource = get_resource('two_page.pdf')
8
+ end
9
+
10
+ describe '#call' do
11
+
12
+ it 'rotates the page to the left' do
13
+ # rotation of document is calculated clockwise
14
+ before = %x(pdftk #{@resource.file.path} dump_data | grep PageMediaRotation | sed 's/[^0-9]*//').split("\n")
15
+ ret = PdfEditor::RotatePage.call(resource: @resource, page: 1, rotate: :left)
16
+ after = %x(pdftk #{ret.file.path} dump_data | grep PageMediaRotation | sed 's/[^0-9]*//').split("\n")
17
+ expect(before[0].to_i).to eq 0
18
+ expect(after[0].to_i).to eq 270
19
+ end
20
+
21
+ it 'rotates the page to the right' do
22
+ # rotation of document is calculated clockwise
23
+ before = %x(pdftk #{@resource.file.path} dump_data | grep PageMediaRotation | sed 's/[^0-9]*//').split("\n")
24
+ ret = PdfEditor::RotatePage.call(resource: @resource, page: 1, rotate: :right)
25
+ after = %x(pdftk #{ret.file.path} dump_data | grep PageMediaRotation | sed 's/[^0-9]*//').split("\n")
26
+ expect(before[0].to_i).to eq 0
27
+ expect(after[0].to_i).to eq 90
28
+ end
29
+
30
+ it 'rotates the page upside down' do
31
+ # rotation of document is calculated clockwise
32
+ before = %x(pdftk #{@resource.file.path} dump_data | grep PageMediaRotation | sed 's/[^0-9]*//').split("\n")
33
+ ret = PdfEditor::RotatePage.call(resource: @resource, page: 1, rotate: :flip)
34
+ after = %x(pdftk #{ret.file.path} dump_data | grep PageMediaRotation | sed 's/[^0-9]*//').split("\n")
35
+ expect(before[0].to_i).to eq 0
36
+ expect(after[0].to_i).to eq 180
37
+ end
38
+
39
+ it 'raises an error if resource is not present' do
40
+ expect{PdfEditor::RotatePage.call(page: 1, rotate: :left)}.to raise_error PdfEditor::Errors::ArgumentMissingError
41
+ end
42
+
43
+ it 'raises an error if page is not present' do
44
+ expect{PdfEditor::RotatePage.call(resource: @resource, rotate: :left)}.to raise_error PdfEditor::Errors::ArgumentMissingError
45
+ end
46
+
47
+ it 'raises an error if rotate is not present' do
48
+ expect{PdfEditor::RotatePage.call(resource: @resource, page: 1)}.to raise_error PdfEditor::Errors::ArgumentMissingError
49
+ end
50
+
51
+ end
52
+
53
+ describe '#get_page_count' do
54
+
55
+ it 'raises an error if page count is 0' do
56
+ @resource.stub(:page_count) { 0 }
57
+ service = PdfEditor::RotatePage.new(resource: @resource, page: 1, rotate: :left)
58
+ expect{service.send(:get_page_count)}.to raise_error PdfEditor::Errors::PageRangeError
59
+ end
60
+
61
+ it 'raises an error if page is out of range' do
62
+ @resource.stub(:page_count) { 2 }
63
+ service = PdfEditor::RotatePage.new(resource: @resource, page: 3, rotate: :left)
64
+ expect{service.send(:get_page_count)}.to raise_error PdfEditor::Errors::PageRangeError
65
+ end
66
+
67
+ end
68
+
69
+ describe '#format_command' do
70
+
71
+ it 'returns the proper format' do
72
+ resource = get_resource('five_page.pdf')
73
+ expected_format = [
74
+ {:pdf => resource.path, :start => 1, :end => 3},
75
+ {:pdf => resource.path, :start => 4, :end => 4, :orientation => 'left'},
76
+ {:pdf => resource.path, :start => 5, :end => 5}
77
+ ]
78
+ service = PdfEditor::RotatePage.new(resource: resource, page: 4, rotate: :left)
79
+ expect(service.send(:format_command)).to eq expected_format
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,69 @@
1
+ require 'support/spec_helper'
2
+
3
+ module PdfEditor
4
+ describe Shuffle do
5
+
6
+ before do
7
+ ::File.open(::File.join(::File.dirname(__FILE__), 'support', 'docs', 'five_page.pdf'), 'r') do |f|
8
+ ::Tempfile.open(['', '.pdf']) do |tf|
9
+ tf.write f.read
10
+ @resource = PdfEditor::Resource.new(tf)
11
+ end
12
+ end
13
+ end
14
+
15
+ describe '#call' do
16
+
17
+ it 'raises an error if resource is nil' do
18
+ expect{PdfEditor::Shuffle.call(page_order: [1,2])}.to raise_error PdfEditor::Errors::ResourcesEmptyError
19
+ end
20
+
21
+ it 'raises an error if page_order is empty' do
22
+ expect{PdfEditor::Shuffle.call(resource: @resource)}.to raise_error PdfEditor::Errors::PageOrderInvalidError
23
+ end
24
+
25
+ it 'returns a resource' do
26
+ ret = PdfEditor::Shuffle.call(resource: @resource, page_order: [5, 4, 3, 1, 2])
27
+ expect(ret).to be_instance_of PdfEditor::Resource
28
+ end
29
+
30
+ it 'returns a document in the correct order' do
31
+ ret = PdfEditor::Shuffle.call(resource: @resource, page_order: [5, 4, 3, 1, 2])
32
+ contents = []
33
+ ret.open_file do |f|
34
+ PDF::Reader.new(f).pages.each {|page| contents << page.text}
35
+ end
36
+ contents = contents.join(' ')
37
+ expect(contents).to eq 'Page 5 Page 4 Page 3 Page 1 Page 2'
38
+ end
39
+
40
+ it 'can work with duplicates' do
41
+ ret = PdfEditor::Shuffle.call(resource: @resource, page_order: [5, 4, 3, 1, 2, 5])
42
+ contents = []
43
+ ret.open_file do |f|
44
+ PDF::Reader.new(f).pages.each {|page| contents << page.text}
45
+ end
46
+ contents = contents.join(' ')
47
+ expect(contents).to eq 'Page 5 Page 4 Page 3 Page 1 Page 2 Page 5'
48
+ end
49
+
50
+ end
51
+
52
+ describe '#format_command' do
53
+
54
+ it 'returns the correct format' do
55
+ expected_format = [
56
+ {:pdf => @resource.path, :start => 5, :end => 5},
57
+ {:pdf => @resource.path, :start => 4, :end => 4},
58
+ {:pdf => @resource.path, :start => 3, :end => 3},
59
+ {:pdf => @resource.path, :start => 1, :end => 1},
60
+ {:pdf => @resource.path, :start => 2, :end => 2}
61
+ ]
62
+ service = PdfEditor::Shuffle.new(resource: @resource, page_order: [5, 4, 3, 1, 2])
63
+ expect(service.send(:format_command)).to eq expected_format
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,265 @@
1
+ %PDF-1.3
2
+ %����
3
+ 4 0 obj
4
+ <<
5
+ /BaseFont /Helvetica
6
+ /Subtype /Type1
7
+ /Type /Font
8
+ /Encoding /WinAnsiEncoding
9
+ >>
10
+ endobj
11
+ 5 0 obj
12
+ <<
13
+ /Length 79
14
+ >>
15
+ stream
16
+ q
17
+
18
+ BT
19
+ 243.42000000000002 697.28 Td
20
+ /F1.0 40 Tf
21
+ [<50> 40 <6167652031>] TJ
22
+ ET
23
+
24
+ Q
25
+
26
+ endstream
27
+ endobj
28
+ 3 0 obj
29
+ <<
30
+ /Parent 1 0 R
31
+ /MediaBox [0 0 612.0 792.0]
32
+ /Resources
33
+ <<
34
+ /Font
35
+ <<
36
+ /F1.0 4 0 R
37
+ >>
38
+ /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
39
+ >>
40
+ /Type /Page
41
+ /Contents 5 0 R
42
+ >>
43
+ endobj
44
+ 8 0 obj
45
+ <<
46
+ /BaseFont /Helvetica
47
+ /Subtype /Type1
48
+ /Type /Font
49
+ /Encoding /WinAnsiEncoding
50
+ >>
51
+ endobj
52
+ 9 0 obj
53
+ <<
54
+ /Length 79
55
+ >>
56
+ stream
57
+ q
58
+
59
+ BT
60
+ 243.42000000000002 697.28 Td
61
+ /F1.0 40 Tf
62
+ [<50> 40 <6167652032>] TJ
63
+ ET
64
+
65
+ Q
66
+
67
+ endstream
68
+ endobj
69
+ 7 0 obj
70
+ <<
71
+ /Parent 1 0 R
72
+ /MediaBox [0 0 612.0 792.0]
73
+ /Resources
74
+ <<
75
+ /Font
76
+ <<
77
+ /F1.0 8 0 R
78
+ >>
79
+ /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
80
+ >>
81
+ /Type /Page
82
+ /Contents 9 0 R
83
+ >>
84
+ endobj
85
+ 12 0 obj
86
+ <<
87
+ /BaseFont /Helvetica
88
+ /Subtype /Type1
89
+ /Type /Font
90
+ /Encoding /WinAnsiEncoding
91
+ >>
92
+ endobj
93
+ 13 0 obj
94
+ <<
95
+ /Length 79
96
+ >>
97
+ stream
98
+ q
99
+
100
+ BT
101
+ 243.42000000000002 697.28 Td
102
+ /F1.0 40 Tf
103
+ [<50> 40 <6167652033>] TJ
104
+ ET
105
+
106
+ Q
107
+
108
+ endstream
109
+ endobj
110
+ 11 0 obj
111
+ <<
112
+ /Parent 1 0 R
113
+ /MediaBox [0 0 612.0 792.0]
114
+ /Resources
115
+ <<
116
+ /Font
117
+ <<
118
+ /F1.0 12 0 R
119
+ >>
120
+ /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
121
+ >>
122
+ /Type /Page
123
+ /Contents 13 0 R
124
+ >>
125
+ endobj
126
+ 16 0 obj
127
+ <<
128
+ /BaseFont /Helvetica
129
+ /Subtype /Type1
130
+ /Type /Font
131
+ /Encoding /WinAnsiEncoding
132
+ >>
133
+ endobj
134
+ 17 0 obj
135
+ <<
136
+ /Length 79
137
+ >>
138
+ stream
139
+ q
140
+
141
+ BT
142
+ 243.42000000000002 697.28 Td
143
+ /F1.0 40 Tf
144
+ [<50> 40 <6167652034>] TJ
145
+ ET
146
+
147
+ Q
148
+
149
+ endstream
150
+ endobj
151
+ 15 0 obj
152
+ <<
153
+ /Parent 1 0 R
154
+ /MediaBox [0 0 612.0 792.0]
155
+ /Resources
156
+ <<
157
+ /Font
158
+ <<
159
+ /F1.0 16 0 R
160
+ >>
161
+ /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
162
+ >>
163
+ /Type /Page
164
+ /Contents 17 0 R
165
+ >>
166
+ endobj
167
+ 20 0 obj
168
+ <<
169
+ /BaseFont /Helvetica
170
+ /Subtype /Type1
171
+ /Type /Font
172
+ /Encoding /WinAnsiEncoding
173
+ >>
174
+ endobj
175
+ 21 0 obj
176
+ <<
177
+ /Length 79
178
+ >>
179
+ stream
180
+ q
181
+
182
+ BT
183
+ 243.42000000000002 697.28 Td
184
+ /F1.0 40 Tf
185
+ [<50> 40 <6167652035>] TJ
186
+ ET
187
+
188
+ Q
189
+
190
+ endstream
191
+ endobj
192
+ 19 0 obj
193
+ <<
194
+ /Parent 1 0 R
195
+ /MediaBox [0 0 612.0 792.0]
196
+ /Resources
197
+ <<
198
+ /Font
199
+ <<
200
+ /F1.0 20 0 R
201
+ >>
202
+ /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
203
+ >>
204
+ /Type /Page
205
+ /Contents 21 0 R
206
+ >>
207
+ endobj
208
+ 1 0 obj
209
+ <<
210
+ /Kids [3 0 R 7 0 R 11 0 R 15 0 R 19 0 R]
211
+ /Count 5
212
+ /Type /Pages
213
+ >>
214
+ endobj
215
+ 23 0 obj
216
+ <<
217
+ /Pages 1 0 R
218
+ /Type /Catalog
219
+ >>
220
+ endobj
221
+ 24 0 obj
222
+ <<
223
+ /Creator (pdftk 2.02 - www.pdftk.com)
224
+ /Producer (itext-paulo-155 \(itextpdf.sf.net-lowagie.com\))
225
+ /ModDate (D:20150130172938-05'00')
226
+ /CreationDate (D:20150130172938-05'00')
227
+ >>
228
+ endobj xref
229
+ 0 25
230
+ 0000000000 65535 f
231
+ 0000002095 00000 n
232
+ 0000000000 65535 f
233
+ 0000000246 00000 n
234
+ 0000000015 00000 n
235
+ 0000000114 00000 n
236
+ 0000000000 65535 f
237
+ 0000000659 00000 n
238
+ 0000000428 00000 n
239
+ 0000000527 00000 n
240
+ 0000000000 65535 f
241
+ 0000001074 00000 n
242
+ 0000000841 00000 n
243
+ 0000000941 00000 n
244
+ 0000000000 65535 f
245
+ 0000001492 00000 n
246
+ 0000001259 00000 n
247
+ 0000001359 00000 n
248
+ 0000000000 65535 f
249
+ 0000001910 00000 n
250
+ 0000001677 00000 n
251
+ 0000001777 00000 n
252
+ 0000000000 65535 f
253
+ 0000002181 00000 n
254
+ 0000002233 00000 n
255
+ trailer
256
+
257
+ <<
258
+ /Info 24 0 R
259
+ /Root 23 0 R
260
+ /Size 25
261
+ /ID [<efd12ae32a2d94a233cd2cfbb2f19c8f><ce8debdccc19e1eaf1cf262837a6f4e0>]
262
+ >>
263
+ startxref
264
+ 2429
265
+ %%EOF