Class: Configuration::Thumbnail
- Inherits:
-
HandlerStatement
- Object
- Scope
- HandlerStatement
- Configuration::Thumbnail
- Extended by:
- Stats
- Includes:
- ClassLogging, ConditionalInclusion, GlobalConfiguration, ImageName, LocalConfiguration, PerfStats
- Defined in:
- lib/httpimagestore/configuration/thumbnailer.rb
Defined Under Namespace
Classes: ThumbnailSpec, ThumbnailingError
Class Method Summary collapse
Instance Method Summary collapse
- #included?(request_state) ⇒ Boolean
-
#initialize(global, source_image_name, specs, use_multipart_api) ⇒ Thumbnail
constructor
A new instance of Thumbnail.
- #realize(request_state) ⇒ Object
Methods inherited from Scope
node_parsers, #parse, register_node_parser
Constructor Details
#initialize(global, source_image_name, specs, use_multipart_api) ⇒ Thumbnail
Returns a new instance of Thumbnail.
249 250 251 252 253 254 255 |
# File 'lib/httpimagestore/configuration/thumbnailer.rb', line 249 def initialize(global, source_image_name, specs, use_multipart_api) with_global_configuration(global) with_image_name(source_image_name) @source_image_name = source_image_name @specs = specs.freeze @use_multipart_api = use_multipart_api end |
Class Method Details
.match(node) ⇒ Object
181 182 183 |
# File 'lib/httpimagestore/configuration/thumbnailer.rb', line 181 def self.match(node) node.name == 'thumbnail' end |
.parse(configuration, node) ⇒ Object
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/httpimagestore/configuration/thumbnailer.rb', line 185 def self.parse(configuration, node) # if we don't have any subnodes use this node as single subnode and parse as if they were subnodes use_multipart_api = node.values.length == 1 ? true : false nodes = use_multipart_api ? node.children : [node] source_image_name = use_multipart_api ? node.grab_values('source image name').first : nil # parsed later general_conditions = [] if use_multipart_api general_conditions, remaining = *ConditionalInclusion.grab_conditions_with_remaining(node.attributes) remaining.empty? or raise UnexpectedAttributesError.new(node, remaining) end nodes.empty? and raise NoValueError.new(node, 'thumbnail image name') specs = nodes.map do |node| if use_multipart_api image_name = node.grab_values('thumbnail image name').first else source_image_name, image_name = *node.grab_values('source image name', 'thumbnail image name') end operation, width, height, format, remaining = *node.grab_attributes_with_remaining('operation', 'width', 'height', 'format') conditions, remaining = *ConditionalInclusion.grab_conditions_with_remaining(remaining) edits = [] # check for subnodes subnodes = node.children.group_by{|node| node.name} edit_nodes = subnodes.delete('edit') edit_nodes and edit_nodes.each.with_index do |node, edit_no| edit_conditions, = *ConditionalInclusion.grab_conditions_with_remaining(node.attributes) args = node.values.dup edit = ThumbnailSpec::EditSpec.new(args.shift, args, , edit_no) edit.with_conditions(edit_conditions) edits << edit end subnodes.keys.empty? or raise UnknownThumbnailingDirectiveError.new(source_image_name, image_name, subnodes.keys.join(' and ')) ThumbnailSpec.new( image_name, operation || 'fit', width || 'input', height || 'input', format || 'input', remaining || {}, edits ).with_conditions(conditions) end thum = self.new( configuration.global, source_image_name, specs, use_multipart_api, ) thum.with_conditions(general_conditions) configuration.processors << thum end |
Instance Method Details
#included?(request_state) ⇒ Boolean
332 333 334 335 336 337 338 339 340 341 |
# File 'lib/httpimagestore/configuration/thumbnailer.rb', line 332 def included?(request_state) # TODO this is to complicated! if @use_multipart_api super(request_state) else @specs.any? do |spec| spec.included?(request_state) end end end |
#realize(request_state) ⇒ Object
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
# File 'lib/httpimagestore/configuration/thumbnailer.rb', line 257 def realize(request_state) client = @global.thumbnailer or fail 'thumbnailer configuration' specs = @specs.select do |spec| spec.included?(request_state) end if specs.empty? # in single part form we are OK to skip the thumbnailing all thogether return if not @use_multipart_api # in multipart for at least one thumbnail spec should be selected raise NoSpecSelectedError.new(@specs.map(&:image_name)) end rendered_specs = specs.map do |spec| spec.render(request_state) end source_image = request_state.images[@source_image_name] thumbnails = {} input_mime_type = nil input_width = nil input_height = nil log.info "thumbnailing '#{@source_image_name}' to specs: #{rendered_specs.map{|s| "#{s.name} -> #{s.spec}"}.join('; ')}" Thumbnail.stats.incr_total_thumbnail_requests Thumbnail.stats.incr_total_thumbnail_requests_bytes source_image.data.bytesize thumbnails = begin measure "thumbnailing image", "'#{@source_image_name}' to specs: #{rendered_specs.map{|s| "#{s.name} -> #{s.spec}"}.join('; ')}" do client.with_headers(request_state.forward_headers).thumbnail(source_image.data, *rendered_specs.map(&:spec)) end rescue HTTPThumbnailerClient::HTTPThumbnailerClientError => error log.warn 'got thumbnailer error', error raise ThumbnailingError.new(@source_image_name, rendered_specs.length == 1 ? rendered_specs.first.name : nil, error) end input_mime_type = thumbnails.input_mime_type input_width = thumbnails.input_width input_height = thumbnails.input_height # check each thumbnail for errors thumbnails = Hash[rendered_specs.map(&:name).zip(thumbnails)] thumbnails.each do |name, thumbnail| if thumbnail.kind_of? HTTPThumbnailerClient::HTTPThumbnailerClientError error = thumbnail log.warn 'got single thumbnail error', error raise ThumbnailingError.new(@source_image_name, name, error) end end # borrow from memory limit - note that we might have already used too much memory thumbnails.each do |name, thumbnail| request_state.memory_limit.borrow(thumbnail.data.bytesize, "thumbnail '#{name}'") end # copy input source path and url thumbnails.each do |name, thumbnail| thumbnail.extend ImageMetaData thumbnail.source_path = source_image.source_path thumbnail.source_url = source_image.source_url Thumbnail.stats.incr_total_thumbnail_thumbnails Thumbnail.stats.incr_total_thumbnail_thumbnails_bytes thumbnail.data.bytesize end # use httpthumbnailer provided information on input image mime type and size source_image.mime_type = input_mime_type if input_mime_type source_image.width = input_width if input_width source_image.height = input_height if input_height request_state.images.merge! thumbnails end |