lib/kanoko/application/convert.rb in kanoko-0.2.0 vs lib/kanoko/application/convert.rb in kanoko-0.3.0

- old
+ new

@@ -1,9 +1,10 @@ require 'sinatra' require 'net/http' require 'tempfile' require 'kanoko' +require 'mime/types' # This is an experimental implementation. # You can set configure and other. # This application receve url make by Kanoko.url_for(). # You can choice function that image processing. @@ -31,10 +32,22 @@ module Kanoko module Application class Convert < Sinatra::Application require 'kanoko/application/convert/function' + IMAGE_TYPES = MIME::Types.select do |m| + m.media_type == 'image' + end + TYPE_MAP = IMAGE_TYPES.map { |i| + [i.to_s, i.preferred_extension] + }.to_h + EXT_MAP = IMAGE_TYPES.each_with_object({}) do |i, h| + i.extensions.each do |ext| + h[ext] = i.to_s + end + end + # /123abc456def=/resize/200x200/crop/100x100/path/to/src get '/:hash/*' do # REQUEST_URI dependent on unicorn. # request.path should be use only testing raw_request_uri = env["REQUEST_URI"] || request.path @@ -46,26 +59,29 @@ end list = Kanoko::Application::Convert::Function.list convert_options = [] arguments = [] - + to_ext = File.extname(request_params.last)[1..-1] while id = request_params.shift.to_sym - if list.include?(id) + if id == :to + to_ext = request_params.shift + arguments << id << to_ext + elsif list.include?(id) arguments << id method = Function.new.method(id) arg = request_params.shift(method.arity) - arg.map!{|i| URI.decode_www_form_component i} + arg.map! { |i| URI.decode_www_form_component i } arguments.concat arg if 0 < arg.length convert_options.concat method.call(*arg) else request_params.unshift(id.to_s) break end end - check_path = request_params.map{ |i| URI.decode_www_form_component(i) }.join('/') + check_path = request_params.map { |i| URI.decode_www_form_component(i) }.join('/') unless hash == Kanoko.make_hash(*arguments, check_path) logger.error "hash check failed #{[*arguments, check_path]}" return 400 end @@ -78,25 +94,38 @@ Tempfile.create("src") do |src_file| src_file.write res.body src_file.fdatasync - Tempfile.create("dst") do |dst_file| + t = TYPE_MAP[res.content_type] + src_type = if t + "#{t}:" + else + "" + end + + dst_name = if to_ext.nil? + "dst" + else + ["dst", ".#{to_ext}"] + end + Tempfile.create(dst_name) do |dst_file| system_command = [ - {"OMP_NUM_THREADS" => "1"}, + { "OMP_NUM_THREADS" => "1" }, 'convert', '-depth', '8', convert_options, - src_file.path, - dst_file.path + "#{src_type}#{src_file.path}", + dst_file.path, ].flatten result = system *system_command unless result - logger.error "command fail $?=#{$?.inspect}" + logger.error "command fail $?=#{$CHILD_STATUS.inspect}" return 500 end + content_type EXT_MAP[to_ext] dst_file.read end end end