blobsterix 0.0.9
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.
- data/.gitignore +27 -0
- data/CHANGELOG.txt +13 -0
- data/Gemfile +16 -0
- data/LICENSE +22 -0
- data/README.md +122 -0
- data/Rakefile +13 -0
- data/bin/blobsterix +152 -0
- data/bin/test +26 -0
- data/blobsterix.gemspec +39 -0
- data/config/lighttpd.conf +50 -0
- data/lib/blobsterix.rb +213 -0
- data/lib/blobsterix/blob/blob_api.rb +55 -0
- data/lib/blobsterix/blob/blob_url_helper.rb +55 -0
- data/lib/blobsterix/helper/accept_type.rb +62 -0
- data/lib/blobsterix/helper/blob_access.rb +73 -0
- data/lib/blobsterix/helper/config_loader.rb +33 -0
- data/lib/blobsterix/helper/data_response.rb +54 -0
- data/lib/blobsterix/helper/http.rb +47 -0
- data/lib/blobsterix/helper/logable.rb +11 -0
- data/lib/blobsterix/helper/murmur.rb +137 -0
- data/lib/blobsterix/helper/status_info.rb +42 -0
- data/lib/blobsterix/helper/template_renderer.rb +39 -0
- data/lib/blobsterix/mimemagic/magic.rb +138 -0
- data/lib/blobsterix/mimemagic/tables.rb +1770 -0
- data/lib/blobsterix/mimemagic/version.rb +5 -0
- data/lib/blobsterix/router/app_router.rb +134 -0
- data/lib/blobsterix/s3/s3_api.rb +92 -0
- data/lib/blobsterix/s3/s3_url_helper.rb +93 -0
- data/lib/blobsterix/service.rb +34 -0
- data/lib/blobsterix/status/status_api.rb +62 -0
- data/lib/blobsterix/status/status_url_helper.rb +11 -0
- data/lib/blobsterix/storage/blob_meta_data.rb +60 -0
- data/lib/blobsterix/storage/bucket.rb +36 -0
- data/lib/blobsterix/storage/bucket_entry.rb +29 -0
- data/lib/blobsterix/storage/bucket_list.rb +26 -0
- data/lib/blobsterix/storage/cache.rb +90 -0
- data/lib/blobsterix/storage/file_system.rb +132 -0
- data/lib/blobsterix/storage/file_system_meta_data.rb +136 -0
- data/lib/blobsterix/storage/storage.rb +30 -0
- data/lib/blobsterix/transformation/image_transformation.rb +439 -0
- data/lib/blobsterix/transformation/transformation.rb +30 -0
- data/lib/blobsterix/transformation/transformation_chain.rb +78 -0
- data/lib/blobsterix/transformation/transformation_manager.rb +115 -0
- data/lib/blobsterix/version.rb +3 -0
- data/scripts/download.rb +30 -0
- data/scripts/test +6 -0
- data/spec/lib/blob/blob_api_spec.rb +81 -0
- data/spec/lib/helper/blob_access_spec.rb +72 -0
- data/spec/lib/s3/s3_api_spec.rb +183 -0
- data/spec/lib/service_spec.rb +12 -0
- data/spec/lib/status/status_api_spec.rb +42 -0
- data/spec/lib/storage/cache_spec.rb +135 -0
- data/spec/lib/storage/file_system_spec.rb +84 -0
- data/spec/spec_helper.rb +139 -0
- data/templates/app/Gemfile +12 -0
- data/templates/app/Rakefile +7 -0
- data/templates/app/config.rb +61 -0
- data/templates/app/config/environments/development.rb +40 -0
- data/templates/app/config/environments/production.rb +40 -0
- data/templates/app/storages/.keep +0 -0
- data/templates/app/transformators/.keep +0 -0
- data/templates/app/views/.keep +0 -0
- data/templates/storage_template.rb +30 -0
- data/templates/transformation_template.rb +41 -0
- data/templates/views/error_page.erb +18 -0
- data/templates/views/status_page.erb +31 -0
- metadata +325 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
module Blobsterix
|
2
|
+
module Storage
|
3
|
+
class Storage
|
4
|
+
def list(bucket="root")
|
5
|
+
Nokogiri::XML::Builder.new do |xml|
|
6
|
+
xml.Error "no such bucket"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
def bucket_exist(bucket="root")
|
10
|
+
false
|
11
|
+
end
|
12
|
+
def get(bucket, key)
|
13
|
+
Blobsterix::Storage::BlobMetaData.new
|
14
|
+
end
|
15
|
+
def put(bucket, key, value)
|
16
|
+
Blobsterix::Storage::BlobMetaData.new
|
17
|
+
end
|
18
|
+
def create(bucket)
|
19
|
+
Nokogiri::XML::Builder.new do |xml|
|
20
|
+
end
|
21
|
+
end
|
22
|
+
def delete(bucket)
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
def delete_key(bucket, key)
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,439 @@
|
|
1
|
+
module Blobsterix::Transformations::Impl
|
2
|
+
class ColorSpaceImage < Blobsterix::Transformations::Transformation
|
3
|
+
def name()
|
4
|
+
"grayscale"
|
5
|
+
end
|
6
|
+
def input_type()
|
7
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
8
|
+
end
|
9
|
+
|
10
|
+
def output_type()
|
11
|
+
@output_type ||= Blobsterix::AcceptType.new "image/*"
|
12
|
+
end
|
13
|
+
|
14
|
+
def transform(input_path, target_path, value)
|
15
|
+
image = MiniMagick::Image.open(input_path)
|
16
|
+
image.colorspace "gray"
|
17
|
+
image.write target_path
|
18
|
+
end
|
19
|
+
end
|
20
|
+
class RotateImage < Blobsterix::Transformations::Transformation
|
21
|
+
def name()
|
22
|
+
"rotate"
|
23
|
+
end
|
24
|
+
def input_type()
|
25
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
26
|
+
end
|
27
|
+
|
28
|
+
def output_type()
|
29
|
+
@output_type ||= Blobsterix::AcceptType.new "image/*"
|
30
|
+
end
|
31
|
+
|
32
|
+
def transform(input_path, target_path, value)
|
33
|
+
image = MiniMagick::Image.open(input_path)
|
34
|
+
image.combine_options do |c|
|
35
|
+
c.background "none"
|
36
|
+
c.rotate value
|
37
|
+
end
|
38
|
+
image.write target_path
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class AdaptiveResizeImage < Blobsterix::Transformations::Transformation
|
43
|
+
def name()
|
44
|
+
"aresize"
|
45
|
+
end
|
46
|
+
def input_type()
|
47
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
48
|
+
end
|
49
|
+
|
50
|
+
def output_type()
|
51
|
+
@output_type ||= Blobsterix::AcceptType.new "image/*"
|
52
|
+
end
|
53
|
+
|
54
|
+
def transform(input_path, target_path, value)
|
55
|
+
image = MiniMagick::Image.open(input_path)
|
56
|
+
image.adaptive_resize value
|
57
|
+
image.write target_path
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class ResizeImage < Blobsterix::Transformations::Transformation
|
62
|
+
def name()
|
63
|
+
"resize"
|
64
|
+
end
|
65
|
+
def input_type()
|
66
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
67
|
+
end
|
68
|
+
|
69
|
+
def output_type()
|
70
|
+
@output_type ||= Blobsterix::AcceptType.new "image/*"
|
71
|
+
end
|
72
|
+
|
73
|
+
def transform(input_path, target_path, value)
|
74
|
+
image = MiniMagick::Image.open(input_path)
|
75
|
+
image.resize value
|
76
|
+
image.write target_path
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class MaxsizeImage < Blobsterix::Transformations::Transformation
|
81
|
+
def name()
|
82
|
+
"resizemax"
|
83
|
+
end
|
84
|
+
def input_type()
|
85
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
86
|
+
end
|
87
|
+
|
88
|
+
def output_type()
|
89
|
+
@output_type ||= Blobsterix::AcceptType.new "image/*"
|
90
|
+
end
|
91
|
+
|
92
|
+
def transform(input_path, target_path, value)
|
93
|
+
image = MiniMagick::Image.open(input_path)
|
94
|
+
image.resize "#{value}>"
|
95
|
+
image.write target_path
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class ShrinkImage < Blobsterix::Transformations::Transformation
|
100
|
+
def name()
|
101
|
+
"shrink"
|
102
|
+
end
|
103
|
+
def input_type()
|
104
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
105
|
+
end
|
106
|
+
|
107
|
+
def output_type()
|
108
|
+
@output_type ||= Blobsterix::AcceptType.new "image/*"
|
109
|
+
end
|
110
|
+
|
111
|
+
def transform(input_path, target_path, value)
|
112
|
+
image = MiniMagick::Image.open(input_path)
|
113
|
+
image.resize "#{image[:width]/value.to_i}x#{image[:height]/value.to_i}"
|
114
|
+
image.write target_path
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class StripImage < Blobsterix::Transformations::Transformation
|
119
|
+
def name()
|
120
|
+
"strip"
|
121
|
+
end
|
122
|
+
def input_type()
|
123
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
124
|
+
end
|
125
|
+
|
126
|
+
def output_type()
|
127
|
+
@output_type ||= Blobsterix::AcceptType.new "image/*"
|
128
|
+
end
|
129
|
+
|
130
|
+
def is_format?()
|
131
|
+
true
|
132
|
+
end
|
133
|
+
|
134
|
+
def transform(input_path, target_path, value)
|
135
|
+
image = MiniMagick::Image.open(input_path)
|
136
|
+
image.strip
|
137
|
+
image.write target_path
|
138
|
+
# system("convert #{input_path} -strip #{target_path}")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
class CropImage < Blobsterix::Transformations::Transformation
|
143
|
+
def name()
|
144
|
+
"crop"
|
145
|
+
end
|
146
|
+
def input_type()
|
147
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
148
|
+
end
|
149
|
+
|
150
|
+
def output_type()
|
151
|
+
@output_type ||= Blobsterix::AcceptType.new "image/*"
|
152
|
+
end
|
153
|
+
|
154
|
+
def transform(input_path, target_path, value)
|
155
|
+
image = MiniMagick::Image.open(input_path)
|
156
|
+
image.crop value
|
157
|
+
image.write target_path
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
class Image2HTML < Blobsterix::Transformations::Transformation
|
162
|
+
def input_type()
|
163
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
164
|
+
end
|
165
|
+
|
166
|
+
def output_type()
|
167
|
+
@output_type ||= Blobsterix::AcceptType.new "text/html"
|
168
|
+
end
|
169
|
+
|
170
|
+
def is_format?()
|
171
|
+
true
|
172
|
+
end
|
173
|
+
|
174
|
+
def transform(input_path, target_path, value)
|
175
|
+
type = "image/*"
|
176
|
+
File.open(input_path) {|file|
|
177
|
+
type = MimeMagic.by_magic(file).type
|
178
|
+
}
|
179
|
+
|
180
|
+
image = type === "image/webp" ? {:width => "unknown", :height => "unknown"} : MiniMagick::Image.open(input_path)
|
181
|
+
File.open(target_path, "w") {|file|
|
182
|
+
file.write("<html><body>Mimetype: #{type}<br>Width: #{image[:width]}<br>Height: #{image[:height]}</body></html>")
|
183
|
+
}
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
class Image2Json < Blobsterix::Transformations::Transformation
|
188
|
+
def name()
|
189
|
+
"json"
|
190
|
+
end
|
191
|
+
|
192
|
+
def input_type()
|
193
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
194
|
+
end
|
195
|
+
|
196
|
+
def output_type()
|
197
|
+
@output_type ||= Blobsterix::AcceptType.new "text/json"
|
198
|
+
end
|
199
|
+
|
200
|
+
def is_format?()
|
201
|
+
true
|
202
|
+
end
|
203
|
+
|
204
|
+
def transform(input_path, target_path, value)
|
205
|
+
type = "image/*"
|
206
|
+
File.open(input_path) {|file|
|
207
|
+
type = MimeMagic.by_magic(file).type
|
208
|
+
}
|
209
|
+
|
210
|
+
image = type === "image/webp" ? {:width => "unknown", :height => "unknown"} : MiniMagick::Image.open(input_path)
|
211
|
+
File.open(target_path, "w") {|file|
|
212
|
+
file.write({:width => image[:width], :height => image[:height]}.merge(Blobsterix::Storage::FileSystemMetaData.new(input_path).as_json).to_json)
|
213
|
+
}
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
class Image2Json < Blobsterix::Transformations::Transformation
|
218
|
+
def name()
|
219
|
+
"json_all"
|
220
|
+
end
|
221
|
+
|
222
|
+
def input_type()
|
223
|
+
@input_type ||= Blobsterix::AcceptType.new "*/*"
|
224
|
+
end
|
225
|
+
|
226
|
+
def output_type()
|
227
|
+
@output_type ||= Blobsterix::AcceptType.new "text/json"
|
228
|
+
end
|
229
|
+
|
230
|
+
def is_format?()
|
231
|
+
true
|
232
|
+
end
|
233
|
+
|
234
|
+
def transform(input_path, target_path, value)
|
235
|
+
File.open(target_path, "w") {|file|
|
236
|
+
file.write(Blobsterix::Storage::FileSystemMetaData.new(input_path).to_json)
|
237
|
+
}
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
class RawTransformation < Blobsterix::Transformations::Transformation
|
242
|
+
def name()
|
243
|
+
"raw"
|
244
|
+
end
|
245
|
+
|
246
|
+
def is_format?()
|
247
|
+
true
|
248
|
+
end
|
249
|
+
|
250
|
+
def input_type()
|
251
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
252
|
+
end
|
253
|
+
|
254
|
+
def output_type()
|
255
|
+
@output_type ||= Blobsterix::AcceptType.new "image/*"
|
256
|
+
end
|
257
|
+
|
258
|
+
def transform(input_path, target_path, value)
|
259
|
+
raise StandardError.new($?) unless system("cp \"#{input_path}\" \"#{target_path}\"")
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
class AsciiTransformation < Blobsterix::Transformations::Transformation
|
264
|
+
def name()
|
265
|
+
"ascii"
|
266
|
+
end
|
267
|
+
|
268
|
+
def is_format?()
|
269
|
+
true
|
270
|
+
end
|
271
|
+
|
272
|
+
def input_type()
|
273
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
274
|
+
end
|
275
|
+
|
276
|
+
def output_type()
|
277
|
+
@output_type ||= Blobsterix::AcceptType.new "text/plain"
|
278
|
+
end
|
279
|
+
|
280
|
+
def transform(input_path, target_path, value)
|
281
|
+
raise StandardError.new($?) unless system("convert \"#{input_path}\" jpg:- | jp2a --width=#{value and value.size > 0 ? value : 100} - > \"#{target_path}\"")
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
class AsciiHTMLTransformation < Blobsterix::Transformations::Transformation
|
286
|
+
def name()
|
287
|
+
"asciihtml"
|
288
|
+
end
|
289
|
+
|
290
|
+
def is_format?()
|
291
|
+
true
|
292
|
+
end
|
293
|
+
|
294
|
+
def input_type()
|
295
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
296
|
+
end
|
297
|
+
|
298
|
+
def output_type()
|
299
|
+
@output_type ||= Blobsterix::AcceptType.new "text/plain"
|
300
|
+
end
|
301
|
+
|
302
|
+
def transform(input_path, target_path, value)
|
303
|
+
parts = value.split("x")[0]
|
304
|
+
lines = parts[0]
|
305
|
+
em = parts.length > 1 ? parts[1].to_i : 1
|
306
|
+
raise StandardError.new($?) unless system("convert \"#{input_path}\" jpg:- | jp2a --width=#{lines and lines.to_i > 0 ? value : 100} - > \"#{target_path}\"")
|
307
|
+
text = File.read(target_path)
|
308
|
+
File.write(target_path, "<html><body style='font-size: #{em}em'><pre>#{text.gsub("\n", "<br>")}</pre></body></html>")
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
class PngTransformation < Blobsterix::Transformations::Transformation
|
313
|
+
def name()
|
314
|
+
"png"
|
315
|
+
end
|
316
|
+
|
317
|
+
def is_format?()
|
318
|
+
true
|
319
|
+
end
|
320
|
+
|
321
|
+
def input_type()
|
322
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
323
|
+
end
|
324
|
+
|
325
|
+
def output_type()
|
326
|
+
@output_type ||= Blobsterix::AcceptType.new "image/png"
|
327
|
+
end
|
328
|
+
|
329
|
+
def transform(input_path, target_path, value)
|
330
|
+
raise StandardError.new($?) unless system("convert \"#{input_path}\" png:\"#{target_path}\"")
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
class JPegTransformation < Blobsterix::Transformations::Transformation
|
335
|
+
def name()
|
336
|
+
"jpg"
|
337
|
+
end
|
338
|
+
|
339
|
+
def is_format?()
|
340
|
+
true
|
341
|
+
end
|
342
|
+
|
343
|
+
def input_type()
|
344
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
345
|
+
end
|
346
|
+
|
347
|
+
def output_type()
|
348
|
+
@output_type ||= Blobsterix::AcceptType.new "image/jpeg"
|
349
|
+
end
|
350
|
+
|
351
|
+
def transform(input_path, target_path, value)
|
352
|
+
raise StandardError.new($?) unless system("convert \"#{input_path}\" jpg:\"#{target_path}\"")
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
class GifTransformation < Blobsterix::Transformations::Transformation
|
357
|
+
def name()
|
358
|
+
"gif"
|
359
|
+
end
|
360
|
+
|
361
|
+
def is_format?()
|
362
|
+
true
|
363
|
+
end
|
364
|
+
|
365
|
+
def input_type()
|
366
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
367
|
+
end
|
368
|
+
|
369
|
+
def output_type()
|
370
|
+
@output_type ||= Blobsterix::AcceptType.new "image/gif"
|
371
|
+
end
|
372
|
+
|
373
|
+
def transform(input_path, target_path, value)
|
374
|
+
raise StandardError.new($?) unless system("convert \"#{input_path}\" gif:\"#{target_path}\"")
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
class WebPTransformation < Blobsterix::Transformations::Transformation
|
379
|
+
def name()
|
380
|
+
"webp"
|
381
|
+
end
|
382
|
+
|
383
|
+
def is_format?()
|
384
|
+
true
|
385
|
+
end
|
386
|
+
|
387
|
+
def input_type()
|
388
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
389
|
+
end
|
390
|
+
|
391
|
+
def output_type()
|
392
|
+
@output_type ||= Blobsterix::AcceptType.new "image/webp"
|
393
|
+
end
|
394
|
+
|
395
|
+
def transform(input_path, target_path, value)
|
396
|
+
raise StandardError.new($?) unless system("cwebp \"#{input_path}\" -o \"#{target_path}\"")
|
397
|
+
#system("cp #{input_path} #{target_path}")
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
class RenderTextTransformation < Blobsterix::Transformations::Transformation
|
402
|
+
def name()
|
403
|
+
"text"
|
404
|
+
end
|
405
|
+
|
406
|
+
def input_type()
|
407
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
408
|
+
end
|
409
|
+
|
410
|
+
def output_type()
|
411
|
+
@output_type ||= Blobsterix::AcceptType.new "image/*"
|
412
|
+
end
|
413
|
+
|
414
|
+
def transform(input_path, target_path, value)
|
415
|
+
puts "Render text"
|
416
|
+
raise StandardError.new($?) unless system("convert \"#{input_path}\" -pointsize 20 -draw \"gravity center fill white text 0,12 '#{value.gsub("_", " ").gsub("\"", "'")}'\" \"#{target_path}\"")
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
class SleepTransformation < Blobsterix::Transformations::Transformation
|
421
|
+
def name()
|
422
|
+
"sleep"
|
423
|
+
end
|
424
|
+
|
425
|
+
def input_type()
|
426
|
+
@input_type ||= Blobsterix::AcceptType.new "image/*"
|
427
|
+
end
|
428
|
+
|
429
|
+
def output_type()
|
430
|
+
@output_type ||= Blobsterix::AcceptType.new "image/*"
|
431
|
+
end
|
432
|
+
|
433
|
+
def transform(input_path, target_path, value)
|
434
|
+
p "SLEEEP"
|
435
|
+
sleep(value.to_i)
|
436
|
+
raise StandardError.new($?) unless system("cp \"#{input_path}\" \"#{target_path}\"")
|
437
|
+
end
|
438
|
+
end
|
439
|
+
end
|