lib/flammarion/revelator.rb in flammarion-0.1.1 vs lib/flammarion/revelator.rb in flammarion-0.1.2

- old
+ new

@@ -1,5 +1,9 @@ +require 'ostruct' +require 'launchy' +require 'timeout' + module Flammarion # Raised when flammarion cannot find any way to display an engraving. # On Linux, Flammarion will first try to launch Electron using the command # +electron+. If that fails, it will try common aliases of Google Chrome. If # none of them execute succesfully, it will raise this error. On Windows, it @@ -12,43 +16,86 @@ # @api private # @todo This all needs a lot of clean up module Revelator CHROME_PATH = ENV["FLAMMARION_REVELATOR_PATH"] || 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe' - def open_a_window_on_windows(options) + + def open_a_window(options = {}) + if RbConfig::CONFIG["host_os"] =~ /cygwin|mswin|mingw/ + development_mode = ENV["FLAMMARION_DEVELOPMENT"] == "true" + else + development_mode = system("lsof -i:#{4567}", out: '/dev/null') and File.exist?("#{File.dirname(__FILE__)}/../html/source/index.html.slim") + end + host = "file://#{File.dirname(File.absolute_path(__FILE__))}/../html/build/index.html" + host = "http://localhost:4567/" if development_mode + + @expect_title = options[:title] || "Flammarion-#{rand.to_s[2..-1]}" + url = "#{host}?path=#{@window_id}&port=#{server.port}&title=#{@expect_title}" + @browser_options = options.merge({url: url, development_mode: development_mode}) + @requested_browser = ENV["FLAMMARION_BROWSER"] || options[:browser] + + @browser = @@browsers.find do |browser| + next if @requested_browser and browser.name.to_s != @requested_browser + begin + __send__(browser.name, @browser_options) + rescue Exception + next + end + end + + raise SetupError.new("You must have either electron or google-chrome installed and accesible via your path.") unless @browser + end + + # @api private + def wait_for_a_connection + Timeout.timeout(20) { sleep 0.5 while @sockets.empty? } + rescue Timeout::Error + raise SetupError.new("Timed out while waiting for a connecting using #{@browser.name}.") + end + + private + @@browsers = [] + def self.browser(name, &block) + @@browsers << OpenStruct.new(name: name, method:define_method(name, block)) + end + + browser :chrome_windows do |options| + return false unless RbConfig::CONFIG["host_os"] =~ /cygwin|mswin|mingw/ file_path = File.absolute_path(File.join(File.dirname(__FILE__), "..")) file_path = `cygpath -w '#{file_path}'`.strip if RbConfig::CONFIG["host_os"] == "cygwin" resource = %[file\://#{file_path}/html/build/index.html] - resource = "http://localhost:4567/" if ENV["FLAMMARION_DEVELOPMENT"] == "true" + resource = "http://localhost:4567/" if options[:development_mode] chrome_path = CHROME_PATH chrome_path = `cygpath -u '#{CHROME_PATH}'`.strip if RbConfig::CONFIG["host_os"] == "cygwin" - raise SetupError.new("Cannot find #{chrome_path}. You need to install Google Chrome or set the environment variable FLAMMARION_REVELATOR_PATH to point to chrome.exe") unless File.exist?(chrome_path) + return false unless File.exist?(chrome_path) Process.detach(spawn(chrome_path, %[--app=#{resource}?path=#{@window_id}&port=#{server.port}&title="#{options[:title] || "Flammarion%20Engraving"}"])) end - def open_a_window(options = {}) - return open_a_window_on_windows(options) if RbConfig::CONFIG["host_os"] =~ /cygwin|mswin|mingw/ - developmentMode = system("lsof -i:#{4567}", out: '/dev/null') and File.exist?("#{File.dirname(__FILE__)}/../html/source/index.html.slim") - host = "file://#{File.dirname(File.absolute_path(__FILE__))}/../html/build/index.html" - host = "http://localhost:4567/" if developmentMode - - @expect_title = options[:title] || "Flammarion-#{rand.to_s[2..-1]}" - + browser :electron do |options| if which('electron') then - Process.detach(spawn("electron #{File.dirname(File.absolute_path(__FILE__))}/../../electron '#{host}?path=#{@window_id}&port=#{server.port}&title=#{@expect_title}'")) - return + Process.detach(spawn("electron #{File.dirname(File.absolute_path(__FILE__))}/../../electron '#{options[:url]}'")) + return true end + false + end + browser :chrome do |options| %w[google-chrome google-chrome-stable chromium chromium-browser chrome].each do |executable| next unless which(executable) - @chrome.in, @chrome.out, @chrome.err, @chrome.thread = Open3.popen3("#{executable} --app='#{host}?path=#{@window_id}&port=#{server.port}&title=#{@expect_title}'") - break if @chrome.in + @chrome.in, @chrome.out, @chrome.err, @chrome.thread = Open3.popen3("#{executable} --app='#{options[:url]}'") + return true if @chrome.in end + return false + end - raise SetupError.new("You must have either electron or google-chrome installed and accesible via your path.") unless @chrome.in + browser :www do |options| + # Last ditch effort to display something + Launchy.open(options[:url].gsub(/\s/, "%20")) do |error| + return false + end + return true end - private def which(cmd) exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : [''] ENV['PATH'].split(File::PATH_SEPARATOR).each do |path| exts.each do |ext| exe = File.join(path, "#{cmd}#{ext}")