dragonfly 0.9.15 → 1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of dragonfly might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/.gitignore +1 -8
- data/.travis.yml +11 -0
- data/Gemfile +1 -0
- data/History.md +52 -2
- data/LICENSE +1 -1
- data/README.md +38 -95
- data/dev/grid.jpg +0 -0
- data/dev/irbrc.rb +27 -0
- data/dev/rails_template.rb +38 -0
- data/dev/test.ru +56 -0
- data/dev/test_rails +19 -0
- data/dragonfly.gemspec +3 -21
- data/lib/dragonfly.rb +45 -44
- data/lib/dragonfly/app.rb +175 -96
- data/lib/dragonfly/configurable.rb +71 -170
- data/lib/dragonfly/content.rb +211 -0
- data/lib/dragonfly/core_ext/object.rb +1 -6
- data/lib/dragonfly/file_data_store.rb +197 -0
- data/lib/dragonfly/image_magick/analysers/image_properties.rb +23 -0
- data/lib/dragonfly/image_magick/generators/convert.rb +19 -0
- data/lib/dragonfly/image_magick/generators/plain.rb +26 -0
- data/lib/dragonfly/image_magick/generators/plasma.rb +25 -0
- data/lib/dragonfly/image_magick/generators/text.rb +127 -0
- data/lib/dragonfly/image_magick/plugin.rb +83 -0
- data/lib/dragonfly/image_magick/processors/convert.rb +29 -0
- data/lib/dragonfly/image_magick/processors/encode.rb +18 -0
- data/lib/dragonfly/image_magick/processors/thumb.rb +76 -0
- data/lib/dragonfly/job.rb +118 -134
- data/lib/dragonfly/job_endpoint.rb +2 -0
- data/lib/dragonfly/memory_data_store.rb +34 -0
- data/lib/dragonfly/middleware.rb +5 -3
- data/lib/dragonfly/{active_model_extensions.rb → model.rb} +5 -3
- data/lib/dragonfly/{active_model_extensions → model}/attachment.rb +40 -35
- data/lib/dragonfly/{active_model_extensions → model}/attachment_class_methods.rb +36 -40
- data/lib/dragonfly/model/class_methods.rb +109 -0
- data/lib/dragonfly/{active_model_extensions → model}/instance_methods.rb +2 -2
- data/lib/dragonfly/{active_model_extensions → model}/validations.rb +17 -12
- data/lib/dragonfly/railtie.rb +8 -6
- data/lib/dragonfly/register.rb +27 -0
- data/lib/dragonfly/response.rb +47 -52
- data/lib/dragonfly/routed_endpoint.rb +4 -0
- data/lib/dragonfly/serializer.rb +15 -5
- data/lib/dragonfly/server.rb +56 -29
- data/lib/dragonfly/shell.rb +12 -23
- data/lib/dragonfly/spec/data_store_examples.rb +64 -0
- data/lib/dragonfly/temp_object.rb +32 -47
- data/lib/dragonfly/url_attributes.rb +19 -22
- data/lib/dragonfly/url_mapper.rb +3 -0
- data/lib/dragonfly/utils.rb +12 -0
- data/lib/dragonfly/version.rb +1 -1
- data/lib/dragonfly/whitelist.rb +19 -0
- data/lib/rails/generators/dragonfly/USAGE +8 -0
- data/lib/rails/generators/dragonfly/dragonfly_generator.rb +24 -0
- data/lib/rails/generators/dragonfly/templates/initializer.rb.erb +27 -0
- data/samples/gif.gif +0 -0
- data/spec/dragonfly/app_spec.rb +270 -64
- data/spec/dragonfly/configurable_spec.rb +142 -418
- data/spec/dragonfly/content_spec.rb +353 -0
- data/spec/dragonfly/cookie_monster_spec.rb +2 -1
- data/spec/dragonfly/file_data_store_spec.rb +301 -0
- data/spec/dragonfly/image_magick/analysers/image_properties_spec.rb +20 -0
- data/spec/dragonfly/image_magick/generators/convert_spec.rb +19 -0
- data/spec/dragonfly/image_magick/generators/plain_spec.rb +50 -0
- data/spec/dragonfly/image_magick/generators/plasma_spec.rb +32 -0
- data/spec/dragonfly/image_magick/generators/text_spec.rb +77 -0
- data/spec/dragonfly/image_magick/plugin_spec.rb +131 -0
- data/spec/dragonfly/image_magick/processors/convert_spec.rb +56 -0
- data/spec/dragonfly/image_magick/processors/thumb_spec.rb +173 -0
- data/spec/dragonfly/job_endpoint_spec.rb +30 -73
- data/spec/dragonfly/job_spec.rb +280 -608
- data/spec/dragonfly/memory_data_store_spec.rb +20 -0
- data/spec/dragonfly/middleware_spec.rb +47 -27
- data/spec/dragonfly/{active_model_extensions → model}/model_spec.rb +331 -555
- data/spec/dragonfly/model/validations_spec.rb +196 -0
- data/spec/dragonfly/register_spec.rb +35 -0
- data/spec/dragonfly/routed_endpoint_spec.rb +6 -6
- data/spec/dragonfly/serializer_spec.rb +13 -15
- data/spec/dragonfly/server_spec.rb +122 -46
- data/spec/dragonfly/shell_spec.rb +43 -24
- data/spec/dragonfly/temp_object_spec.rb +69 -94
- data/spec/dragonfly/url_attributes_spec.rb +49 -0
- data/spec/dragonfly/utils_spec.rb +32 -0
- data/spec/dragonfly/whitelist_spec.rb +30 -0
- data/spec/dragonfly_spec.rb +43 -0
- data/spec/fixtures/deprecated_stored_content/eggs.bonus +1 -0
- data/spec/fixtures/deprecated_stored_content/eggs.bonus.meta +1 -0
- data/spec/functional/configuration_spec.rb +19 -0
- data/spec/functional/model_urls_spec.rb +43 -41
- data/spec/functional/remote_on_the_fly_spec.rb +14 -16
- data/spec/functional/shell_commands_spec.rb +24 -14
- data/spec/functional/to_response_spec.rb +10 -10
- data/spec/functional/urls_spec.rb +5 -3
- data/spec/spec_helper.rb +23 -28
- data/spec/support/argument_matchers.rb +7 -8
- data/spec/support/image_matchers.rb +14 -36
- data/spec/support/model_helpers.rb +97 -0
- data/spec/support/simple_matchers.rb +12 -0
- metadata +92 -393
- data/.yardopts +0 -29
- data/Rakefile +0 -36
- data/config.ru +0 -14
- data/docs.watchr +0 -1
- data/extra_docs/Analysers.md +0 -68
- data/extra_docs/Caching.md +0 -23
- data/extra_docs/Configuration.md +0 -149
- data/extra_docs/Couch.md +0 -49
- data/extra_docs/DataStorage.md +0 -226
- data/extra_docs/Encoding.md +0 -67
- data/extra_docs/ExampleUseCases.md +0 -116
- data/extra_docs/GeneralUsage.md +0 -105
- data/extra_docs/Generators.md +0 -68
- data/extra_docs/Heroku.md +0 -50
- data/extra_docs/ImageMagick.md +0 -136
- data/extra_docs/Index.md +0 -33
- data/extra_docs/MimeTypes.md +0 -40
- data/extra_docs/Models.md +0 -441
- data/extra_docs/Mongo.md +0 -42
- data/extra_docs/Processing.md +0 -77
- data/extra_docs/Rack.md +0 -52
- data/extra_docs/Rails2.md +0 -57
- data/extra_docs/Rails3.md +0 -56
- data/extra_docs/ServingRemotely.md +0 -104
- data/extra_docs/Sinatra.md +0 -25
- data/extra_docs/URLs.md +0 -203
- data/features/images.feature +0 -47
- data/features/no_processing.feature +0 -14
- data/features/rails.feature +0 -8
- data/features/steps/common_steps.rb +0 -8
- data/features/steps/dragonfly_steps.rb +0 -66
- data/features/steps/rails_steps.rb +0 -40
- data/features/support/env.rb +0 -13
- data/features/support/setup.rb +0 -41
- data/fixtures/rails/files/app/models/album.rb +0 -6
- data/fixtures/rails/files/app/views/albums/new.html.erb +0 -7
- data/fixtures/rails/files/app/views/albums/show.html.erb +0 -6
- data/fixtures/rails/files/config/initializers/dragonfly.rb +0 -4
- data/fixtures/rails/files/features/manage_album_images.feature +0 -38
- data/fixtures/rails/files/features/step_definitions/helper_steps.rb +0 -7
- data/fixtures/rails/files/features/step_definitions/image_steps.rb +0 -25
- data/fixtures/rails/files/features/step_definitions/web_steps.rb +0 -189
- data/fixtures/rails/files/features/support/paths.rb +0 -17
- data/fixtures/rails/files/features/text_images.feature +0 -7
- data/fixtures/rails/template.rb +0 -20
- data/irbrc.rb +0 -19
- data/lib/dragonfly/active_model_extensions/class_methods.rb +0 -98
- data/lib/dragonfly/analyser.rb +0 -58
- data/lib/dragonfly/analysis/file_command_analyser.rb +0 -33
- data/lib/dragonfly/analysis/image_magick_analyser.rb +0 -6
- data/lib/dragonfly/config/heroku.rb +0 -26
- data/lib/dragonfly/config/image_magick.rb +0 -6
- data/lib/dragonfly/config/rails.rb +0 -20
- data/lib/dragonfly/data_storage.rb +0 -11
- data/lib/dragonfly/data_storage/couch_data_store.rb +0 -83
- data/lib/dragonfly/data_storage/file_data_store.rb +0 -144
- data/lib/dragonfly/data_storage/mongo_data_store.rb +0 -96
- data/lib/dragonfly/data_storage/s3data_store.rb +0 -168
- data/lib/dragonfly/encoder.rb +0 -13
- data/lib/dragonfly/encoding/image_magick_encoder.rb +0 -6
- data/lib/dragonfly/function_manager.rb +0 -67
- data/lib/dragonfly/generation/image_magick_generator.rb +0 -6
- data/lib/dragonfly/generator.rb +0 -9
- data/lib/dragonfly/image_magick/analyser.rb +0 -53
- data/lib/dragonfly/image_magick/config.rb +0 -44
- data/lib/dragonfly/image_magick/encoder.rb +0 -57
- data/lib/dragonfly/image_magick/generator.rb +0 -147
- data/lib/dragonfly/image_magick/processor.rb +0 -114
- data/lib/dragonfly/image_magick/utils.rb +0 -46
- data/lib/dragonfly/image_magick_utils.rb +0 -4
- data/lib/dragonfly/job_builder.rb +0 -39
- data/lib/dragonfly/job_definitions.rb +0 -30
- data/lib/dragonfly/loggable.rb +0 -28
- data/lib/dragonfly/processing/image_magick_processor.rb +0 -6
- data/lib/dragonfly/processor.rb +0 -9
- data/lib/dragonfly/rails/images.rb +0 -32
- data/lib/dragonfly/simple_cache.rb +0 -23
- data/spec/dragonfly/active_model_extensions/spec_helper.rb +0 -95
- data/spec/dragonfly/analyser_spec.rb +0 -123
- data/spec/dragonfly/analysis/file_command_analyser_spec.rb +0 -49
- data/spec/dragonfly/data_storage/couch_data_store_spec.rb +0 -84
- data/spec/dragonfly/data_storage/file_data_store_spec.rb +0 -308
- data/spec/dragonfly/data_storage/mongo_data_store_spec.rb +0 -81
- data/spec/dragonfly/data_storage/s3_data_store_spec.rb +0 -277
- data/spec/dragonfly/data_storage/shared_data_store_examples.rb +0 -77
- data/spec/dragonfly/function_manager_spec.rb +0 -154
- data/spec/dragonfly/image_magick/analyser_spec.rb +0 -73
- data/spec/dragonfly/image_magick/encoder_spec.rb +0 -46
- data/spec/dragonfly/image_magick/generator_spec.rb +0 -178
- data/spec/dragonfly/image_magick/processor_spec.rb +0 -293
- data/spec/dragonfly/job_builder_spec.rb +0 -37
- data/spec/dragonfly/job_definitions_spec.rb +0 -57
- data/spec/dragonfly/loggable_spec.rb +0 -80
- data/spec/dragonfly/simple_cache_spec.rb +0 -27
- data/spec/dragonfly/url_attributes.rb +0 -47
- data/spec/functional/deprecations_spec.rb +0 -51
- data/spec/functional/image_magick_app_spec.rb +0 -27
- data/spec/test_imagemagick.ru +0 -49
- data/yard/handlers/configurable_attr_handler.rb +0 -38
- data/yard/setup.rb +0 -15
- data/yard/templates/default/fulldoc/html/css/common.css +0 -109
- data/yard/templates/default/layout/html/layout.erb +0 -93
- data/yard/templates/default/module/html/configuration_summary.erb +0 -31
- data/yard/templates/default/module/setup.rb +0 -17
@@ -2,205 +2,106 @@ module Dragonfly
|
|
2
2
|
module Configurable
|
3
3
|
|
4
4
|
# Exceptions
|
5
|
-
class
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
module InstanceMethods
|
26
|
-
|
27
|
-
def configure(&block)
|
28
|
-
yield ConfigurationProxy.new(self)
|
29
|
-
self
|
30
|
-
end
|
31
|
-
|
32
|
-
def configure_with(config, *args, &block)
|
33
|
-
config = saved_config_for(config) if config.is_a?(Symbol)
|
34
|
-
config.apply_configuration(self, *args)
|
35
|
-
configure(&block) if block
|
36
|
-
self
|
37
|
-
end
|
38
|
-
|
39
|
-
def has_config_method?(method_name)
|
40
|
-
config_methods.include?(method_name.to_sym)
|
41
|
-
end
|
42
|
-
|
43
|
-
def configuration
|
44
|
-
@configuration ||= {}
|
45
|
-
end
|
46
|
-
|
47
|
-
def config_methods
|
48
|
-
@config_methods ||= self.class.config_methods.dup
|
49
|
-
end
|
50
|
-
|
51
|
-
def default_configuration
|
52
|
-
@default_configuration ||= self.class.default_configuration.dup
|
53
|
-
end
|
54
|
-
|
55
|
-
def set_config_value(key, value)
|
56
|
-
configuration[key] = value
|
57
|
-
child_configurables.each{|c| c.set_if_unset(key, value) }
|
58
|
-
value
|
59
|
-
end
|
60
|
-
|
61
|
-
def use_as_fallback_config(other_configurable)
|
62
|
-
other_configurable.add_child_configurable(self)
|
63
|
-
self.fallback_configurable = other_configurable
|
64
|
-
end
|
65
|
-
|
66
|
-
protected
|
67
|
-
|
68
|
-
def add_child_configurable(obj)
|
69
|
-
child_configurables << obj
|
70
|
-
config_methods.push(*obj.config_methods)
|
71
|
-
fallback_configurable.config_methods.push(*obj.config_methods) if fallback_configurable
|
72
|
-
end
|
73
|
-
|
74
|
-
def set_if_unset(key, value)
|
75
|
-
set_config_value(key, value) unless set_locally?(key)
|
76
|
-
end
|
77
|
-
|
78
|
-
private
|
79
|
-
|
80
|
-
attr_accessor :fallback_configurable
|
81
|
-
|
82
|
-
def child_configurables
|
83
|
-
@child_configurables ||= []
|
84
|
-
end
|
85
|
-
|
86
|
-
def set_locally?(key)
|
87
|
-
instance_variable_defined?("@#{key}")
|
88
|
-
end
|
89
|
-
|
90
|
-
def default_value(key)
|
91
|
-
if default_configuration[key].is_a?(DeferredBlock)
|
92
|
-
default_configuration[key] = default_configuration[key].call
|
5
|
+
class UnregisteredPlugin < RuntimeError; end
|
6
|
+
|
7
|
+
class Configurer
|
8
|
+
|
9
|
+
class << self
|
10
|
+
private
|
11
|
+
|
12
|
+
def writer(*args)
|
13
|
+
names, opts = extract_options(args)
|
14
|
+
names.each do |name|
|
15
|
+
define_method name do |value|
|
16
|
+
if opts[:for]
|
17
|
+
obj.send(opts[:for]).send("#{name}=", value)
|
18
|
+
else
|
19
|
+
obj.send("#{name}=", value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
93
23
|
end
|
94
|
-
default_configuration[key]
|
95
|
-
end
|
96
|
-
|
97
|
-
def saved_configs
|
98
|
-
self.class.saved_configs
|
99
|
-
end
|
100
24
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
25
|
+
def meth(*args)
|
26
|
+
names, opts = extract_options(args)
|
27
|
+
names.each do |name|
|
28
|
+
define_method name do |*args, &block|
|
29
|
+
if opts[:for]
|
30
|
+
obj.send(opts[:for]).send(name, *args, &block)
|
31
|
+
else
|
32
|
+
obj.send(name, *args, &block)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
105
36
|
end
|
106
|
-
config = config.call if config.respond_to?(:call)
|
107
|
-
config
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
37
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
@default_configuration ||= configurable_ancestors.reverse.inject({}) do |default_config, klass|
|
116
|
-
default_config.merge!(klass.default_configuration)
|
117
|
-
default_config
|
38
|
+
def extract_options(args)
|
39
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
40
|
+
[args, opts]
|
118
41
|
end
|
119
42
|
end
|
120
43
|
|
121
|
-
def
|
122
|
-
|
123
|
-
conf_methods |= klass.config_methods
|
124
|
-
conf_methods
|
125
|
-
end
|
44
|
+
def initialize(&block)
|
45
|
+
(class << self; self; end).class_eval(&block)
|
126
46
|
end
|
127
47
|
|
128
|
-
def
|
129
|
-
|
48
|
+
def configure(obj, &block)
|
49
|
+
previous_obj = @obj
|
50
|
+
@obj = obj
|
51
|
+
instance_eval(&block)
|
52
|
+
@obj = previous_obj
|
130
53
|
end
|
131
54
|
|
132
|
-
def
|
133
|
-
|
55
|
+
def configure_with_plugin(obj, plugin, *args, &block)
|
56
|
+
if plugin.is_a?(Symbol)
|
57
|
+
symbol = plugin
|
58
|
+
raise(UnregisteredPlugin, "plugin #{symbol.inspect} is not registered") unless registered_plugins[symbol]
|
59
|
+
plugin = registered_plugins[symbol].call
|
60
|
+
obj.plugins[symbol] = plugin if obj.respond_to?(:plugins)
|
61
|
+
end
|
62
|
+
plugin.call(obj, *args, &block)
|
63
|
+
plugin
|
134
64
|
end
|
135
65
|
|
136
|
-
def
|
137
|
-
|
66
|
+
def register_plugin(name, &block)
|
67
|
+
registered_plugins[name] = block
|
138
68
|
end
|
139
69
|
|
140
|
-
def
|
141
|
-
|
70
|
+
def plugin(plugin, *args, &block)
|
71
|
+
configure_with_plugin(obj, plugin, *args, &block)
|
142
72
|
end
|
143
73
|
|
144
74
|
private
|
145
75
|
|
146
|
-
|
147
|
-
default_configuration[attribute] = blk ? DeferredBlock.new(blk) : default
|
148
|
-
|
149
|
-
# Define the reader
|
150
|
-
define_method(attribute) do
|
151
|
-
configuration.has_key?(attribute) ? configuration[attribute] : default_value(attribute)
|
152
|
-
end
|
153
|
-
|
154
|
-
# Define the writer
|
155
|
-
define_method("#{attribute}=") do |value|
|
156
|
-
instance_variable_set("@#{attribute}", value)
|
157
|
-
set_config_value(attribute, value)
|
158
|
-
end
|
76
|
+
attr_reader :obj
|
159
77
|
|
160
|
-
|
161
|
-
|
78
|
+
def registered_plugins
|
79
|
+
@registered_plugins ||= {}
|
162
80
|
end
|
163
|
-
|
164
|
-
def configuration_method(*method_names)
|
165
|
-
config_methods.push(*method_names.map{|n| n.to_sym }).uniq!
|
166
|
-
end
|
167
|
-
|
168
|
-
def nested_configurable(*method_names)
|
169
|
-
nested_configurables.push(*method_names)
|
170
|
-
end
|
171
|
-
|
172
81
|
end
|
173
82
|
|
174
|
-
|
83
|
+
#######
|
175
84
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
attribute = method_name.to_s.tr('=','').to_sym
|
183
|
-
if method_name.to_s =~ /=$/ && owner.has_config_method?(attribute) # a bit hacky - if it has both getter and setter, assume it's a configurable_attr
|
184
|
-
owner.set_config_value(attribute, args.first)
|
185
|
-
else
|
186
|
-
owner.send(method_name, *args, &block)
|
187
|
-
end
|
188
|
-
elsif nested_configurable?(method_name)
|
189
|
-
owner.send(method_name)
|
190
|
-
else
|
191
|
-
raise BadConfigAttribute, "You tried to configure using '#{method_name.inspect}', but the valid config attributes are #{owner.config_methods.map{|a| %('#{a.inspect}') }.sort.join(', ')}"
|
85
|
+
def set_up_config(&setup_block)
|
86
|
+
self.configurer = Configurer.new(&setup_block)
|
87
|
+
class_eval do
|
88
|
+
def configure(&block)
|
89
|
+
self.class.configurer.configure(self, &block)
|
90
|
+
self
|
192
91
|
end
|
193
|
-
end
|
194
|
-
|
195
|
-
private
|
196
92
|
|
197
|
-
|
93
|
+
def configure_with(plugin, *args, &block)
|
94
|
+
self.class.configurer.configure_with_plugin(self, plugin, *args, &block)
|
95
|
+
self
|
96
|
+
end
|
198
97
|
|
199
|
-
|
200
|
-
|
98
|
+
def plugins
|
99
|
+
@plugins ||= {}
|
100
|
+
end
|
201
101
|
end
|
202
|
-
|
203
102
|
end
|
204
103
|
|
104
|
+
attr_accessor :configurer
|
105
|
+
|
205
106
|
end
|
206
107
|
end
|
@@ -0,0 +1,211 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'forwardable'
|
3
|
+
require 'dragonfly/has_filename'
|
4
|
+
require 'dragonfly/temp_object'
|
5
|
+
require 'dragonfly/utils'
|
6
|
+
|
7
|
+
module Dragonfly
|
8
|
+
|
9
|
+
# A Dragonfly::Content object is responsible for holding
|
10
|
+
# 1. content (in the form of a data string, file, tempfile, or path)
|
11
|
+
# 2. metadata about the content (i.e. name, etc.)
|
12
|
+
# Furthermore, it belongs to a Dragonfly app, so has access to its already registered generators, processors, analysers and datastore.
|
13
|
+
# It provides convenience methods for updating its content, and though the original data may have been in the form of a String, or a Pathname, etc.
|
14
|
+
# methods like "path", "data" and "file" will always work regardless.
|
15
|
+
#
|
16
|
+
# It is acted upon in generator, processor, analyser and datastore methods and provides a standard interface for updating content,
|
17
|
+
# no matter how that content first got there (whether in the form of a String/Pathname/File/etc.)
|
18
|
+
class Content
|
19
|
+
|
20
|
+
include HasFilename
|
21
|
+
extend Forwardable
|
22
|
+
|
23
|
+
def initialize(app, obj="", meta=nil)
|
24
|
+
@app = app
|
25
|
+
@meta = {}
|
26
|
+
@previous_temp_objects = []
|
27
|
+
update(obj, meta)
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :app
|
31
|
+
def_delegators :app,
|
32
|
+
:analyser, :generator, :processor, :shell, :datastore, :env
|
33
|
+
|
34
|
+
attr_reader :temp_object
|
35
|
+
|
36
|
+
# @return [Hash]
|
37
|
+
attr_accessor :meta
|
38
|
+
|
39
|
+
# @!method data
|
40
|
+
# @return [String] the content data as a string (even if it was initialized with a file)
|
41
|
+
# @!method file
|
42
|
+
# @example
|
43
|
+
# content.file
|
44
|
+
# @example With a block (it closes the file at the end)
|
45
|
+
# content.file do |f|
|
46
|
+
# # do something with f
|
47
|
+
# end
|
48
|
+
# @return [File] the content as a readable file (even if it was initialized with data)
|
49
|
+
# @!method path
|
50
|
+
# @return [String] a file path for the content (even if it was initialized with data)
|
51
|
+
# @!method size
|
52
|
+
# @return [Fixnum] the size in bytes
|
53
|
+
# @!method to_file
|
54
|
+
# @param [String] path
|
55
|
+
# @return [File] a new file
|
56
|
+
# @!method to_tempfile
|
57
|
+
# @return [Tempfile] a new tempfile
|
58
|
+
def_delegators :temp_object,
|
59
|
+
:data, :file, :tempfile, :path, :size, :each, :to_file, :to_tempfile
|
60
|
+
|
61
|
+
# @example "beach.jpg"
|
62
|
+
# @return [String]
|
63
|
+
def name
|
64
|
+
meta["name"] || temp_object.original_filename
|
65
|
+
end
|
66
|
+
|
67
|
+
# @example
|
68
|
+
# content.name = "beach.jpg"
|
69
|
+
def name=(name)
|
70
|
+
meta["name"] = name
|
71
|
+
end
|
72
|
+
|
73
|
+
# The mime-type taken from the name's file extension
|
74
|
+
# @example "image/jpeg"
|
75
|
+
# @return [String]
|
76
|
+
def mime_type
|
77
|
+
app.mime_type_for(ext)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Set the content using a pre-registered generator
|
81
|
+
# @example
|
82
|
+
# content.generate!(:text, "some text")
|
83
|
+
# @return [Content] self
|
84
|
+
def generate!(name, *args)
|
85
|
+
app.get_generator(name).call(self, *args)
|
86
|
+
self
|
87
|
+
end
|
88
|
+
|
89
|
+
# Update the content using a pre-registered processor
|
90
|
+
# @example
|
91
|
+
# content.process!(:convert, "-resize 300x300")
|
92
|
+
# @return [Content] self
|
93
|
+
def process!(name, *args)
|
94
|
+
app.get_processor(name).call(self, *args)
|
95
|
+
self
|
96
|
+
end
|
97
|
+
|
98
|
+
# Analyse the content using a pre-registered analyser
|
99
|
+
# @example
|
100
|
+
# content.analyse(:width) # ===> 280
|
101
|
+
def analyse(name)
|
102
|
+
analyser_cache[name.to_s] ||= app.get_analyser(name).call(self)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Update the content
|
106
|
+
# @param obj [String, Pathname, Tempfile, File, Content, TempObject] can be any of these types
|
107
|
+
# @param meta [Hash] - should be json-like, i.e. contain no types other than String, Number, Boolean
|
108
|
+
# @return [Content] self
|
109
|
+
def update(obj, meta=nil)
|
110
|
+
self.temp_object = TempObject.new(obj)
|
111
|
+
original_filename = temp_object.original_filename
|
112
|
+
self.meta['name'] ||= original_filename if original_filename
|
113
|
+
self.meta.delete("analyser_cache")
|
114
|
+
add_meta(obj.meta) if obj.respond_to?(:meta)
|
115
|
+
add_meta(meta) if meta
|
116
|
+
self
|
117
|
+
end
|
118
|
+
|
119
|
+
# Add to the meta (merge)
|
120
|
+
# @param meta [Hash] - should be json-like, i.e. contain no types other than String, Number, Boolean
|
121
|
+
def add_meta(meta)
|
122
|
+
self.meta.merge!(meta)
|
123
|
+
self
|
124
|
+
end
|
125
|
+
|
126
|
+
# Analyse the content using a shell command
|
127
|
+
# @param opts [Hash] passing :escape => false doesn't shell-escape each word
|
128
|
+
# @example
|
129
|
+
# content.shell_eval do |path|
|
130
|
+
# "file --mime-type #{path}"
|
131
|
+
# end
|
132
|
+
# # ===> "beach.jpg: image/jpeg"
|
133
|
+
def shell_eval(opts={})
|
134
|
+
should_escape = opts[:escape] != false
|
135
|
+
command = yield(should_escape ? shell.quote(path) : path)
|
136
|
+
run command, :escape => should_escape
|
137
|
+
end
|
138
|
+
|
139
|
+
# Set the content using a shell command
|
140
|
+
# @param opts [Hash] :ext sets the file extension of the new path and :escape => false doesn't shell-escape each word
|
141
|
+
# @example
|
142
|
+
# content.shell_generate do |path|
|
143
|
+
# "/usr/local/bin/generate_text gumfry -o #{path}"
|
144
|
+
# end
|
145
|
+
# @return [Content] self
|
146
|
+
def shell_generate(opts={})
|
147
|
+
ext = opts[:ext] || self.ext
|
148
|
+
should_escape = opts[:escape] != false
|
149
|
+
tempfile = Utils.new_tempfile(ext)
|
150
|
+
new_path = should_escape ? shell.quote(tempfile.path) : tempfile.path
|
151
|
+
command = yield(new_path)
|
152
|
+
run(command, :escape => should_escape)
|
153
|
+
update(tempfile)
|
154
|
+
end
|
155
|
+
|
156
|
+
# Update the content using a shell command
|
157
|
+
# @param opts [Hash] :ext sets the file extension of the new path and :escape => false doesn't shell-escape each word
|
158
|
+
# @example
|
159
|
+
# content.shell_update do |old_path, new_path|
|
160
|
+
# "convert -resize 20x10 #{old_path} #{new_path}"
|
161
|
+
# end
|
162
|
+
# @return [Content] self
|
163
|
+
def shell_update(opts={})
|
164
|
+
ext = opts[:ext] || self.ext
|
165
|
+
should_escape = opts[:escape] != false
|
166
|
+
tempfile = Utils.new_tempfile(ext)
|
167
|
+
old_path = should_escape ? shell.quote(path) : path
|
168
|
+
new_path = should_escape ? shell.quote(tempfile.path) : tempfile.path
|
169
|
+
command = yield(old_path, new_path)
|
170
|
+
run(command, :escape => should_escape)
|
171
|
+
update(tempfile)
|
172
|
+
end
|
173
|
+
|
174
|
+
def store(opts={})
|
175
|
+
datastore.write(self, opts)
|
176
|
+
end
|
177
|
+
|
178
|
+
# @example
|
179
|
+
# "data:image/jpeg;base64,IGSsdhfsoi..."
|
180
|
+
# @return [String] A data url representation of the data
|
181
|
+
def b64_data
|
182
|
+
"data:#{mime_type};base64,#{Base64.encode64(data)}"
|
183
|
+
end
|
184
|
+
|
185
|
+
def close
|
186
|
+
previous_temp_objects.each{|temp_object| temp_object.close }
|
187
|
+
temp_object.close
|
188
|
+
end
|
189
|
+
|
190
|
+
def inspect
|
191
|
+
"<#{self.class.name} temp_object=#{temp_object.inspect}>"
|
192
|
+
end
|
193
|
+
|
194
|
+
private
|
195
|
+
|
196
|
+
attr_reader :previous_temp_objects
|
197
|
+
def temp_object=(temp_object)
|
198
|
+
previous_temp_objects.push(@temp_object) if @temp_object
|
199
|
+
@temp_object = temp_object
|
200
|
+
end
|
201
|
+
|
202
|
+
def analyser_cache
|
203
|
+
meta["analyser_cache"] ||= {}
|
204
|
+
end
|
205
|
+
|
206
|
+
def run(command, opts)
|
207
|
+
shell.run(command, opts)
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
end
|