dragonfly_pdf 2.0.1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +2 -2
- data/CHANGELOG.md +5 -0
- data/README.md +9 -0
- data/dragonfly_pdf.gemspec +4 -4
- data/lib/dragonfly_pdf.rb +9 -0
- data/lib/dragonfly_pdf/analysers/pdf_properties.rb +9 -6
- data/lib/dragonfly_pdf/plugin.rb +18 -37
- data/lib/dragonfly_pdf/processors/append.rb +4 -2
- data/lib/dragonfly_pdf/processors/convert.rb +26 -21
- data/lib/dragonfly_pdf/processors/page.rb +4 -3
- data/lib/dragonfly_pdf/processors/page_thumb.rb +17 -14
- data/lib/dragonfly_pdf/processors/remove_password.rb +3 -1
- data/lib/dragonfly_pdf/processors/rotate.rb +5 -3
- data/lib/dragonfly_pdf/processors/stamp.rb +3 -1
- data/lib/dragonfly_pdf/processors/subset_fonts.rb +3 -1
- data/lib/dragonfly_pdf/version.rb +1 -1
- data/test/dragonfly_pdf/analysers/pdf_properties_test.rb +6 -35
- data/test/dragonfly_pdf/plugin_test.rb +17 -59
- data/test/dragonfly_pdf/processors/append_test.rb +7 -5
- data/test/dragonfly_pdf/processors/convert_test.rb +15 -36
- data/test/dragonfly_pdf/processors/page_test.rb +9 -9
- data/test/dragonfly_pdf/processors/page_thumb_test.rb +12 -14
- data/test/dragonfly_pdf/processors/remove_password_test.rb +7 -4
- data/test/dragonfly_pdf/processors/rotate_test.rb +11 -10
- data/test/dragonfly_pdf/processors/stamp_test.rb +7 -9
- data/test/dragonfly_pdf/processors/subset_fonts_test.rb +7 -2
- data/test/test_helper.rb +6 -7
- metadata +19 -20
- data/lib/dragonfly_pdf/errors.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 76f9364c0e260943bd144490065c03b31df16566dfc5edfbdfb8a43a201a5bd7
|
4
|
+
data.tar.gz: 9d632fb7d1f1d52bae8f2be9b1aabc850d6f2581fdb0ef3502bb1d408df200f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 40d25571ea32a0b72e253cfd3db2efed9fa22d4e1d7cfc06a5d53101887f3cb058ecc28d9c2445561842a89c062434b9b632d3d075667b7c2cdeb17d089eab73
|
7
|
+
data.tar.gz: a7c119532f70acbd4b0dad5e329aacc9ab0cfb5ae5750f21742837b98d799225904c33017c03ac81c80fee0f6c3e3fdb0c989c1086ce72af3558bf0495c7fa6c
|
data/.travis.yml
CHANGED
@@ -12,8 +12,8 @@ before_install:
|
|
12
12
|
- sudo apt-get update
|
13
13
|
- sudo apt-get install -y pdftk
|
14
14
|
- sudo apt-get install -y ghostscript
|
15
|
-
- curl -OL https://mupdf.com/downloads/mupdf-1.
|
16
|
-
- tar zvxf mupdf-1.
|
15
|
+
- curl -OL https://mupdf.com/downloads/mupdf-1.13.0-source.tar.gz
|
16
|
+
- tar zvxf mupdf-1.13.0-source.tar.gz && cd mupdf-1.13.0-source && sudo make HAVE_X11=no HAVE_GLUT=no prefix=/usr/local install
|
17
17
|
- sudo apt-get install -y gobject-introspection libgirepository1.0-dev libglib2.0-dev libpoppler-glib-dev
|
18
18
|
- curl -OL https://github.com/jcupitt/libvips/releases/download/v8.5.8/vips-8.5.8.tar.gz
|
19
19
|
- tar zvxf vips-8.5.8.tar.gz && cd vips-8.5.8 && ./configure && sudo make && sudo make install
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 2.1.0
|
4
|
+
|
5
|
+
* add `SUPPORTED_FORMATS` and `SUPPORTED_OUTPUT_FORMATS` and raise errors when formats are not matching
|
6
|
+
* add more thorough tests for supported formats
|
7
|
+
|
3
8
|
## 2.0.1
|
4
9
|
|
5
10
|
* fixed: a bug in Convert and Page Thumb Processors which caused the url to not include file extension
|
data/README.md
CHANGED
@@ -41,6 +41,15 @@ Dragonfly.app.configure do
|
|
41
41
|
end
|
42
42
|
```
|
43
43
|
|
44
|
+
## Supported Formats
|
45
|
+
|
46
|
+
List of supported formats is available as:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
DragonflyPdf::SUPPORTED_FORMATS # => ["pdf"]
|
50
|
+
DragonflyPdf::SUPPORTED_OUTPUT_FORMATS # => ["pdf", "svg", …]
|
51
|
+
```
|
52
|
+
|
44
53
|
## Analysers
|
45
54
|
|
46
55
|
### PDF properties
|
data/dragonfly_pdf.gemspec
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('
|
1
|
+
|
2
|
+
lib = File.expand_path('lib', __dir__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
require 'dragonfly_pdf/version'
|
5
5
|
|
@@ -19,13 +19,13 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
21
|
spec.add_dependency 'dragonfly', '~> 1.0'
|
22
|
-
spec.add_dependency 'dragonfly_libvips', '~> 2.
|
23
|
-
spec.add_dependency 'activesupport', '>= 4.0'
|
22
|
+
spec.add_dependency 'dragonfly_libvips', '~> 2.2.0'
|
24
23
|
|
25
24
|
spec.add_development_dependency 'bundler', '~> 1.12'
|
26
25
|
spec.add_development_dependency 'guard'
|
27
26
|
spec.add_development_dependency 'guard-minitest'
|
28
27
|
spec.add_development_dependency 'minitest', '~> 5.0'
|
28
|
+
spec.add_development_dependency 'minitest-reporters'
|
29
29
|
spec.add_development_dependency 'rake', '~> 10.0'
|
30
30
|
spec.add_development_dependency 'pdf-reader'
|
31
31
|
end
|
data/lib/dragonfly_pdf.rb
CHANGED
@@ -1,3 +1,12 @@
|
|
1
1
|
require 'dragonfly'
|
2
|
+
require 'dragonfly_libvips'
|
2
3
|
require 'dragonfly_pdf/plugin'
|
3
4
|
require 'dragonfly_pdf/version'
|
5
|
+
|
6
|
+
module DragonflyPdf
|
7
|
+
class PageNotFound < RuntimeError; end
|
8
|
+
class UnsupportedFormat < RuntimeError; end
|
9
|
+
|
10
|
+
SUPPORTED_FORMATS = %w[pdf].freeze
|
11
|
+
SUPPORTED_OUTPUT_FORMATS = %w[png pam pbm pkm pnm pdf tga svg].uniq.sort
|
12
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
module DragonflyPdf
|
2
2
|
module Analysers
|
3
3
|
class PdfProperties
|
4
|
-
def call(content,
|
4
|
+
def call(content, options = {})
|
5
|
+
return {} unless SUPPORTED_FORMATS.include?(content.ext)
|
6
|
+
|
5
7
|
data = `pdftk #{content.path} dump_data`
|
6
8
|
|
7
9
|
page_count = data.scan(/NumberOfPages: (\d+)/).flatten.first.to_i
|
@@ -13,11 +15,12 @@ module DragonflyPdf
|
|
13
15
|
aspect_ratios = page_dimensions.inject([]) { |res, page| res << (page.first / page.last) }
|
14
16
|
|
15
17
|
{
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
'format' => content.ext.downcase,
|
19
|
+
'aspect_ratios' => aspect_ratios,
|
20
|
+
'page_count' => page_count,
|
21
|
+
'page_dimensions' => page_dimensions,
|
22
|
+
'page_numbers' => page_numbers,
|
23
|
+
'page_rotations' => page_rotations
|
21
24
|
}
|
22
25
|
end
|
23
26
|
|
data/lib/dragonfly_pdf/plugin.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/core_ext/hash'
|
2
|
-
|
3
1
|
require 'dragonfly_pdf/analysers/pdf_properties'
|
4
2
|
|
5
3
|
require 'dragonfly_pdf/processors/append'
|
@@ -11,47 +9,30 @@ require 'dragonfly_pdf/processors/rotate'
|
|
11
9
|
require 'dragonfly_pdf/processors/stamp'
|
12
10
|
require 'dragonfly_pdf/processors/subset_fonts'
|
13
11
|
|
14
|
-
require 'dragonfly_libvips'
|
15
|
-
require 'dragonfly_libvips/analysers/image_properties'
|
16
|
-
require 'dragonfly_libvips/processors/thumb'
|
17
|
-
|
18
12
|
module DragonflyPdf
|
19
13
|
class Plugin
|
20
14
|
def call(app, _opts = {})
|
21
|
-
app.add_analyser :
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
app.add_analyser :page_dimensions do |content|
|
33
|
-
content.analyse(:pdf_properties)[:page_dimensions]
|
34
|
-
end
|
35
|
-
|
36
|
-
app.add_analyser :page_rotations do |content|
|
37
|
-
content.analyse(:pdf_properties)[:page_rotations]
|
38
|
-
end
|
39
|
-
|
40
|
-
app.add_analyser :aspect_ratios do |content|
|
41
|
-
content.analyse(:pdf_properties)[:aspect_ratios]
|
15
|
+
app.add_analyser :pdf_properties, Analysers::PdfProperties.new
|
16
|
+
|
17
|
+
%w[ page_count
|
18
|
+
page_numbers
|
19
|
+
page_dimensions
|
20
|
+
page_rotations
|
21
|
+
aspect_ratios
|
22
|
+
].each do |name|
|
23
|
+
app.add_analyser(name) { |c| c.analyse(:pdf_properties)[name] }
|
42
24
|
end
|
43
25
|
|
44
|
-
|
26
|
+
app.add_processor :append, Processors::Append.new
|
27
|
+
app.add_processor :convert, Processors::Convert.new
|
28
|
+
app.add_processor :page, Processors::Page.new
|
29
|
+
app.add_processor :remove_password, Processors::RemovePassword.new
|
30
|
+
app.add_processor :rotate, Processors::Rotate.new
|
31
|
+
app.add_processor :stamp, Processors::Stamp.new
|
32
|
+
app.add_processor :subset_fonts, Processors::SubsetFonts.new
|
33
|
+
app.add_processor :page_thumb, Processors::PageThumb.new
|
45
34
|
|
46
|
-
app.
|
47
|
-
app.add_processor :convert, DragonflyPdf::Processors::Convert.new
|
48
|
-
app.add_processor :page, DragonflyPdf::Processors::Page.new
|
49
|
-
app.add_processor :remove_password, DragonflyPdf::Processors::RemovePassword.new
|
50
|
-
app.add_processor :rotate, DragonflyPdf::Processors::Rotate.new
|
51
|
-
app.add_processor :stamp, DragonflyPdf::Processors::Stamp.new
|
52
|
-
app.add_processor :subset_fonts, DragonflyPdf::Processors::SubsetFonts.new
|
53
|
-
app.add_processor :thumb, DragonflyLibvips::Processors::Thumb.new
|
54
|
-
app.add_processor :page_thumb, DragonflyPdf::Processors::PageThumb.new
|
35
|
+
app.define(:encode) { convert }
|
55
36
|
end
|
56
37
|
end
|
57
38
|
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
module DragonflyPdf
|
2
2
|
module Processors
|
3
3
|
class Append
|
4
|
-
def call(content, pdfs_to_append,
|
5
|
-
content.
|
4
|
+
def call(content, pdfs_to_append, options = {})
|
5
|
+
raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
|
6
|
+
|
7
|
+
content.shell_update(ext: 'pdf') do |old_path, new_path|
|
6
8
|
"#{pdftk_command} #{old_path} #{pdfs_to_append.map(&:path).join(' ')} cat output #{new_path}"
|
7
9
|
end
|
8
10
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'dragonfly_libvips
|
1
|
+
require 'dragonfly_libvips'
|
2
2
|
require 'vips'
|
3
3
|
|
4
4
|
module DragonflyPdf
|
@@ -6,20 +6,24 @@ module DragonflyPdf
|
|
6
6
|
class Convert
|
7
7
|
DPI = 600
|
8
8
|
|
9
|
-
def call(content, page, geometry=nil, options = {})
|
10
|
-
|
11
|
-
format = options.fetch(:format, :png)
|
9
|
+
def call(content, page, geometry = nil, options = {})
|
10
|
+
raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
options = options.each_with_object({}) { |(k, v), memo| memo[k.to_s] = v } # stringify keys
|
13
|
+
format = options.fetch('format', 'png').to_s
|
14
|
+
|
15
|
+
raise UnsupportedOutputFormat unless SUPPORTED_OUTPUT_FORMATS.include?(format)
|
16
|
+
|
17
|
+
case format
|
18
|
+
when 'pdf'
|
19
|
+
pdf_options = options.fetch('pdf_options', 'compress,compress-fonts,compress-images,linearize,sanitize,garbage=deduplicate')
|
16
20
|
|
17
21
|
content.shell_update(ext: format) do |old_path, new_path|
|
18
22
|
"#{convert_command} -o #{new_path} -F #{format} -O #{pdf_options} #{old_path} #{page}"
|
19
23
|
end
|
20
24
|
|
21
|
-
when
|
22
|
-
text = options.fetch(
|
25
|
+
when 'svg'
|
26
|
+
text = options.fetch('text', 'path')
|
23
27
|
|
24
28
|
content.shell_update(ext: format) do |old_path, new_path|
|
25
29
|
"#{convert_command} -o #{new_path} -F #{format} -O text=#{text} #{old_path} #{page}"
|
@@ -29,16 +33,18 @@ module DragonflyPdf
|
|
29
33
|
`mv #{content.path.sub(".#{format}", "1.#{format}")} #{content.path}`
|
30
34
|
|
31
35
|
else
|
32
|
-
input_options = options.fetch(
|
33
|
-
input_options[
|
34
|
-
input_options[
|
36
|
+
input_options = options.fetch('input_options', {})
|
37
|
+
input_options['access'] = input_options.fetch('access', 'sequential')
|
38
|
+
input_options['dpi'] = input_options.fetch('dpi', DPI)
|
35
39
|
|
36
40
|
img = ::Vips::Image.new_from_file(content.path, input_options)
|
37
41
|
|
38
42
|
dimensions = case geometry
|
39
|
-
|
40
|
-
|
41
|
-
|
43
|
+
when DragonflyLibvips::Processors::Thumb::RESIZE_GEOMETRY
|
44
|
+
DragonflyLibvips::Dimensions.call(geometry, img.width, img.height)
|
45
|
+
else
|
46
|
+
raise ArgumentError, "Didn't recognise the geometry string: #{geometry}"
|
47
|
+
end
|
42
48
|
|
43
49
|
width = dimensions.width.ceil
|
44
50
|
|
@@ -50,16 +56,15 @@ module DragonflyPdf
|
|
50
56
|
`mv #{content.path.sub(".#{format}", "1.#{format}")} #{content.path}`
|
51
57
|
end
|
52
58
|
|
53
|
-
content.meta['format'] = format
|
59
|
+
content.meta['format'] = format
|
54
60
|
content.ext = format
|
55
61
|
content.meta['mime_type'] = nil # don't need it as we have ext now
|
56
62
|
end
|
57
63
|
|
58
|
-
def update_url(attrs,
|
59
|
-
options = options.
|
60
|
-
format = options.fetch(
|
61
|
-
|
62
|
-
attrs.ext = format.to_s
|
64
|
+
def update_url(attrs, _page, _geometry = nil, options = {})
|
65
|
+
options = options.each_with_object({}) { |(k, v), memo| memo[k.to_s] = v } # stringify keys
|
66
|
+
format = options.fetch('format', 'png').to_s
|
67
|
+
attrs.ext = format
|
63
68
|
end
|
64
69
|
|
65
70
|
private
|
@@ -1,14 +1,15 @@
|
|
1
|
-
require_relative '../errors'
|
2
1
|
require_relative '../analysers/pdf_properties'
|
3
2
|
|
4
3
|
module DragonflyPdf
|
5
4
|
module Processors
|
6
5
|
class Page
|
7
6
|
def call(content, page_number = 1, _opts = {})
|
7
|
+
raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
|
8
|
+
|
8
9
|
pdf_properties = DragonflyPdf::Analysers::PdfProperties.new.call(content)
|
9
|
-
raise DragonflyPdf::PageNotFound unless pdf_properties[
|
10
|
+
raise DragonflyPdf::PageNotFound unless pdf_properties['page_numbers'].include?(page_number)
|
10
11
|
|
11
|
-
content.shell_update(ext:
|
12
|
+
content.shell_update(ext: 'pdf') do |old_path, new_path|
|
12
13
|
"#{gs_command} -dFirstPage=#{page_number} -dLastPage=#{page_number} -o #{new_path} -f #{old_path}"
|
13
14
|
end
|
14
15
|
end
|
@@ -2,38 +2,41 @@ module DragonflyPdf
|
|
2
2
|
module Processors
|
3
3
|
class PageThumb
|
4
4
|
def call(content, page, geometry = nil, options = {})
|
5
|
-
|
6
|
-
|
5
|
+
raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
|
6
|
+
|
7
|
+
options = options.each_with_object({}) { |(k, v), memo| memo[k.to_s] = v } # stringify keys
|
8
|
+
format = options.delete('format') { 'jpg' }.to_s
|
7
9
|
|
8
10
|
convert(content, page, geometry, format)
|
9
11
|
|
10
|
-
unless %
|
12
|
+
unless %w[pdf png svg].include?(format)
|
11
13
|
thumb(content, geometry, format, options)
|
12
14
|
end
|
13
15
|
|
14
|
-
content.meta['format'] = format
|
16
|
+
content.meta['format'] = format
|
15
17
|
content.ext = format
|
16
18
|
content.meta['mime_type'] = nil # don't need it as we have ext now
|
17
19
|
end
|
18
20
|
|
19
|
-
def update_url(attrs,
|
20
|
-
options = options.
|
21
|
-
|
22
|
-
attrs.ext = format.to_s
|
21
|
+
def update_url(attrs, _page, _geometry = nil, options = {})
|
22
|
+
options = options.each_with_object({}) { |(k, v), memo| memo[k.to_s] = v } # stringify keys
|
23
|
+
attrs.ext = options.fetch('format', 'jpg').to_s
|
23
24
|
end
|
24
25
|
|
25
|
-
private
|
26
|
+
private
|
26
27
|
|
27
28
|
def convert(content, page, geometry, format)
|
28
|
-
|
29
|
-
|
30
|
-
|
29
|
+
convert_to_format = case format
|
30
|
+
when 'pdf', 'svg' then format
|
31
|
+
else 'png'
|
31
32
|
end
|
32
|
-
|
33
|
+
|
34
|
+
Convert.new.call(content, page, geometry, 'format' => convert_to_format)
|
33
35
|
end
|
34
36
|
|
35
37
|
def thumb(content, geometry, format, options)
|
36
|
-
|
38
|
+
options['format'] = format
|
39
|
+
DragonflyLibvips::Processors::Thumb.new.call(content, geometry, options)
|
37
40
|
end
|
38
41
|
end
|
39
42
|
end
|
@@ -2,7 +2,9 @@ module DragonflyPdf
|
|
2
2
|
module Processors
|
3
3
|
class RemovePassword
|
4
4
|
def call(content, _options = {})
|
5
|
-
content.
|
5
|
+
raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
|
6
|
+
|
7
|
+
content.shell_update(ext: 'pdf') do |old_path, new_path|
|
6
8
|
"#{gs_command} -q -sOutputFile=#{new_path} -c .setpdfwrite -f #{old_path}"
|
7
9
|
end
|
8
10
|
end
|
@@ -2,16 +2,18 @@ module DragonflyPdf
|
|
2
2
|
module Processors
|
3
3
|
class Rotate
|
4
4
|
def call(content, arg)
|
5
|
+
raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
|
6
|
+
|
5
7
|
rotate_args = case arg
|
6
8
|
when String, Symbol
|
7
|
-
raise ArgumentError unless arg =~ /north|south|east|west|left|right|down/i
|
9
|
+
raise ArgumentError unless arg.to_s =~ /north|south|east|west|left|right|down/i
|
8
10
|
"1-end#{arg}"
|
9
11
|
when Hash
|
10
12
|
pdf_properties = DragonflyPdf::Analysers::PdfProperties.new.call(content)
|
11
|
-
pdf_properties[
|
13
|
+
pdf_properties['page_numbers'].map { |page| [page, arg[page]].compact.join }.join(' ')
|
12
14
|
end
|
13
15
|
|
14
|
-
content.shell_update(ext:
|
16
|
+
content.shell_update(ext: 'pdf') do |old_path, new_path|
|
15
17
|
"#{pdftk_command} #{old_path} cat #{rotate_args} output #{new_path}"
|
16
18
|
end
|
17
19
|
end
|
@@ -2,7 +2,9 @@ module DragonflyPdf
|
|
2
2
|
module Processors
|
3
3
|
class Stamp
|
4
4
|
def call(content, stamp_pdf, _options = {})
|
5
|
-
content.
|
5
|
+
raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
|
6
|
+
|
7
|
+
content.shell_update(ext: 'pdf') do |old_path, new_path|
|
6
8
|
"#{pdftk_command} #{old_path} stamp #{stamp_pdf.path} output #{new_path}"
|
7
9
|
end
|
8
10
|
end
|
@@ -2,7 +2,9 @@ module DragonflyPdf
|
|
2
2
|
module Processors
|
3
3
|
class SubsetFonts
|
4
4
|
def call(content, _opts = {})
|
5
|
-
content.
|
5
|
+
raise UnsupportedFormat unless SUPPORTED_FORMATS.include?(content.ext)
|
6
|
+
|
7
|
+
content.shell_update(ext: 'pdf') do |old_path, new_path|
|
6
8
|
"#{gs_command} -o #{new_path} -f #{old_path}"
|
7
9
|
end
|
8
10
|
end
|
@@ -7,39 +7,10 @@ describe DragonflyPdf::Analysers::PdfProperties do
|
|
7
7
|
let(:sample_pages_with_bleed) { app.fetch_file(SAMPLES_DIR.join('sample_pages_with_bleed.pdf')) }
|
8
8
|
let(:sample_pages_rotated) { app.fetch_file(SAMPLES_DIR.join('sample_pages_rotated.pdf')) }
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
it
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
describe '#page_numbers' do
|
17
|
-
it 'returns one-dimensional array' do
|
18
|
-
analyser.call(sample_pages)[:page_numbers].must_equal (1..10).to_a
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
describe '#page_count' do
|
23
|
-
it 'returns correct page count' do
|
24
|
-
analyser.call(sample_pages)[:page_count].must_equal 10
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
describe '#page_dimensions' do
|
29
|
-
it 'returns array of page dimensions' do
|
30
|
-
analyser.call(sample_pages)[:page_dimensions].map { |p| p.map(&:round) }.must_equal [[210, 297]].cycle.take(10)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
describe '#aspect_ratios' do
|
35
|
-
it 'returns aspect ratios' do
|
36
|
-
analyser.call(sample_pages)[:aspect_ratios].map { |i| i.round(2) }.must_equal [0.71].cycle.take(10)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
describe '#page_rotations' do
|
41
|
-
it 'returns correct page count' do
|
42
|
-
analyser.call(sample_pages_rotated)[:page_rotations].must_equal [0.0, 90.0, 180.0, 270.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
43
|
-
end
|
44
|
-
end
|
10
|
+
it { analyser.call(sample_pages).must_be_kind_of Hash }
|
11
|
+
it { analyser.call(sample_pages)['page_numbers'].must_equal (1..10).to_a }
|
12
|
+
it { analyser.call(sample_pages)['page_count'].must_equal 10 }
|
13
|
+
it { analyser.call(sample_pages)['page_dimensions'].map { |p| p.map(&:round) }.must_equal [[210, 297]].cycle.take(10) }
|
14
|
+
it { analyser.call(sample_pages)['aspect_ratios'].map { |i| i.round(2) }.must_equal [0.71].cycle.take(10) }
|
15
|
+
it { analyser.call(sample_pages_rotated)['page_rotations'].must_equal [0.0, 90.0, 180.0, 270.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] }
|
45
16
|
end
|
@@ -3,70 +3,28 @@ require 'test_helper'
|
|
3
3
|
module DragonflyPdf
|
4
4
|
describe Plugin do
|
5
5
|
let(:app) { test_app.configure_with(:pdf) }
|
6
|
-
let(:
|
7
|
-
|
8
|
-
# ---------------------------------------------------------------------
|
6
|
+
let(:content) { app.fetch_file(SAMPLES_DIR.join('sample_pages.pdf')) }
|
9
7
|
|
10
8
|
describe 'analysers' do
|
11
|
-
it
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
it
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
it 'adds #page_count' do
|
20
|
-
pdf.must_respond_to :page_count
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'adds #page_numbers' do
|
24
|
-
pdf.must_respond_to :page_numbers
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'adds #page_dimensions' do
|
28
|
-
pdf.must_respond_to :page_dimensions
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'adds #aspect_ratios' do
|
32
|
-
pdf.must_respond_to :aspect_ratios
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'adds #page_rotations' do
|
36
|
-
pdf.must_respond_to :page_rotations
|
37
|
-
end
|
9
|
+
it { content.must_respond_to :pdf_properties }
|
10
|
+
it { content.pdf_properties.must_be_kind_of Hash }
|
11
|
+
it { content.must_respond_to :page_count }
|
12
|
+
it { content.must_respond_to :page_numbers }
|
13
|
+
it { content.must_respond_to :page_dimensions }
|
14
|
+
it { content.must_respond_to :aspect_ratios }
|
15
|
+
it { content.must_respond_to :page_rotations }
|
38
16
|
end
|
39
17
|
|
40
|
-
# ---------------------------------------------------------------------
|
41
|
-
|
42
18
|
describe 'processors' do
|
43
|
-
it
|
44
|
-
|
45
|
-
|
46
|
-
it
|
47
|
-
|
48
|
-
|
49
|
-
it
|
50
|
-
|
51
|
-
|
52
|
-
it 'adds #remove_password' do
|
53
|
-
pdf.must_respond_to :remove_password
|
54
|
-
end
|
55
|
-
it 'adds #rotate' do
|
56
|
-
pdf.must_respond_to :rotate
|
57
|
-
end
|
58
|
-
it 'adds #stamp' do
|
59
|
-
pdf.must_respond_to :stamp
|
60
|
-
end
|
61
|
-
it 'adds #subset_fonts' do
|
62
|
-
pdf.must_respond_to :subset_fonts
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
describe '#convert' do
|
67
|
-
it 'adds the correct extension to resulting url' do
|
68
|
-
pdf.convert(1, '600x').url.must_match /\.png/
|
69
|
-
end
|
19
|
+
it { content.must_respond_to :append }
|
20
|
+
it { content.must_respond_to :convert }
|
21
|
+
it { content.must_respond_to :encode }
|
22
|
+
it { content.must_respond_to :page }
|
23
|
+
it { content.must_respond_to :page_thumb }
|
24
|
+
it { content.must_respond_to :remove_password }
|
25
|
+
it { content.must_respond_to :rotate }
|
26
|
+
it { content.must_respond_to :stamp }
|
27
|
+
it { content.must_respond_to :subset_fonts }
|
70
28
|
end
|
71
29
|
end
|
72
30
|
end
|
@@ -3,12 +3,14 @@ require 'test_helper'
|
|
3
3
|
describe DragonflyPdf::Processors::Append do
|
4
4
|
let(:app) { test_app.configure_with(:pdf) }
|
5
5
|
let(:processor) { DragonflyPdf::Processors::Append.new }
|
6
|
-
let(:
|
7
|
-
let(:
|
6
|
+
let(:content_1) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample_pages.pdf')) }
|
7
|
+
let(:content_2) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample_pages_with_bleed.pdf')) }
|
8
8
|
|
9
|
-
before { processor.call(
|
9
|
+
before { processor.call(content_1, [content_2]) }
|
10
10
|
|
11
|
-
it
|
12
|
-
|
11
|
+
it { content_1.analyse(:page_count).must_equal 11 }
|
12
|
+
|
13
|
+
describe 'tempfile has extension' do
|
14
|
+
it { content_1.tempfile.path.must_match /\.pdf\z/ }
|
13
15
|
end
|
14
16
|
end
|
@@ -2,45 +2,24 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
describe DragonflyPdf::Processors::Convert do
|
4
4
|
let(:app) { test_app.configure_with(:pdf) }
|
5
|
-
let(:sample) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample_pages.pdf')) }
|
6
|
-
|
7
5
|
let(:processor) { DragonflyPdf::Processors::Convert.new }
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
it 'updates the file meta format to PNG by default' do
|
20
|
-
sample.meta['format'].must_equal 'png'
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'updates the url extension to PNG by default' do
|
24
|
-
processor.update_url(url_attributes, 1)
|
25
|
-
url_attributes.ext.must_equal 'png'
|
6
|
+
let(:content) { app.fetch_file SAMPLES_DIR.join('sample_pages.pdf') }
|
7
|
+
|
8
|
+
describe 'SUPPORTED_OUTPUT_FORMATS' do
|
9
|
+
DragonflyPdf::SUPPORTED_OUTPUT_FORMATS.each do |format|
|
10
|
+
it(format) do
|
11
|
+
result = content.convert(1, '600x', format: format)
|
12
|
+
result.ext.must_equal format
|
13
|
+
result.mime_type.must_equal Rack::Mime.mime_type(".#{format}")
|
14
|
+
result.size.must_be :>, 0
|
15
|
+
result.tempfile.path.must_match /\.#{format}\z/
|
26
16
|
end
|
27
17
|
end
|
18
|
+
end
|
28
19
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
sample.ext.must_equal 'svg'
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'updates the file meta format to SVG' do
|
37
|
-
sample.meta['format'].must_equal 'svg'
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'updates the url extension to SVG' do
|
41
|
-
processor.update_url(url_attributes, 1, '', format: :svg)
|
42
|
-
url_attributes.ext.must_equal 'svg'
|
43
|
-
end
|
44
|
-
end
|
20
|
+
describe 'url' do
|
21
|
+
let (:url_attributes) { OpenStruct.new }
|
22
|
+
before { processor.update_url(url_attributes, 1) }
|
23
|
+
it { url_attributes.ext.must_equal 'png' }
|
45
24
|
end
|
46
25
|
end
|
@@ -2,18 +2,18 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
describe DragonflyPdf::Processors::Page do
|
4
4
|
let(:app) { test_app.configure_with(:pdf) }
|
5
|
+
let(:content) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample_pages.pdf')) }
|
5
6
|
let(:processor) { DragonflyPdf::Processors::Page.new }
|
6
|
-
let(:sample_pages) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample_pages.pdf')) }
|
7
7
|
|
8
|
-
it
|
9
|
-
|
10
|
-
proc { processor.call(sample_pages, 11) }.must_raise DragonflyPdf::PageNotFound
|
11
|
-
end
|
8
|
+
it { proc { processor.call(content, 0) }.must_raise DragonflyPdf::PageNotFound }
|
9
|
+
it { proc { processor.call(content, 11) }.must_raise DragonflyPdf::PageNotFound }
|
12
10
|
|
13
11
|
describe 'single pages' do
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
before { processor.call(content, 1) }
|
13
|
+
it { content.analyse(:page_count).must_equal 1 }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'tempfile has extension' do
|
17
|
+
it { processor.call(content, 1).tempfile.path.must_match /\.pdf\z/ }
|
18
18
|
end
|
19
19
|
end
|
@@ -2,28 +2,26 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
describe DragonflyPdf::Processors::PageThumb do
|
4
4
|
let(:app) { test_app.configure_with(:pdf) }
|
5
|
-
let(:
|
6
|
-
|
5
|
+
let(:content) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample_pages.pdf')) }
|
7
6
|
let(:processor) { DragonflyPdf::Processors::PageThumb.new }
|
8
7
|
|
9
8
|
describe 'formats' do
|
10
9
|
let (:url_attributes) { OpenStruct.new }
|
11
10
|
|
12
11
|
describe 'default' do
|
13
|
-
before
|
14
|
-
|
15
|
-
it 'converts the PDF to a JPG by default' do
|
16
|
-
sample.ext.must_equal 'jpg'
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'updates the file meta format to JPG by default' do
|
20
|
-
sample.meta['format'].must_equal 'jpg'
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'updates the url extension to JPG by default' do
|
12
|
+
before do
|
13
|
+
processor.call(content, 1, '600x')
|
24
14
|
processor.update_url(url_attributes, 1)
|
25
|
-
url_attributes.ext.must_equal 'jpg'
|
26
15
|
end
|
16
|
+
|
17
|
+
it { content.ext.must_equal 'jpg' }
|
18
|
+
it { content.meta['format'].must_equal 'jpg' }
|
19
|
+
it { url_attributes.ext.must_equal 'jpg' }
|
27
20
|
end
|
28
21
|
end
|
22
|
+
|
23
|
+
describe 'tempfile has extension' do
|
24
|
+
before { processor.call(content, 1, '600x') }
|
25
|
+
it { content.tempfile.path.must_match /\.jpg\z/ }
|
26
|
+
end
|
29
27
|
end
|
@@ -2,11 +2,14 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
describe DragonflyPdf::Processors::RemovePassword do
|
4
4
|
let(:app) { test_app.configure_with(:pdf) }
|
5
|
+
let(:content) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample_pages_with_password.pdf')) }
|
5
6
|
let(:processor) { DragonflyPdf::Processors::RemovePassword.new }
|
6
|
-
let(:sample_pages) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample_pages_with_password.pdf')) }
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
before { processor.call(content, 1) }
|
9
|
+
|
10
|
+
it { `pdftk #{content.path} dump_data`.wont_include 'OWNER PASSWORD REQUIRED' }
|
11
|
+
|
12
|
+
describe 'tempfile has extension' do
|
13
|
+
it { content.tempfile.path.must_match /\.pdf\z/ }
|
11
14
|
end
|
12
15
|
end
|
@@ -2,20 +2,21 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
describe DragonflyPdf::Processors::Rotate do
|
4
4
|
let(:app) { test_app.configure_with(:pdf) }
|
5
|
+
let(:content) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample_pages.pdf')) }
|
5
6
|
let(:processor) { DragonflyPdf::Processors::Rotate.new }
|
6
|
-
let(:sample_1) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample_pages.pdf')) }
|
7
7
|
|
8
|
-
describe '
|
9
|
-
|
10
|
-
|
11
|
-
sample_1.analyse(:page_rotations).must_equal [270, 270, 270, 270, 270, 270, 270, 270, 270, 270]
|
12
|
-
end
|
8
|
+
describe 'String|Symbol' do
|
9
|
+
before { processor.call(content, :left) }
|
10
|
+
it { content.analyse(:page_rotations).must_equal [270, 270, 270, 270, 270, 270, 270, 270, 270, 270] }
|
13
11
|
end
|
14
12
|
|
15
13
|
describe 'arg is Hash' do
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
before { processor.call(content, 1 => :left, 3 => :right) }
|
15
|
+
it { content.analyse(:page_rotations).must_equal [270, 0.0, 90, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'tempfile has extension' do
|
19
|
+
before { processor.call(content, :left) }
|
20
|
+
it { content.tempfile.path.must_match /\.pdf\z/ }
|
20
21
|
end
|
21
22
|
end
|
@@ -3,18 +3,16 @@ require 'test_helper'
|
|
3
3
|
|
4
4
|
describe DragonflyPdf::Processors::Stamp do
|
5
5
|
let(:app) { test_app.configure_with(:pdf) }
|
6
|
+
let(:content) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample_pages.pdf')) }
|
7
|
+
let(:content_stamp) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample_stamp.pdf')) }
|
6
8
|
let(:processor) { DragonflyPdf::Processors::Stamp.new }
|
7
|
-
let(:sample_1) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample_pages.pdf')) }
|
8
|
-
let(:sample_stamp) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample_stamp.pdf')) }
|
9
|
-
let(:text) { PDF::Reader.new(sample_1.path).pages.map(&:text) }
|
10
9
|
|
11
|
-
before { processor.call(
|
10
|
+
before { processor.call(content, content_stamp) }
|
12
11
|
|
13
|
-
it
|
14
|
-
|
15
|
-
end
|
12
|
+
it { content.analyse(:page_count).must_equal 10 }
|
13
|
+
it { PDF::Reader.new(content.path).pages.map(&:text).must_equal %w(STAMP).cycle(10).to_a }
|
16
14
|
|
17
|
-
|
18
|
-
|
15
|
+
describe 'tempfile has extension' do
|
16
|
+
it { content.tempfile.path.must_match /\.pdf\z/ }
|
19
17
|
end
|
20
18
|
end
|
@@ -2,11 +2,16 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
describe DragonflyPdf::Processors::SubsetFonts do
|
4
4
|
let(:app) { test_app.configure_with(:pdf) }
|
5
|
+
let(:content) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample_pages.pdf')) }
|
5
6
|
let(:processor) { DragonflyPdf::Processors::SubsetFonts.new }
|
6
|
-
let(:sample_pages) { Dragonfly::Content.new(app, SAMPLES_DIR.join('sample_pages.pdf')) }
|
7
7
|
|
8
8
|
it 'returns PDF by default' do
|
9
9
|
skip 'not sure how to test this'
|
10
|
-
processor.call(
|
10
|
+
processor.call(content, 1)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'tempfile has extension' do
|
14
|
+
before { processor.call(content, 1) }
|
15
|
+
it { content.tempfile.path.must_match /\.pdf\z/ }
|
11
16
|
end
|
12
17
|
end
|
data/test/test_helper.rb
CHANGED
@@ -2,20 +2,19 @@ require 'bundler/setup'
|
|
2
2
|
|
3
3
|
require 'minitest'
|
4
4
|
require 'minitest/autorun'
|
5
|
+
require 'minitest/reporters'
|
5
6
|
require 'minitest/spec'
|
6
7
|
|
7
8
|
require 'dragonfly'
|
8
9
|
require 'dragonfly_pdf'
|
9
10
|
|
10
|
-
# ---------------------------------------------------------------------
|
11
|
-
|
12
11
|
SAMPLES_DIR = Pathname.new(File.expand_path('../../samples', __FILE__))
|
13
12
|
|
14
|
-
|
13
|
+
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
15
14
|
|
16
15
|
def test_app(name = nil)
|
17
|
-
app = Dragonfly::App.instance(name)
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
app = Dragonfly::App.instance(name).tap do |app|
|
17
|
+
app.datastore = Dragonfly::MemoryDataStore.new
|
18
|
+
app.secret = 'test secret'
|
19
|
+
end
|
21
20
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dragonfly_pdf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomas Celizna
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-07-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dragonfly
|
@@ -30,28 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 2.
|
33
|
+
version: 2.2.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 2.
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: activesupport
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '4.0'
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '4.0'
|
40
|
+
version: 2.2.0
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: bundler
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,6 +94,20 @@ dependencies:
|
|
108
94
|
- - "~>"
|
109
95
|
- !ruby/object:Gem::Version
|
110
96
|
version: '5.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: minitest-reporters
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: rake
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -154,7 +154,6 @@ files:
|
|
154
154
|
- dragonfly_pdf.gemspec
|
155
155
|
- lib/dragonfly_pdf.rb
|
156
156
|
- lib/dragonfly_pdf/analysers/pdf_properties.rb
|
157
|
-
- lib/dragonfly_pdf/errors.rb
|
158
157
|
- lib/dragonfly_pdf/plugin.rb
|
159
158
|
- lib/dragonfly_pdf/processors/append.rb
|
160
159
|
- lib/dragonfly_pdf/processors/convert.rb
|
@@ -201,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
201
200
|
version: '0'
|
202
201
|
requirements: []
|
203
202
|
rubyforge_project:
|
204
|
-
rubygems_version: 2.
|
203
|
+
rubygems_version: 2.7.6
|
205
204
|
signing_key:
|
206
205
|
specification_version: 4
|
207
206
|
summary: Dragonfly PDF analysers and processors.
|
data/lib/dragonfly_pdf/errors.rb
DELETED