class Levdon::LevdonImpl
Public Class Methods
new()
click to toggle source
def LevdonImpl.dealloc(workers)
proc {|id| begin workers.each(&:stop) workers = nil rescue => e # nothing to do end }
end
# File lib/levdon.rb, line 553 def initialize() @access_token = "DUMMY" @blocks = {} @timeout = 10.0 # default 10sec @request_cluster_num = 1 # prediction parameters @ontologies = [:CLASS_ADULT] end
Public Instance Methods
_predict_impl(parameter)
click to toggle source
# File lib/levdon.rb, line 563 def _predict_impl(parameter) ret = nil error = nil f = parameter[:target] request_id = parameter[:request_id] ontologies = parameter[:ontologies] access_token = parameter[:access_token] url = URI.parse(API_URL) options = {} options['ontologies'] = [] error = "Class is not specified." if ontologies.length == 0 ontologies.each{|key| obj = ONTOLOGY_LIST[key] unless obj error = "Invalid key => " + key.to_s break end unless obj[:available] error = key.to_s + " class is not available.\n Reason => #{obj[:desc]}" break end options['ontologies'] += [obj[:key]] } if(!error) stream = load(f) if(stream) io = nil begin io = StringIO.new(Levdon.prob_resize(stream)) req = Net::HTTP::Post::Multipart.new url.path, "api_version" => API_VERSION, "upload" => UploadIO.new(io, "image/jpeg", "image.jpg"), "request_id" => request_id, "access_token" => access_token, "constant_id" => APPLICATION_ID, "options" => JSON.generate(options) n = Net::HTTP.new(url.host, url.port) n.use_ssl = ENABLE_SSL res = n.start {|http| http.request(req) } j = JSON.parse(res.body) if(res.code == '200' and j['results']) # TODO: data struct problem ret = {} j['results'].each{|k,v| ret[ONTOLOGY_REV_LIST[k]] = v } else ret = nil error = j['desc'] end rescue => e error = "" error += e.class.to_s + "\n" error += e.message.to_s + "\n" error += e.backtrace.to_s + "\n" ensure if(io) begin io.close() rescue IOError # nothing to do rescue => e error = "" error += e.class.to_s + "\n" error += e.message.to_s + "\n" error += e.backtrace.to_s + "\n" end end end else error = "Could not read a '#{f.to_s}'." end end return {:error=>error,:result=>ret} end
async_predict(parameter,&block)
click to toggle source
# File lib/levdon.rb, line 822 def async_predict(parameter,&block) raise "expected key: request_id" if(parameter[:request_id]) raise "expected key: ontologies" if(parameter[:ontologies]) raise "required key: target. Specify a file path or URL or data." unless(parameter[:target]) parameter[:request_id] = SecureRandom.uuid.gsub("-","") parameter[:ontologies] = @ontologies enqueue(parameter) @blocks[VUUID+parameter[:request_id]] = block end
async_start(access_token,&block)
click to toggle source
# File lib/levdon.rb, line 644 def async_start(access_token,&block) @access_token = access_token @workers = @request_cluster_num.times.map{ Worker.new{|*args| ret = nil error = nil begin parameter = args[0] parameter[:access_token] = access_token obj = _predict_impl(parameter) ret = obj[:result] error = obj[:error] rescue => e error = "" error += e.class.to_s + "\n" error += e.message.to_s + "\n" error += e.backtrace.to_s + "\n" end {:results => ret, :error => error} } } @workers.map(&:run).each(&:join) @roundrobin_counter = 0 @task_stacking_counter = [] @workers.length.times{|i| @task_stacking_counter.push([i,0]) } #ObjectSpace.define_finalizer(self,LevdonImpl.dealloc(@workers)) # CTRL + C Signal.trap(:INT) { puts "Stop " + APPLICATION_ID + " clients " close() exit(0) } block.call({:error => nil}) end
close()
click to toggle source
# File lib/levdon.rb, line 835 def close begin @workers.each(&:stop) rescue => e # nothing to do end end
detect_content_type(ouri)
click to toggle source
# File lib/levdon.rb, line 700 def detect_content_type(ouri) if(ouri) if(ouri.respond_to?(:content_type)) ct = ouri.content_type if(ct) if(ct.index('image')) return 'image' elsif(ct.index('video')) return 'video' end end else return 'file' end end return nil end
detect_image_or_video_from_path(path)
click to toggle source
# File lib/levdon.rb, line 718 def detect_image_or_video_from_path(path) ext = File.extname(path).downcase if(ext == ".jpeg" || ext == ".png" || ext == ".gif" || ext == ".jpg" || ext == ".tiff" || ext == ".tif" || ext == ".psd" || ext == ".pdf") return "image" elsif(ext == ".mp4" || ext == ".avi" || ext == ".mov" || ext == ".3gp" || ext == ".flv" || ext == ".wmv") return "video" end return nil end
enqueue(*args)
click to toggle source
# File lib/levdon.rb, line 812 def enqueue(*args) target = @task_stacking_counter.sort{|a,b| a[1]-b[1]}[0][0] @task_stacking_counter[target][1] += 1 #target = @roundrobin_counter % @workers.length #@roundrobin_counter += 1 worker = @workers[target] worker.async_execute(*args) end
generate_thumb_from_video(f)
click to toggle source
# File lib/levdon.rb, line 728 def generate_thumb_from_video(f) thumb_url = "tmp"+Process.pid.to_s movie = FFMPEG::Movie.new(f) duration = (movie.duration / 2).floor path = "#{thumb_url}.jpg" movie.screenshot(path, seek_time: duration) data = File.open(path).read() File.delete(path) return data end
load(any)
click to toggle source
# File lib/levdon.rb, line 749 def load(any) if(any.class.name == "String") if(any.index("http://") == 0 or any.index("https://") == 0) # from network ouri = open(any) ct = detect_content_type(ouri) new_data = nil if(ct == "video") new_data = generate_thumb_from_video(ouri.path) elsif(ct == "image") new_data = ouri.read end return new_data else if File::ftype(any) == "file" ct = detect_image_or_video_from_path(any) if(ct == "video") return generate_thumb_from_video(any) elsif(ct == "image") return File.open(any).read end puts "Invalid media file." return nil elsif(File::ftype(any) == "directory") puts "Can't load a directory. Target should be a file or URL." return nil else # from memory return any end end else # from memory return any end return nil end
option(obj)
click to toggle source
# File lib/levdon.rb, line 688 def option(obj) obj.each{|k,v| if(k == :CLASS) @ontologies = v elsif(k == :PARALLEL) @request_cluster_num = v else puts "Invalid option : " + k.to_s end } end
poll()
click to toggle source
# File lib/levdon.rb, line 787 def poll @workers.each(&:poll) @workers.map(&:nonblock_read_from_child).each_with_index{|ret,i| begin if(ret) request_id = ret[:parameter][:request_id] key = VUUID + request_id if(@blocks.has_key?(key)) @task_stacking_counter[i][1] -= 1 @blocks[key].call(ret) @blocks.delete(key) else puts "Error" puts "Invalid response from server." end end rescue => e puts "Response error" puts e.class puts e.message puts e.backtrace end } end
predict(parameter)
click to toggle source
# File lib/levdon.rb, line 843 def predict(parameter) if(parameter.class.name == "String") parameter = {:target => parameter } elsif(parameter.class.name == "Hash") raise "expected key: request_id" if(parameter[:request_id]) raise "expected key: ontologies" if(parameter[:ontologies]) raise "required key: target. Specify a file path or URL or data." unless(parameter[:target]) else raise "Invalid parameter type" end parameter[:request_id] = SecureRandom.uuid.gsub("-","") parameter[:ontologies] = @ontologies parameter[:access_token] = @access_token ret = nil error = nil begin obj = _predict_impl(parameter) ret = obj[:result] error = obj[:error] rescue => e error = "" error += e.class.to_s + "\n" error += e.message.to_s + "\n" error += e.backtrace.to_s + "\n" end return {:results => ret, :error => error} end
queue_size()
click to toggle source
# File lib/levdon.rb, line 831 def queue_size @blocks.length end
start(access_token)
click to toggle source
# File lib/levdon.rb, line 683 def start(access_token) @access_token = access_token return {:erorr => nil} end
to_image(fname,ct)
click to toggle source
# File lib/levdon.rb, line 739 def to_image(fname,ct) if(ct == "video") return generate_thumb_from_video(fname) elsif(ct == "image") return File.open(fname).read end puts "Invalid media stream." return nil end