poleica 0.9.6

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 (46) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +2 -0
  3. data/.travis.yml +15 -0
  4. data/CHANGELOG.md +16 -0
  5. data/Gemfile +19 -0
  6. data/Gemfile.lock +192 -0
  7. data/Guardfile +19 -0
  8. data/LICENSE +20 -0
  9. data/README.md +82 -0
  10. data/Rakefile +7 -0
  11. data/lib/poleica/converters/coercive.rb +68 -0
  12. data/lib/poleica/converters/convertible.rb +60 -0
  13. data/lib/poleica/converters/general.rb +18 -0
  14. data/lib/poleica/converters/graphics_magick.rb +110 -0
  15. data/lib/poleica/converters/libre_office.rb +103 -0
  16. data/lib/poleica/converters/null.rb +17 -0
  17. data/lib/poleica/converters/utils.rb +49 -0
  18. data/lib/poleica/pathable.rb +20 -0
  19. data/lib/poleica/polei.rb +24 -0
  20. data/lib/poleica/types/archive.rb +12 -0
  21. data/lib/poleica/types/document.rb +53 -0
  22. data/lib/poleica/types/image.rb +37 -0
  23. data/lib/poleica/types/null.rb +12 -0
  24. data/lib/poleica/types/pdf.rb +19 -0
  25. data/lib/poleica/types/typeable.rb +50 -0
  26. data/lib/poleica/version.rb +4 -0
  27. data/lib/poleica.rb +27 -0
  28. data/poleica.gemspec +18 -0
  29. data/test/poleica/converters/coercive_test.rb +77 -0
  30. data/test/poleica/converters/convertible_test.rb +44 -0
  31. data/test/poleica/converters/general_test.rb +11 -0
  32. data/test/poleica/converters/graphics_magick_test.rb +102 -0
  33. data/test/poleica/converters/libre_office_test.rb +55 -0
  34. data/test/poleica/converters/null_test.rb +18 -0
  35. data/test/poleica/converters/utils_test.rb +5 -0
  36. data/test/poleica/pathable_test.rb +11 -0
  37. data/test/poleica/polei_test.rb +15 -0
  38. data/test/poleica/types/typeable_test.rb +57 -0
  39. data/test/poleica_test.rb +10 -0
  40. data/test/support/files/1px.gif +0 -0
  41. data/test/support/files/example.doc +0 -0
  42. data/test/support/files/example.mp3 +0 -0
  43. data/test/support/files/example.pdf +0 -0
  44. data/test/support/files/example.png +0 -0
  45. data/test/test_helper.rb +38 -0
  46. metadata +134 -0
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZDcyMDk2NWVkMzQ3Nzk2ZjBjN2IzN2NmMzg4OWQ3OGI1NjRmZTM4Yw==
5
+ data.tar.gz: !binary |-
6
+ OGQ1ZjcxNTVmYTIyOWJiMTE5NGNkYWQ1YWI0NTU1MzZmMzBjYjE2Yg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ OTZiOWYzODE4YjQ1NmFlODUzYzQxNDZkYWRjODRiYTcwYTlmYTU3MTYyMDRi
10
+ MDEzZDBmNjYzMzcyZWQ1M2FiZjc2YmIyZDFhZThiODA4MzcwZmFiY2JmZWYw
11
+ MWM2ZDhhMGZkZmUyZWQ5NTFhOGI1MTNmYTVhZWNmODJkNzMzMjM=
12
+ data.tar.gz: !binary |-
13
+ MDZiNGQ2MzcxMjhjNGI5MjNlZjA4YzJjMGZhNzdkNjI3OGFkMTViZWM0NTVl
14
+ MjIzZWMxYjVkMDJmM2FmM2JjNjcxMTMzYjY3YjMxYmMxZThlMDZlZDMxZDEx
15
+ YWVmOTI5MDljNjkwNzc1NGNiNWQ2ZjcwN2FkMTFiNmMxN2NhNDA=
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ coverage/
2
+ .bundle/
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ language: ruby
2
+ bundler_args: --without development
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - rbx-19mode
7
+ - jruby-19mode
8
+ before_script:
9
+ - sudo apt-get update -qq
10
+ - sudo apt-get install -qq graphicsmagick libreoffice
11
+ script:
12
+ - rake test
13
+ - rubocop
14
+ notifications:
15
+ email: false
data/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # Poleica 0.9.6 (30 July 2013)
2
+ * Add thumbnail option in GraphicsMagick <3
3
+ # Poleica 0.9.5 (29 July 2013)
4
+ * Implement force_resize option for GraphicsMagick
5
+ # Poleica 0.9.4 (24 July 2013)
6
+ * Add Open Office document handling
7
+ # Poleica 0.9.3 (24 July 2013)
8
+ * Fix Unsupported Pages and Keynote file type
9
+ # Poleica 0.9.2 (23 July 2013)
10
+ * Fix the coercive converter
11
+ # Poleica 0.9.1 (22 July 2013)
12
+ * Escape path options
13
+ # Poleica 0.9.0 (19 July 2013)
14
+ * Convert to pdf and png, handle file path
15
+ # Poleica 0.1.0 (14 June 2013)
16
+ * Just a try, working version for pngs
data/Gemfile ADDED
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ source 'https://rubygems.org'
3
+
4
+ # Specify your gem's dependencies in poleica.gemspec
5
+ gemspec
6
+
7
+ group :test do
8
+ gem 'minitest'
9
+ gem 'rubocop', :github => 'bbatsov/rubocop'
10
+ gem 'coveralls', require: false
11
+ end
12
+
13
+ group :development do
14
+ gem 'jazz_hands'
15
+
16
+ # Guards
17
+ gem 'guard-rubocop'
18
+ gem 'guard-minitest', :github => 'guard/guard-minitest'
19
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,192 @@
1
+ GIT
2
+ remote: git://github.com/bbatsov/rubocop.git
3
+ revision: 2876ed09d2751c9f0cda33733baec031a48289fa
4
+ specs:
5
+ rubocop (0.8.2)
6
+ parser (= 2.0.0.beta6)
7
+ rainbow (>= 1.1.4)
8
+
9
+ GIT
10
+ remote: git://github.com/guard/guard-minitest.git
11
+ revision: f13d0ec2a59cd11d1b400f2db62445c6092ee112
12
+ specs:
13
+ guard-minitest (1.0.0.rc.3)
14
+ guard (>= 1.8)
15
+ minitest (>= 2.1)
16
+
17
+ PATH
18
+ remote: .
19
+ specs:
20
+ poleica (0.9.6)
21
+
22
+ GEM
23
+ remote: https://rubygems.org/
24
+ specs:
25
+ actionpack (3.2.13)
26
+ activemodel (= 3.2.13)
27
+ activesupport (= 3.2.13)
28
+ builder (~> 3.0.0)
29
+ erubis (~> 2.7.0)
30
+ journey (~> 1.0.4)
31
+ rack (~> 1.4.5)
32
+ rack-cache (~> 1.2)
33
+ rack-test (~> 0.6.1)
34
+ sprockets (~> 2.2.1)
35
+ activemodel (3.2.13)
36
+ activesupport (= 3.2.13)
37
+ builder (~> 3.0.0)
38
+ activesupport (3.2.13)
39
+ i18n (= 0.6.1)
40
+ multi_json (~> 1.0)
41
+ ast (1.1.0)
42
+ awesome_print (1.1.0)
43
+ binding_of_caller (0.7.2)
44
+ debug_inspector (>= 0.0.1)
45
+ builder (3.0.4)
46
+ childprocess (0.3.9)
47
+ ffi (~> 1.0, >= 1.0.11)
48
+ coderay (1.0.9)
49
+ colorize (0.5.8)
50
+ columnize (0.3.6)
51
+ coolline (0.4.2)
52
+ coveralls (0.6.7)
53
+ colorize
54
+ multi_json (~> 1.3)
55
+ rest-client
56
+ simplecov (>= 0.7)
57
+ thor
58
+ debug_inspector (0.0.2)
59
+ debugger (1.6.0)
60
+ columnize (>= 0.3.1)
61
+ debugger-linecache (~> 1.2.0)
62
+ debugger-ruby_core_source (~> 1.2.1)
63
+ debugger-linecache (1.2.0)
64
+ debugger-ruby_core_source (1.2.2)
65
+ diff-lcs (1.2.4)
66
+ diffy (2.1.4)
67
+ erubis (2.7.0)
68
+ ffi (1.9.0)
69
+ formatador (0.2.4)
70
+ grit (2.5.0)
71
+ diff-lcs (~> 1.1)
72
+ mime-types (~> 1.15)
73
+ posix-spawn (~> 0.3.6)
74
+ guard (1.8.1)
75
+ formatador (>= 0.2.4)
76
+ listen (>= 1.0.0)
77
+ lumberjack (>= 1.0.2)
78
+ pry (>= 0.9.10)
79
+ thor (>= 0.14.6)
80
+ guard-rubocop (0.0.4)
81
+ childprocess (~> 0.3)
82
+ guard (~> 1.8)
83
+ rubocop (>= 0.8.2, < 0.9.0)
84
+ term-ansicolor (~> 1.1)
85
+ hike (1.2.3)
86
+ hirb (0.7.1)
87
+ i18n (0.6.1)
88
+ jazz_hands (0.5.0)
89
+ awesome_print (~> 1.1.0)
90
+ coderay (~> 1.0.9)
91
+ coolline (>= 0.4.0)
92
+ hirb (~> 0.7.1)
93
+ pry (~> 0.9.12)
94
+ pry-debugger (~> 0.2.2)
95
+ pry-doc (~> 0.4.4)
96
+ pry-git (~> 0.2.3)
97
+ pry-rails (~> 0.2.2)
98
+ pry-remote (>= 0.1.7)
99
+ pry-stack_explorer (~> 0.4.9)
100
+ railties (>= 3.0, < 5.0)
101
+ journey (1.0.4)
102
+ json (1.8.0)
103
+ listen (1.2.2)
104
+ rb-fsevent (>= 0.9.3)
105
+ rb-inotify (>= 0.9)
106
+ rb-kqueue (>= 0.2)
107
+ lumberjack (1.0.3)
108
+ method_source (0.8.1)
109
+ mime-types (1.23)
110
+ minitest (5.0.5)
111
+ multi_json (1.7.7)
112
+ parser (2.0.0.beta6)
113
+ ast (~> 1.1)
114
+ slop (~> 3.4)
115
+ posix-spawn (0.3.6)
116
+ pry (0.9.12.2)
117
+ coderay (~> 1.0.5)
118
+ method_source (~> 0.8)
119
+ slop (~> 3.4)
120
+ pry-debugger (0.2.2)
121
+ debugger (~> 1.3)
122
+ pry (~> 0.9.10)
123
+ pry-doc (0.4.6)
124
+ pry (>= 0.9)
125
+ yard (>= 0.8)
126
+ pry-git (0.2.3)
127
+ diffy
128
+ grit
129
+ pry (>= 0.9.8)
130
+ pry-rails (0.2.2)
131
+ pry (>= 0.9.10)
132
+ pry-remote (0.1.7)
133
+ pry (~> 0.9)
134
+ slop (~> 3.0)
135
+ pry-stack_explorer (0.4.9)
136
+ binding_of_caller (>= 0.7)
137
+ pry (~> 0.9.11)
138
+ rack (1.4.5)
139
+ rack-cache (1.2)
140
+ rack (>= 0.4)
141
+ rack-ssl (1.3.3)
142
+ rack
143
+ rack-test (0.6.2)
144
+ rack (>= 1.0)
145
+ railties (3.2.13)
146
+ actionpack (= 3.2.13)
147
+ activesupport (= 3.2.13)
148
+ rack-ssl (~> 1.3.2)
149
+ rake (>= 0.8.7)
150
+ rdoc (~> 3.4)
151
+ thor (>= 0.14.6, < 2.0)
152
+ rainbow (1.1.4)
153
+ rake (10.1.0)
154
+ rb-fsevent (0.9.3)
155
+ rb-inotify (0.9.0)
156
+ ffi (>= 0.5.0)
157
+ rb-kqueue (0.2.0)
158
+ ffi (>= 0.5.0)
159
+ rdoc (3.12.2)
160
+ json (~> 1.4)
161
+ rest-client (1.6.7)
162
+ mime-types (>= 1.16)
163
+ simplecov (0.7.1)
164
+ multi_json (~> 1.0)
165
+ simplecov-html (~> 0.7.1)
166
+ simplecov-html (0.7.1)
167
+ slop (3.4.5)
168
+ sprockets (2.2.2)
169
+ hike (~> 1.2)
170
+ multi_json (~> 1.0)
171
+ rack (~> 1.0)
172
+ tilt (~> 1.1, != 1.3.0)
173
+ term-ansicolor (1.2.2)
174
+ tins (~> 0.8)
175
+ thor (0.18.1)
176
+ tilt (1.4.1)
177
+ tins (0.8.2)
178
+ yard (0.8.6.1)
179
+
180
+ PLATFORMS
181
+ ruby
182
+
183
+ DEPENDENCIES
184
+ bundler (~> 1.3)
185
+ coveralls
186
+ guard-minitest!
187
+ guard-rubocop
188
+ jazz_hands
189
+ minitest
190
+ poleica!
191
+ rake
192
+ rubocop!
data/Guardfile ADDED
@@ -0,0 +1,19 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'minitest' do
5
+ # with Minitest::Unit
6
+ watch(%r|^test/(.*)\/?(.*)_test\.rb|)
7
+ watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "test/#{m[1]}#{m[2]}_test.rb" }
8
+ watch(%r|^test/test_helper\.rb|) { "test" }
9
+
10
+ # with Minitest::Spec
11
+ # watch(%r|^spec/(.*)_spec\.rb|)
12
+ # watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
13
+ # watch(%r|^spec/spec_helper\.rb|) { "spec" }
14
+ end
15
+
16
+ guard 'rubocop' do
17
+ watch(%r{.+\.rb$})
18
+ watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
19
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Antoine Lyset
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ 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, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,82 @@
1
+ # Poleica
2
+ ## Poleica = Polaroid + Leica (Real Hipster)
3
+
4
+ [![Build Status](https://travis-ci.org/antoinelyset/Poleica.png?branch=master)](https://travis-ci.org/antoinelyset/Poleica)
5
+ [![Coverage Status](https://coveralls.io/repos/antoinelyset/Poleica/badge.png)](https://coveralls.io/r/antoinelyset/Poleica)
6
+ [![Code Climate](https://codeclimate.com/github/antoinelyset/Poleica.png)](https://codeclimate.com/github/antoinelyset/Poleica)
7
+ [![Dependency Status](https://gemnasium.com/antoinelyset/Poleica.png)](https://gemnasium.com/antoinelyset/Poleica)
8
+
9
+ ## Install
10
+
11
+ __Ubuntu__ :
12
+
13
+ ```
14
+ apt-get install graphicsmagick libreoffice
15
+ ```
16
+
17
+ __MacOS__ :
18
+
19
+ ```
20
+ brew install graphicsmagick
21
+ ```
22
+
23
+ Then download [LibreOffice](http://www.libreoffice.org/download) and install it.
24
+ ## Concept
25
+
26
+ _ -> PDF -> Image
27
+
28
+ Image -> Image
29
+
30
+ ## Usage
31
+
32
+ ```
33
+ Poleica.new(file_path).to_png
34
+ Poleica.new(file_path).to_png(width: 400, weight: 400)
35
+ ```
36
+
37
+ ## Options
38
+
39
+ - weight: pixel
40
+ - width: pixel
41
+ - path: folder or file
42
+ - force_resize: boolean (it doesnt preserve the image ratio)
43
+ - thumbnail : boolean (it crops the image the given weight and width,
44
+ preserving the image ratio)
45
+
46
+ ## Dependencies
47
+
48
+ - GraphicsMagick (gm)
49
+ - LibreOffice
50
+
51
+ ## Requirements
52
+
53
+ - It should be easy
54
+ - It should work on MacOS & Linux
55
+ - It should handle standard files
56
+ - It should convert to PNG or PDF
57
+
58
+ ## Standard files
59
+
60
+ - Documents: PDF, PPT, DOC, TXT..
61
+ - Images: PNG, JPEG, GIF...
62
+
63
+ ## Conventions
64
+
65
+ - I wrote mimetype not mime_type
66
+
67
+ ## Warning
68
+
69
+ - Exit LibreOffice App before tests and launch
70
+
71
+ ## Thanks
72
+
73
+ - A lot of inspiration from a lot of gems :
74
+ - Docsplit
75
+ - Paperclip
76
+ - ROM
77
+ - ...
78
+
79
+ ## License
80
+
81
+ Poleica is released under the [MIT
82
+ License](http://www.opensource.org/licenses/MIT)
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs.push ['lib', 'test']
5
+ t.test_files = FileList['test/**/*_test.rb']
6
+ t.verbose = true
7
+ end
@@ -0,0 +1,68 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module Poleica
3
+ module Converters
4
+ # The Coercive converter, it tries to coerce the polei
5
+ class Coercive
6
+ include Poleica::Converters::Utils
7
+
8
+ # TODO Think about another way of declare return types
9
+ TYPE_RETURNED_BY_METHOD = {
10
+ to_pdf: Types::PDF,
11
+ to_png: Types::Image
12
+ }
13
+
14
+ attr_reader :polei
15
+
16
+ def initialize(polei)
17
+ @polei = polei
18
+ end
19
+
20
+ private
21
+
22
+ def method_missing(method, *args, &block)
23
+ extension, options = Utils.extract_extension_and_options(method, args)
24
+ return try_convert(method, options) if extension
25
+ super
26
+ end
27
+
28
+ def try_convert(method, options = {})
29
+ coerced_path = coerce(method, options)
30
+ return nil unless coerced_path
31
+ converted_path = Poleica.new(coerced_path).send(method.to_sym, options)
32
+ File.delete(coerced_path)
33
+ converted_path
34
+ end
35
+
36
+ def coerce(method, options)
37
+ conversion_hash = find_next_converter_by_method(method)
38
+ return nil unless conversion_hash
39
+ next_method = conversion_hash.keys.first
40
+ polei.send(next_method.to_sym, options)
41
+ end
42
+
43
+ # Find the next method and converter needed to execute
44
+ # a given conversion
45
+ # @param <Symbol/String> the given method conversion name
46
+ # @return [Hash<Symbol, Converter>] the next method needed to execute
47
+ def find_next_converter_by_method(origin_method)
48
+ next_converters_by_method.find do |converter_by_method|
49
+ conv = converter_by_method.values.first
50
+ conv.method_defined?(origin_method.to_sym)
51
+ end
52
+ end
53
+
54
+ # Returns a hash with the method to execute and the Converters
55
+ # reachable by it
56
+ # @return [Array[Hash<Symbol,Converters>]]
57
+ def next_converters_by_method
58
+ polei.compatible_convert_methods.map do |m|
59
+ ret_type = TYPE_RETURNED_BY_METHOD[m.to_sym]
60
+ next unless ret_type
61
+ convs = Poleica::Convertible.
62
+ compatible_converters_by_type(ret_type)
63
+ convs.map { |conv| { m.to_sym => conv } }
64
+ end.compact.flatten(1)
65
+ end
66
+ end # class Coercive
67
+ end # module Converters
68
+ end # module Poleica
@@ -0,0 +1,60 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module Poleica
3
+ # Conversion Logic, given a type it can search for compatible converters
4
+ module Convertible
5
+
6
+ CONVERTERS = [
7
+ Converters::GraphicsMagick,
8
+ Converters::LibreOffice
9
+ ]
10
+
11
+ def method_missing(method, *args, &block)
12
+ extension, options = Converters::Utils
13
+ .extract_extension_and_options(method, args)
14
+ return convert_to_extension(extension, options) if extension
15
+ super
16
+ end
17
+
18
+ def convert_to_extension(extension, options = {})
19
+ converter = converter_to_extension(extension).new(self)
20
+ converter.send("to_#{extension}".to_sym, options)
21
+ end
22
+
23
+ def converter_to_extension(extension, filter = :mimetype)
24
+ compatible_converter = compatible_converters.find do |converter|
25
+ converter.method_defined?(:"to_#{extension}")
26
+ end
27
+ compatible_converter ||= Converters::Coercive
28
+ end
29
+
30
+ def compatible_converters
31
+ @compatible_converters ||=
32
+ compatible_converters_by_type(self.file_type.class) <<
33
+ Converters::General
34
+ end
35
+
36
+ def compatible_convert_methods
37
+ @compatible_convert_methods ||=
38
+ compatible_converters.map do |c|
39
+ convert_methods_for_converter(c)
40
+ end.flatten
41
+ end
42
+
43
+ module_function
44
+
45
+ def compatible_converters_by_type(type)
46
+ CONVERTERS.select do |converter|
47
+ converter::COMPATIBLE_TYPES.include?(type)
48
+ end
49
+ end
50
+
51
+ def convert_methods_for_converter(converter)
52
+ methods_for_converter(converter).reject { |m| !(m =~ /^to_(.*)/) }
53
+ end
54
+
55
+ def methods_for_converter(converter)
56
+ converter.instance_methods(false).map(&:to_s)
57
+ end
58
+
59
+ end # module Convertible
60
+ end # module Poleica
@@ -0,0 +1,18 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module Poleica
3
+ module Converters
4
+ # The General converter, it handles any file type.
5
+ class General
6
+
7
+ attr_reader :polei
8
+
9
+ def initialize(polei)
10
+ @polei = polei
11
+ end
12
+
13
+ def to_bin(options = {})
14
+ File.binread(polei.path)
15
+ end
16
+ end # class General
17
+ end # module Converters
18
+ end # module Poleica
@@ -0,0 +1,110 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module Poleica
3
+ module Converters
4
+ # The GraphicsMagick converter, use the 'gm' command to convert images and
5
+ # documents
6
+ class GraphicsMagick
7
+ include Poleica::Converters::Utils
8
+
9
+ BIN_PATHS = {
10
+ linux: '/usr/bin/gm',
11
+ osx: '/usr/local/bin/gm'
12
+ }
13
+
14
+ COMPATIBLE_TYPES = [
15
+ Types::Image,
16
+ Types::PDF
17
+ ]
18
+
19
+ DEFAULT_MEASURE = 612
20
+
21
+ attr_reader :polei
22
+
23
+ def initialize(polei)
24
+ @polei = polei
25
+ end
26
+
27
+ def to_png(options = {})
28
+ opts_gen = OptionsGenerator.new(polei, options)
29
+ cmd = "#{bin_path} convert "
30
+ cmd << "#{Utils.escape(polei.path)}#{opts_gen.generate} "
31
+ `#{cmd}`
32
+ expected_file_path = opts_gen[:path]
33
+ File.exists?(expected_file_path) ? expected_file_path : nil
34
+ end
35
+
36
+ private
37
+
38
+ # Generate options for the gm command
39
+ # @options page [Array, Integer]
40
+ class OptionsGenerator
41
+ attr_reader :polei, :options
42
+
43
+ def initialize(polei, options = {})
44
+ @polei = polei
45
+ @options = default_options.merge(options)
46
+ end
47
+
48
+ def generate
49
+ "#{page_options} #{thumbnail_or_resize_options}" +
50
+ " #{Utils.escape(output_options)}"
51
+ end
52
+
53
+ def [](key)
54
+ options[key]
55
+ end
56
+
57
+ private
58
+
59
+ def default_options
60
+ {
61
+ height: DEFAULT_MEASURE,
62
+ width: DEFAULT_MEASURE,
63
+ force_resize: false,
64
+ thumbnail: false,
65
+ page: 0,
66
+ }
67
+ end
68
+
69
+ def page_options
70
+ @page_options ||=
71
+ "#{Array(options[:page]).flatten.compact.uniq.sort.to_s}"
72
+ end
73
+
74
+ def thumbnail_or_resize_options
75
+ @thumbnail_or_resize_options ||=
76
+ options[:thumbnail] ? thumbnail_options : resize_options
77
+ end
78
+
79
+ def thumbnail_options
80
+ @thumbnail_options ||=
81
+ "-thumbnail #{options[:width]}x" +
82
+ "#{options[:height]}^" +
83
+ ' -gravity center' +
84
+ " -extent #{options[:width]}x" +
85
+ "#{options[:height]}"
86
+ end
87
+
88
+ def resize_options
89
+ @resize_options ||=
90
+ "-resize #{options[:width]}x" +
91
+ "#{options[:height]}" +
92
+ "#{'!' if options[:force_resize]}"
93
+ end
94
+
95
+ def output_options
96
+ options[:path] = if options[:path]
97
+ if File.directory?(options[:path])
98
+ basename = File.basename(polei.path_with_md5)
99
+ File.join(options[:path], basename)
100
+ else
101
+ options[:path]
102
+ end
103
+ else
104
+ polei.path_with_md5(:png)
105
+ end
106
+ end
107
+ end # class OptionsGenerator
108
+ end # class GraphicsMagick
109
+ end # module Converters
110
+ end # module Poleica