crabgrass_media 0.1.1 → 0.2.0
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.
- checksums.yaml +4 -4
- data/README.md +2 -9
- data/lib/media.rb +4 -6
- data/lib/media/mime_type.rb +7 -22
- data/lib/media/transmogrifier.rb +28 -28
- data/lib/media/transmogrifiers/graphicsmagick.rb +29 -32
- data/lib/media/transmogrifiers/inkscape.rb +5 -20
- data/lib/media/transmogrifiers/libremagick.rb +17 -8
- data/lib/media/transmogrifiers/libreoffice.rb +4 -63
- data/lib/media/version.rb +1 -1
- data/test/files/kaos.pdf +0 -0
- data/test/graphicsmagick_transmogrifier_test.rb +40 -0
- data/test/libremagick_transmogrifier_test.rb +25 -0
- data/test/media_test.rb +14 -0
- data/test/sleepy_transmogrifier.rb +2 -2
- data/test/transmogrifier_test.rb +8 -2
- metadata +52 -19
- data/lib/media/version.rb.orig +0 -7
- data/test/tempfile_test.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3292a6224e3e8970bc305a69a1c734bf6e56901
|
4
|
+
data.tar.gz: 7c6ce2640a3a283f069e736ab01dc2bf7e9207b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9bbffb27cb8f8fd0eb5c440ca2a9e522d70249aca48f1d92cfd83c3240260a7b58e68c07a93a3275187a113561932efc9f2a5c26931d8b982bfc08ac91e9cdd7
|
7
|
+
data.tar.gz: 2b6a46d543d853031c6cc6662aed2c722cf9019a43639e379242632d6d9c7117de3252434a2174eaaf3392b4c067237a99bb5d13949f7c9031f7097d95167848
|
data/README.md
CHANGED
@@ -15,15 +15,8 @@ Example usage:
|
|
15
15
|
end
|
16
16
|
```
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
Strongly suggested:
|
22
|
-
|
23
|
-
```sh
|
24
|
-
gem install mime-types
|
25
|
-
```
|
18
|
+
Tests require the 'file' utility to be installed to determine the file
|
19
|
+
type of the created files.
|
26
20
|
|
27
21
|
Crabgrass and Crabgrass::Media are based on Ruby on Rails and MySQL.
|
28
22
|
They are released under the AGPL license, version 3.
|
29
|
-
|
data/lib/media.rb
CHANGED
@@ -49,15 +49,13 @@ module Media
|
|
49
49
|
#
|
50
50
|
|
51
51
|
def self.has_dimensions?(mime_type)
|
52
|
-
|
53
|
-
|
54
|
-
end
|
52
|
+
Media::GraphicsMagickTransmogrifier.available? &&
|
53
|
+
Media::GraphicsMagickTransmogrifier.converts_from?(mime_type)
|
55
54
|
end
|
56
55
|
|
57
56
|
def self.dimensions(filepath)
|
58
|
-
|
59
|
-
|
60
|
-
end
|
57
|
+
return unless Media::GraphicsMagickTransmogrifier.available?
|
58
|
+
Media::GraphicsMagickTransmogrifier.dimensions filepath
|
61
59
|
end
|
62
60
|
|
63
61
|
end
|
data/lib/media/mime_type.rb
CHANGED
@@ -1,10 +1,4 @@
|
|
1
|
-
|
2
|
-
require 'mime/types'
|
3
|
-
rescue LoadError => exc
|
4
|
-
puts "WARNING! no mime-types gem installed"
|
5
|
-
puts "you should really do 'gem install mime-types'"
|
6
|
-
end
|
7
|
-
|
1
|
+
require 'mime/types'
|
8
2
|
|
9
3
|
module Media
|
10
4
|
module MimeType
|
@@ -121,22 +115,22 @@ module Media
|
|
121
115
|
'application/excel-template' => [:xlt,:msexcel,'asset/spreadsheet','MS Excel Template'],
|
122
116
|
'application/powerpoint-template' => [:pot,:mspowerpoint,'asset/doc','MS Powerpoint Template'],
|
123
117
|
|
124
|
-
'application/vnd.openxmlformats-officedocument.presentationml.presentation' =>
|
125
|
-
|
118
|
+
# 'application/vnd.openxmlformats-officedocument.presentationml.presentation' =>
|
119
|
+
# [:pptx, :mspowerpoint,'asset/doc','MS Powerpoint'],
|
126
120
|
'application/vnd.openxmlformats-officedocument.presentationml.presentation' =>
|
127
121
|
[:pptm, :mspowerpoint,'asset/doc','MS Powerpoint'],
|
128
122
|
'application/vnd.openxmlformats-officedocument.presentationml.template' =>
|
129
123
|
[:potx,:mspowerpoint,'asset/doc','MS Powerpoint Template'],
|
130
124
|
|
131
|
-
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' =>
|
132
|
-
|
125
|
+
# 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' =>
|
126
|
+
# [:docm,:msword,'asset/text','MS Word'],
|
133
127
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' =>
|
134
128
|
[:docx,:msword,'asset/text','MS Word'],
|
135
129
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.template' =>
|
136
130
|
[:dotx,:msword,'asset/text','MS Word Template'],
|
137
131
|
|
138
|
-
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' =>
|
139
|
-
|
132
|
+
# 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' =>
|
133
|
+
# [:xlsm,:msexcel,'asset/spreadsheet','MS Excel'],
|
140
134
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' =>
|
141
135
|
[:xlsx,:msexcel,'asset/spreadsheet','MS Excel'],
|
142
136
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.template' =>
|
@@ -250,15 +244,6 @@ module Media
|
|
250
244
|
'svg' => 'image/svg+xml',
|
251
245
|
'mod' => 'video/mpeg',
|
252
246
|
|
253
|
-
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
254
|
-
'pptm' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
255
|
-
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
|
256
|
-
'docm' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
257
|
-
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
258
|
-
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
|
259
|
-
'xlsm' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
260
|
-
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
261
|
-
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template'
|
262
247
|
}.freeze
|
263
248
|
|
264
249
|
#
|
data/lib/media/transmogrifier.rb
CHANGED
@@ -18,12 +18,13 @@ module Media
|
|
18
18
|
end
|
19
19
|
|
20
20
|
mattr_accessor :verbose, instance_writer: false
|
21
|
-
mattr_accessor :suppress_errors, instance_writer: false
|
22
21
|
|
23
|
-
|
22
|
+
class << self
|
23
|
+
delegate :debug, :info, :warning, :error, to: :logger
|
24
|
+
end
|
24
25
|
|
26
|
+
delegate :debug, :info, :warning, :error, to: :logger
|
25
27
|
|
26
|
-
attr_accessor :name
|
27
28
|
|
28
29
|
attr_accessor :input
|
29
30
|
attr_accessor :input_file
|
@@ -38,17 +39,12 @@ module Media
|
|
38
39
|
attr_accessor :command_output # output of last command run
|
39
40
|
|
40
41
|
#
|
41
|
-
# takes a
|
42
|
+
# takes a hash of options, some of which are required:
|
42
43
|
#
|
43
44
|
# - :input_file or (:input and :input_type)
|
44
45
|
# - :output_file or :output_type
|
45
46
|
#
|
46
47
|
def initialize(options=nil)
|
47
|
-
self.name = self.class.to_s
|
48
|
-
# we keep an instance in the transmogrifier list.
|
49
|
-
# They only need to have the name set.
|
50
|
-
return if options.nil?
|
51
|
-
|
52
48
|
options = options.dup
|
53
49
|
self.input = options.delete(:input)
|
54
50
|
self.input_file = options.delete(:input_file)
|
@@ -88,7 +84,7 @@ module Media
|
|
88
84
|
end
|
89
85
|
|
90
86
|
def self.inherited(base)
|
91
|
-
add
|
87
|
+
add base
|
92
88
|
end
|
93
89
|
|
94
90
|
##
|
@@ -119,17 +115,17 @@ module Media
|
|
119
115
|
select{|tm| tm.converts_to?(output_type)}.
|
120
116
|
select{|tm| tm.available?}.
|
121
117
|
first
|
122
|
-
return transmog
|
118
|
+
return transmog if transmog
|
123
119
|
logger.error 'could not find a transmogrifier for "%s" -> "%s"' %
|
124
120
|
[input_type, output_type]
|
125
121
|
return nil
|
126
122
|
end
|
127
123
|
|
128
|
-
def converts_from?(input_type)
|
124
|
+
def self.converts_from?(input_type)
|
129
125
|
input_types.include? input_type
|
130
126
|
end
|
131
127
|
|
132
|
-
def converts_to?(output_type)
|
128
|
+
def self.converts_to?(output_type)
|
133
129
|
output_types.include? output_type
|
134
130
|
end
|
135
131
|
|
@@ -147,21 +143,23 @@ module Media
|
|
147
143
|
# runs a shell command, passing each line that is output, as it is output
|
148
144
|
# to the block.
|
149
145
|
#
|
150
|
-
# returns
|
151
|
-
#
|
146
|
+
# returns
|
147
|
+
# * the status of the command, as one of the following symbols:
|
148
|
+
# :success, :failure, :not_found, :error
|
149
|
+
# * the output to STDOUT and STDERR of the command
|
152
150
|
#
|
153
|
-
def run_command(*args)
|
151
|
+
def self.run_command(*args)
|
154
152
|
|
155
153
|
# run the command
|
156
154
|
cmdstr = command_string(*args)
|
157
|
-
|
155
|
+
output = ""
|
158
156
|
before = Time.now
|
159
157
|
IO.popen(cmdstr + ' 2>&1', 'r') do |pipe|
|
160
158
|
while line = pipe.gets
|
161
159
|
if block_given?
|
162
160
|
yield(line)
|
163
161
|
end
|
164
|
-
|
162
|
+
output << line << "\n"
|
165
163
|
end
|
166
164
|
end
|
167
165
|
took = Time.now - before
|
@@ -176,15 +174,21 @@ module Media
|
|
176
174
|
if status == :success
|
177
175
|
log_command cmdstr
|
178
176
|
debug "took #{took} seconds."
|
179
|
-
debug
|
177
|
+
debug output
|
180
178
|
else
|
181
179
|
msg = ' exited with "%s"' % $?.exitstatus
|
182
180
|
error cmdstr
|
183
181
|
error msg
|
184
|
-
error
|
182
|
+
error output if !output.empty?
|
185
183
|
yield(msg) if block_given?
|
186
184
|
end
|
187
185
|
|
186
|
+
return status, output
|
187
|
+
end
|
188
|
+
|
189
|
+
def run_command(*args)
|
190
|
+
status, self.command_output = self.class.run_command(*args)
|
191
|
+
|
188
192
|
# restore the original output_file name
|
189
193
|
unless restore_temporary_outfile
|
190
194
|
msg = 'could not restore temporary outfile'
|
@@ -195,11 +199,7 @@ module Media
|
|
195
199
|
return status
|
196
200
|
end
|
197
201
|
|
198
|
-
|
199
|
-
# command.present? and File.file?(command) and File.executable?(command)
|
200
|
-
#end
|
201
|
-
|
202
|
-
def command_available?(command)
|
202
|
+
def self.command_available?(command)
|
203
203
|
command and
|
204
204
|
File.file?(command) and
|
205
205
|
File.executable?(command)
|
@@ -211,7 +211,7 @@ module Media
|
|
211
211
|
|
212
212
|
protected
|
213
213
|
|
214
|
-
def log_command(command)
|
214
|
+
def self.log_command(command)
|
215
215
|
debug "COMMAND " + command
|
216
216
|
end
|
217
217
|
|
@@ -262,11 +262,11 @@ module Media
|
|
262
262
|
|
263
263
|
private
|
264
264
|
|
265
|
-
def command_string(*args)
|
265
|
+
def self.command_string(*args)
|
266
266
|
args.collect {|arg| shell_escape(arg.to_s)}.join(' ')
|
267
267
|
end
|
268
268
|
|
269
|
-
def shell_escape(str)
|
269
|
+
def self.shell_escape(str)
|
270
270
|
if str.empty?
|
271
271
|
"''"
|
272
272
|
elsif str =~ %r{\A[0-9A-Za-z+_-]+\z}
|
@@ -18,22 +18,19 @@ module Media
|
|
18
18
|
|
19
19
|
class GraphicsMagickTransmogrifier < Media::Transmogrifier
|
20
20
|
|
21
|
-
def input_types
|
22
|
-
%w(
|
23
|
-
application/postscript application/xpdf image/jpeg image/pjpeg image/gif
|
21
|
+
def self.input_types
|
22
|
+
%w( image/jpeg image/pjpeg image/gif
|
24
23
|
image/png image/x-png image/jpg image/tiff )
|
24
|
+
# application/pdf application/bzpdf application/gzpdf
|
25
|
+
# application/postscript application/xpdf
|
25
26
|
end
|
26
27
|
|
27
|
-
|
28
|
-
# self.class.input_types
|
29
|
-
#end
|
30
|
-
|
31
|
-
def output_types
|
28
|
+
def self.output_types
|
32
29
|
%w( application/pdf image/jpeg image/pjpeg
|
33
30
|
image/gif image/png image/jpg image/tiff )
|
34
31
|
end
|
35
32
|
|
36
|
-
def available?
|
33
|
+
def self.available?
|
37
34
|
command_available?(GRAPHICSMAGICK_COMMAND)
|
38
35
|
end
|
39
36
|
|
@@ -43,6 +40,12 @@ module Media
|
|
43
40
|
# on the pipe, since the progress is updated on a single line.
|
44
41
|
#
|
45
42
|
def run(&block)
|
43
|
+
if !File.exist?(input_file.to_s) ||
|
44
|
+
( File.size(input_file.to_s) == 0 )
|
45
|
+
debug "Could not find input file: #{input_file}"
|
46
|
+
return :not_fould
|
47
|
+
end
|
48
|
+
|
46
49
|
# try converting first page only
|
47
50
|
status = convert(input_file.to_s + '[0]', &block)
|
48
51
|
# retry with full file if result was empty
|
@@ -58,7 +61,7 @@ module Media
|
|
58
61
|
def convert(input = input_file.to_s, &block)
|
59
62
|
# +profile '*' will remove all the image profiles, which will save
|
60
63
|
# space (sometimes) and are not useful for thumbnails
|
61
|
-
arguments = [gm_command, 'convert', '+profile', "*"]
|
64
|
+
arguments = [self.class.gm_command, 'convert', '+profile', "*"]
|
62
65
|
if options[:size]
|
63
66
|
# handle multiple size options, if it is an array.
|
64
67
|
sizes = options[:size].is_a?(Array) ? options[:size] : [options[:size]]
|
@@ -83,40 +86,23 @@ module Media
|
|
83
86
|
|
84
87
|
# try to detect the dimensions of the first page.
|
85
88
|
# fallback to detecting dimensions of all pages.
|
86
|
-
def dimensions(filename)
|
89
|
+
def self.dimensions(filename)
|
90
|
+
return unless available?
|
87
91
|
run_dimensions(filename.to_s + '[0]') ||
|
88
92
|
run_dimensions(filename.to_s)
|
89
93
|
end
|
90
94
|
|
91
|
-
def run_dimensions(filename)
|
92
|
-
if available?
|
93
|
-
args = [gm_command, 'identify', '-format', '%m %w %h', filename]
|
94
|
-
dimensions = nil
|
95
|
-
status = run_command(*args) do |output|
|
96
|
-
dimensions = output
|
97
|
-
end
|
98
|
-
if status == :success
|
99
|
-
type, width, height = dimensions.split /\s/
|
100
|
-
return [width,height]
|
101
|
-
else
|
102
|
-
return nil
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
95
|
#
|
108
96
|
# returns the average color of an image, as represented by an array of red, green, blue values, integers
|
109
97
|
# in the range 0..255
|
110
98
|
#
|
111
99
|
# note: it is important that the geometry is "1x1!" ... without the ! this function might die a fiery death.
|
112
100
|
#
|
113
|
-
def average_color(filename)
|
101
|
+
def self.average_color(filename)
|
114
102
|
if available?
|
115
103
|
args = [gm_command, 'convert', '-resize', '1x1!', filename, 'text:-']
|
116
104
|
color = nil
|
117
|
-
status = run_command(*args)
|
118
|
-
color = output
|
119
|
-
end
|
105
|
+
status, color = run_command(*args)
|
120
106
|
if status == :success
|
121
107
|
match = color.match(/^0,0: \(\s*(?<red>\d+),\s*(?<green>\d+),\s*(?<blue>\d+)\)/)
|
122
108
|
if match
|
@@ -128,8 +114,19 @@ module Media
|
|
128
114
|
return [256,256,256]
|
129
115
|
end
|
130
116
|
|
117
|
+
protected
|
118
|
+
|
119
|
+
def self.run_dimensions(filename)
|
120
|
+
args = [gm_command, 'identify', '-format', '%m %w %h', filename]
|
121
|
+
status, dimensions = run_command(*args)
|
122
|
+
if status == :success
|
123
|
+
_type, width, height = dimensions.split(/\s/)
|
124
|
+
return [width,height]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
131
128
|
# this override is just used for test, at the moment.
|
132
|
-
def gm_command
|
129
|
+
def self.gm_command
|
133
130
|
GRAPHICSMAGICK_COMMAND
|
134
131
|
end
|
135
132
|
|
@@ -5,19 +5,19 @@ module Media
|
|
5
5
|
|
6
6
|
class InkscapeTransmogrifier < Media::Transmogrifier
|
7
7
|
|
8
|
-
def magick
|
8
|
+
def self.magick
|
9
9
|
Media::Transmogrifier.list["Media::GraphicsMagickTransmogrifier"]
|
10
10
|
end
|
11
11
|
|
12
|
-
def output_types
|
12
|
+
def self.output_types
|
13
13
|
magick.output_types
|
14
14
|
end
|
15
15
|
|
16
|
-
def input_types
|
16
|
+
def self.input_types
|
17
17
|
%w(image/svg+xml image/svg+xml-compressed application/illustrator image/bzeps image/eps image/gzeps)
|
18
18
|
end
|
19
19
|
|
20
|
-
def available?
|
20
|
+
def self.available?
|
21
21
|
command_available?(INKSCAPE_COMMAND) and magick and magick.available?
|
22
22
|
end
|
23
23
|
|
@@ -30,7 +30,7 @@ module Media
|
|
30
30
|
arguments = [INKSCAPE_COMMAND, '--without-gui', '--export-area-drawing', '--export-area-snap', input_file, '--export-png', png_output_file]
|
31
31
|
status = run_command(*arguments, &block)
|
32
32
|
return status if status != :success
|
33
|
-
magick_transmog =
|
33
|
+
magick_transmog = self.class.magick.new(
|
34
34
|
options.merge({
|
35
35
|
input_file: png_output_file, input_type: "image/png",
|
36
36
|
output_file: output_file, output_type: output_type
|
@@ -39,20 +39,5 @@ module Media
|
|
39
39
|
magick_transmog.run(&block)
|
40
40
|
end
|
41
41
|
end
|
42
|
-
|
43
|
-
#=begin
|
44
|
-
# def dimensions(filename)
|
45
|
-
# if INKSCAPE_COMMAND.present?
|
46
|
-
# args = [INKSCAPE_COMMAND, '--query-height', filename]
|
47
|
-
# success_h, height = cmd(*args)
|
48
|
-
# args = [INKSCAPE_COMMAND, '--query-width', filename]
|
49
|
-
# success_w, width = cmd(*args)
|
50
|
-
# if success_h and success_w
|
51
|
-
# return [width,height]
|
52
|
-
# end
|
53
|
-
# end
|
54
|
-
# end
|
55
|
-
#=end
|
56
|
-
|
57
42
|
end
|
58
43
|
end
|
@@ -6,25 +6,34 @@ module Media
|
|
6
6
|
|
7
7
|
class LibreMagickTransmogrifier < Media::Transmogrifier
|
8
8
|
|
9
|
-
def libre
|
9
|
+
def self.libre
|
10
10
|
Media::Transmogrifier.list["Media::LibreOfficeTransmogrifier"]
|
11
11
|
end
|
12
12
|
|
13
|
-
def magick
|
13
|
+
def self.magick
|
14
14
|
Media::Transmogrifier.list["Media::GraphicsMagickTransmogrifier"]
|
15
15
|
end
|
16
16
|
|
17
|
-
def input_types
|
17
|
+
def self.input_types
|
18
18
|
libre.input_types
|
19
19
|
end
|
20
20
|
|
21
|
-
def output_types
|
21
|
+
def self.output_types
|
22
22
|
# we don't want to use this for pdf, since libreoffice by itself can generate pdf
|
23
23
|
magick.output_types - ['application/pdf']
|
24
24
|
end
|
25
25
|
|
26
|
-
def available?
|
27
|
-
libre
|
26
|
+
def self.available?
|
27
|
+
libre &&
|
28
|
+
magick &&
|
29
|
+
libre.available? &&
|
30
|
+
magick.available? &&
|
31
|
+
ghostscript_available?
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.ghostscript_available?
|
35
|
+
cmd = `which ghostscript`.chomp
|
36
|
+
!cmd.empty? && command_available?(cmd)
|
28
37
|
end
|
29
38
|
|
30
39
|
#
|
@@ -35,12 +44,12 @@ module Media
|
|
35
44
|
#
|
36
45
|
def run(&block)
|
37
46
|
pdf_output_file = Media::TempFile.new(nil, "application/pdf")
|
38
|
-
libre_transmog =
|
47
|
+
libre_transmog = self.class.libre.new(
|
39
48
|
input_file: input_file, input_type: input_type,
|
40
49
|
output_file: pdf_output_file, output_type: "application/pdf")
|
41
50
|
status = libre_transmog.run(&block)
|
42
51
|
return status if status != :success
|
43
|
-
magick_transmog =
|
52
|
+
magick_transmog = self.class.magick.new(
|
44
53
|
options.merge({
|
45
54
|
input_file: pdf_output_file, input_type: "application/pdf",
|
46
55
|
output_file: output_file, output_type: output_type
|
@@ -21,7 +21,7 @@ module Media
|
|
21
21
|
|
22
22
|
class LibreOfficeTransmogrifier < Media::Transmogrifier
|
23
23
|
|
24
|
-
def input_types
|
24
|
+
def self.input_types
|
25
25
|
%w(
|
26
26
|
text/plain text/html text/richtext application/rtf
|
27
27
|
text/csv text/comma-separated-values
|
@@ -48,11 +48,11 @@ module Media
|
|
48
48
|
)
|
49
49
|
end
|
50
50
|
|
51
|
-
def output_types
|
51
|
+
def self.output_types
|
52
52
|
["application/pdf"] + input_types
|
53
53
|
end
|
54
54
|
|
55
|
-
def available?
|
55
|
+
def self.available?
|
56
56
|
command_available?(LIBREOFFICE_COMMAND)
|
57
57
|
end
|
58
58
|
|
@@ -75,7 +75,7 @@ module Media
|
|
75
75
|
msg = ["Error: Could not find libreoffice output %s \n" % output_file]
|
76
76
|
msg << arguments.join(' ')
|
77
77
|
msg += Dir[work_directory + '/*']
|
78
|
-
|
78
|
+
unless command_output.empty?
|
79
79
|
msg << 'LibreOffice said:'
|
80
80
|
msg << command_output
|
81
81
|
end
|
@@ -93,63 +93,4 @@ module Media
|
|
93
93
|
end
|
94
94
|
|
95
95
|
end
|
96
|
-
|
97
|
-
#
|
98
|
-
# old daemon stuff
|
99
|
-
#
|
100
|
-
|
101
|
-
|
102
|
-
#
|
103
|
-
#require 'socket'
|
104
|
-
#
|
105
|
-
#unless defined?(PYTHON_COMMAND)
|
106
|
-
# # TODO: pick which python to use. on some platforms, we may need to run
|
107
|
-
# # an openoffice specific python.
|
108
|
-
# PYTHON_COMMAND = `which python`.chomp
|
109
|
-
#end
|
110
|
-
|
111
|
-
#if LIBREOFFICE_COMMAND
|
112
|
-
# unless defined?(LIBREOFFICE_CONVERTER_COMMAND)
|
113
|
-
# LIBREOFFICE_CONVERTER_COMMAND = File.dirname(__FILE__) + '/od_converter.py'
|
114
|
-
# end
|
115
|
-
# unless defined?(LIBREOFFICE_DAEMON_PORT)
|
116
|
-
# LIBREOFFICE_DAEMON_PORT = 8100
|
117
|
-
# end
|
118
|
-
# unless defined?(LIBREOFFICE_DAEMON_COMMAND)
|
119
|
-
# LIBREOFFICE_DAEMON_COMMAND = '%s -headless -nolockcheck -nologo -norestore -accept="socket,host=127.0.0.1,port=%s;urp;tcpNoDelay=1"' % [LIBREOFFICE_COMMAND, LIBREOFFICE_DAEMON_PORT]
|
120
|
-
# end
|
121
|
-
#end
|
122
|
-
|
123
|
-
#cmd = `which openoffice`.chomp unless cmd.present?
|
124
|
-
#cmd = `which openoffice.org`.chomp unless cmd.present?
|
125
|
-
|
126
|
-
# def try_starting_daemon
|
127
|
-
# info 'attempting to start libreoffice in daemon mode'
|
128
|
-
# output = `#{LIBREOFFICE_DAEMON_COMMAND}`
|
129
|
-
# if $? == 0
|
130
|
-
# info 'libreoffice started'
|
131
|
-
# else
|
132
|
-
# error 'not able to start libreoffice'
|
133
|
-
# error LIBREOFFICE_DAEMON_COMMAND
|
134
|
-
# error output
|
135
|
-
# end
|
136
|
-
# end
|
137
|
-
|
138
|
-
# def daemon_running?
|
139
|
-
# begin
|
140
|
-
# TCPSocket.new 'localhost', LIBREOFFICE_DAEMON_PORT
|
141
|
-
# return true
|
142
|
-
# rescue Errno::ECONNREFUSED
|
143
|
-
# return false
|
144
|
-
# end
|
145
|
-
# end
|
146
|
-
|
147
|
-
# if !daemon_running?
|
148
|
-
# try_starting_daemon
|
149
|
-
# sleep 1
|
150
|
-
# if !daemon_running?
|
151
|
-
# return :error
|
152
|
-
# end
|
153
|
-
# end
|
154
|
-
# arguments = [PYTHON_COMMAND, LIBREOFFICE_CONVERTER_COMMAND, input_file, output_file]
|
155
96
|
end
|
data/lib/media/version.rb
CHANGED
data/test/files/kaos.pdf
ADDED
Binary file
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'media/transmogrifiers/graphicsmagick'
|
3
|
+
|
4
|
+
class GraphicsMagickTransmogrifierTest < Minitest::Test
|
5
|
+
|
6
|
+
def test_scaling_png_to_jpg
|
7
|
+
input = file('lyra.png')
|
8
|
+
transmog = Media::GraphicsMagickTransmogrifier.new input_file: input,
|
9
|
+
output_type: 'image/jpg',
|
10
|
+
size: '100x100!'
|
11
|
+
assert transmog
|
12
|
+
status = transmog.run
|
13
|
+
assert_equal :success, status
|
14
|
+
assert File.exist?(transmog.output_file.to_s)
|
15
|
+
|
16
|
+
assert file_info_matches?(transmog.output_file, /JPEG/),
|
17
|
+
"output should be a jpg: #{file_info(transmog.output_file)}"
|
18
|
+
assert_equal ['100','100'], Media.dimensions(transmog.output_file),
|
19
|
+
"output should be resized: #{file_info(transmog.output_file)}"
|
20
|
+
end
|
21
|
+
|
22
|
+
# libremagic transmogrifier uses this internally.
|
23
|
+
def test_pdf_as_input
|
24
|
+
skip('ghostscript required') if ghostscript_missing?
|
25
|
+
input = file('kaos.pdf')
|
26
|
+
transmog = Media::GraphicsMagickTransmogrifier.new input_file: input,
|
27
|
+
output_type: 'image/jpg'
|
28
|
+
status = transmog.run
|
29
|
+
assert_equal :success, status
|
30
|
+
assert File.exist?(transmog.output_file.to_s)
|
31
|
+
|
32
|
+
assert file_info_matches?(transmog.output_file, /JPEG/),
|
33
|
+
"output should be a jpg: #{file_info(transmog.output_file)}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def ghostscript_missing?
|
37
|
+
`which ghostscript`.empty?
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'media/transmogrifiers/libremagick'
|
3
|
+
|
4
|
+
class LibreMagickTransmogrifierTest < Minitest::Test
|
5
|
+
|
6
|
+
def test_libremagick_transmog
|
7
|
+
skip 'dependencies missing' unless klass.available?
|
8
|
+
input = file('msword.doc')
|
9
|
+
transmog =
|
10
|
+
klass.new input_file: input,
|
11
|
+
output_type: 'image/jpg'
|
12
|
+
status = transmog.run
|
13
|
+
assert_equal :success, status
|
14
|
+
assert File.exist?(transmog.output_file.to_s)
|
15
|
+
|
16
|
+
assert file_info_matches?(transmog.output_file, /JPEG/),
|
17
|
+
"output should be a jpg: #{file_info(transmog.output_file)}"
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
def klass
|
23
|
+
Media::LibreMagickTransmogrifier
|
24
|
+
end
|
25
|
+
end
|
data/test/media_test.rb
ADDED
data/test/transmogrifier_test.rb
CHANGED
@@ -47,7 +47,6 @@ class TransmogrifierTest < Minitest::Test
|
|
47
47
|
def test_with_output_file
|
48
48
|
input = file('lyra.png')
|
49
49
|
Media::TempFile.open(nil,'image/jpg') do |dest_file|
|
50
|
-
filename = dest_file.to_s
|
51
50
|
transmog = Media.transmogrifier(input_file: input, output_file: dest_file)
|
52
51
|
assert transmog, 'should find transmog'
|
53
52
|
status = transmog.run
|
@@ -69,6 +68,7 @@ class TransmogrifierTest < Minitest::Test
|
|
69
68
|
end
|
70
69
|
|
71
70
|
def test_doc_to_jpg_twostep_transmog
|
71
|
+
skip "We're currently not exposing transformations from pdf. So this has to be done in one step"
|
72
72
|
input = file('msword.doc')
|
73
73
|
transmog = Media.transmogrifier(input_file: input, output_type: 'application/pdf')
|
74
74
|
transmog.run
|
@@ -81,10 +81,16 @@ class TransmogrifierTest < Minitest::Test
|
|
81
81
|
assert file_info_matches?(transmog.output_file, /JPEG/), "output should be a jpg: #{file_info(transmog.output_file)}"
|
82
82
|
end
|
83
83
|
|
84
|
+
def test_no_pdf_transmog
|
85
|
+
input = file('kaos.pdf')
|
86
|
+
transmog = Media.transmogrifier(input_file: input, output_type: 'image/jpg')
|
87
|
+
assert_nil transmog
|
88
|
+
end
|
89
|
+
|
84
90
|
def test_libremagick_transmog
|
85
91
|
input = file('msword.doc')
|
86
92
|
transmog = Media.transmogrifier(input_file: input, output_type: 'image/jpg')
|
87
|
-
|
93
|
+
skip('libremagic is not available') unless transmog
|
88
94
|
status = transmog.run
|
89
95
|
assert_equal :success, status
|
90
96
|
assert File.exist?(transmog.output_file.to_s)
|
metadata
CHANGED
@@ -1,57 +1,85 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crabgrass_media
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Azul
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '4.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '4.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mime-types
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.1'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.1'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rake
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
45
|
- - "~>"
|
32
46
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
47
|
+
version: '12.0'
|
34
48
|
type: :development
|
35
49
|
prerelease: false
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
37
51
|
requirements:
|
38
52
|
- - "~>"
|
39
53
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
54
|
+
version: '12.0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: minitest
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - "~>"
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
61
|
+
version: '5.1'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '5.1'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: conventional-changelog
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.2'
|
48
76
|
type: :development
|
49
77
|
prerelease: false
|
50
78
|
version_requirements: !ruby/object:Gem::Requirement
|
51
79
|
requirements:
|
52
80
|
- - "~>"
|
53
81
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
82
|
+
version: '1.2'
|
55
83
|
description: |2
|
56
84
|
Crabgrass::Media is the Media engine of Crabgrass.
|
57
85
|
|
@@ -76,22 +104,24 @@ files:
|
|
76
104
|
- lib/media/transmogrifiers/libremagick.rb
|
77
105
|
- lib/media/transmogrifiers/libreoffice.rb
|
78
106
|
- lib/media/version.rb
|
79
|
-
- lib/media/version.rb.orig
|
80
107
|
- lib/tasks/media_tasks.rake
|
81
108
|
- test/dummy/db/test.sqlite3
|
82
109
|
- test/dummy/log/test.log
|
83
110
|
- test/files/anarchism.svg
|
84
111
|
- test/files/corrupt.jpg
|
112
|
+
- test/files/kaos.pdf
|
85
113
|
- test/files/lyra.png
|
86
114
|
- test/files/msword.doc
|
115
|
+
- test/graphicsmagick_transmogrifier_test.rb
|
116
|
+
- test/libremagick_transmogrifier_test.rb
|
117
|
+
- test/media_test.rb
|
87
118
|
- test/sleepy_transmogrifier.rb
|
88
119
|
- test/support/file.rb
|
89
|
-
- test/tempfile_test.rb
|
90
120
|
- test/test_helper.rb
|
91
121
|
- test/transmogrifier_test.rb
|
92
122
|
homepage: https://github.com/riseuplabs/crabgrass-media
|
93
123
|
licenses:
|
94
|
-
- AGPL
|
124
|
+
- AGPL-3.0
|
95
125
|
metadata: {}
|
96
126
|
post_install_message:
|
97
127
|
rdoc_options: []
|
@@ -114,14 +144,17 @@ signing_key:
|
|
114
144
|
specification_version: 4
|
115
145
|
summary: Media processing for the Crabgrass social wiki
|
116
146
|
test_files:
|
147
|
+
- test/libremagick_transmogrifier_test.rb
|
148
|
+
- test/test_helper.rb
|
117
149
|
- test/sleepy_transmogrifier.rb
|
118
|
-
- test/
|
119
|
-
- test/
|
150
|
+
- test/media_test.rb
|
151
|
+
- test/support/file.rb
|
120
152
|
- test/files/anarchism.svg
|
121
153
|
- test/files/msword.doc
|
122
|
-
- test/files/corrupt.jpg
|
123
154
|
- test/files/lyra.png
|
124
|
-
- test/
|
155
|
+
- test/files/kaos.pdf
|
156
|
+
- test/files/corrupt.jpg
|
125
157
|
- test/dummy/log/test.log
|
126
|
-
- test/
|
127
|
-
- test/
|
158
|
+
- test/dummy/db/test.sqlite3
|
159
|
+
- test/graphicsmagick_transmogrifier_test.rb
|
160
|
+
- test/transmogrifier_test.rb
|
data/lib/media/version.rb.orig
DELETED