Open the default browser in Ruby - ruby

In Python, you can do this:
import webbrowser
webbrowser.open_new("http://example.com/")
It will open the passed in url in the default browser
Is there a ruby equivalent?

Cross-platform solution:
First, install the Launchy gem:
$ gem install launchy
Then, you can run this:
require 'launchy'
Launchy.open("http://stackoverflow.com")

This should work on most platforms:
link = "Insert desired link location here"
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
system "start #{link}"
elsif RbConfig::CONFIG['host_os'] =~ /darwin/
system "open #{link}"
elsif RbConfig::CONFIG['host_os'] =~ /linux|bsd/
system "xdg-open #{link}"
end

Mac-only solution:
system("open", "http://stackoverflow.com/")
or
`open http://stackoverflow.com/`

Simplest Win solution:
`start http://www.example.com`

Linux-only solution
system("xdg-open", "http://stackoverflow.com/")

This also works:
system("start #{link}")

Windows Only Solution:
require 'win32ole'
shell = WIN32OLE.new('Shell.Application')
shell.ShellExecute(...)
Shell Execute on MSDN

You can use the 'os' gem: https://github.com/rdp/os to let your operating system (in the best case you own your OS, meaning not OS X) decide what to do with an URL.
Typically this will be a good choice.
require 'os'
system(OS.open_file_command, 'https://stackoverflow.com')
# ~ like `xdg-open stackoverflow.com` on most modern unixoids,
# but should work on most other operating systems, too.
Note On windows, the argument(s?) to system need to be escaped, see comment section. There should be a function in Rubys stdlib for that, feel free to add it to the comments and I will update the answer.

If it's windows and it's IE, try this: http://rubyonwindows.blogspot.com/search/label/watir also check out Selenium ruby: http://selenium.rubyforge.org/getting-started.html
HTH

Related

Ruby/Buildr―getting user-, host and OS-name

I am looking for an robust, elegant and portable solution to get the user-, host- and osname in Ruby. I would like to create a folder structure which is set up like this:
linux/maschine1/user53, or
linux/maschine2/user53, or
windows/maschine1/user53, or
mac/supermac/superuser
the name of the user- and hostname should reflect the user#computer:~$ on a linux shell and the operating system should be divided in win, linux and mac.
I found several approaches, using the ENV['USER'/'USERNAME'], or Etc.getLogin() for the username, Socket.gethostname for the computername and the RUBY_PLATFORM constant for the os-name. But all of them have issues when running in different Plattforms like JRuby or even on different operating systems.
So which choice would be the best for each?
Thanks!
Edit:
I came to this solution a short moment before the answer was given. Since Buildr can also use Java commands it is possible to get the values like this:
os = Java.java.lang.System.getProperty('os.name')
usr = Java.java.lang.System.getProperty('user.name')
host = Java.java.net.InetAddress.getLocalHost().getHostName()
But I think I am going to use the pure ruby way to keep the language as consistent as possible.
Not sure there is really a gem that does it all, but Etc.getlogin and Socket.getshostname should work across platforms I think. I use this or variations of to get the os:
require 'rbconfig'
def os
#os ||= (
host_os = RbConfig::CONFIG['host_os']
case host_os
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
:windows
when /darwin|mac os/
:macosx
when /linux/
:linux
when /solaris|bsd/
:unix
else
raise "unknown os: #{host_os.inspect}"
end
)
end
which is ripped off from the selenium gem: https://code.google.com/p/selenium/source/browse/rb/lib/selenium/webdriver/common/platform.rb which might provide a bit more inspiration.

What is the correct way to detect if ruby is running on Windows?

What is the correct way to detect from within Ruby whether the interpreter is running on Windows? "Correct" includes that it works on all major flavors of Ruby, including 1.8.x, 1.9.x, JRuby, Rubinius, and IronRuby.
The currently top ranked Google results for "ruby detect windows" are all incorrect or outdated. For example, one incorrect way to do it is:
RUBY_PLATFORM =~ /mswin/
This is incorrect because it fails to detect the mingw version, or JRuby on Windows.
What's the right way?
It turns out, there's this way:
Gem.win_platform?
Preferred Option (Updated based on #John's recommendations):
require 'rbconfig'
is_windows = (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
This could also work, but is less reliable (it won't work with much older versions, and the environment variable can be modified)
is_windows = (ENV['OS'] == 'Windows_NT')
(I can't easily test either on all of the rubies listed, or anything but Windows 7, but I know that both will work for 1.9.x, IronRuby, and JRuby).
This works perfectly for me
Also etc does not need to be installed, it comes with ruby.
require "etc"
def check_system
return "windows" if Etc.uname[:sysname] == "Windows_NT"
return "linux" if Etc.uname[:sysname] == "Linux"
end
(File::ALT_SEPARATOR || File::SEPARATOR) == '\\'

Unicode filenames on Windows in Ruby

I have a piece of code that looks like this:
Dir.new(path).each do |entry|
puts entry
end
The problem comes when I have a file named こんにちは世界.txt in the directory that I list.
On a Windows 7 machine I get the output:
???????.txt
From googling around, properly reading this filename on windows seems to be an impossible task. Any suggestions?
I had the same problem & just figured out how to get the entries of a directory in UTF-8 in Windows. The following worked for me (using Ruby 1.9.2p136):
opts = {}
opts[:encoding] = "UTF-8"
entries = Dir.entries(path, opts)
entries.each do |entry|
# example
stat = File::stat(entry)
puts "Size: " + String(stat.size)
end
You're out of luck with pure ruby (either 1.8 or 1.9.1) since it uses the ANSI versions of the Windows API.
It seems like Ruby 1.9.2 will support Unicode filenames on Windows. This bug report has 1.9.2 as target. According to this announcement Ruby 1.9.2 will be released at the end of July 2010.
If you really need it earlier you could try to use FindFirstFileW etc. directly via Win32API.new or win32-api.
My solution was to use Dir.glob instead of Dir.entries. But it only works with * parameter. It does not work when passing a path (c:/dir/*). Tested in 1.9.2p290 and 1.9.3p0 on Windows 7.
There are many other issues with unicode paths on Windows. It is still an open issue. The patches are currently targeted at Ruby 2.0, which is rumored to be released in 2013.

How to enable auto completion in Ruby's IRB

When I use Merb's built in console, I get tab auto-completion similar to a standard bash prompt. I find this useful and would like to enable it in non-merb IRB sessions. How do I get auto-completion in IRB?
Just drop require 'irb/completion' in your irbrc.
If that doesn't work try bond, http://tagaholic.me/bond/:
require 'bond'; require 'bond/completion'
Bond not only improves irb's completion, http://tagaholic.me/2009/07/22/better-irb-completion-with-bond.html, but also offers an easy dsl for making custom autocompletions.
This is just repeating the information on Cody Caughlan's comment above so it is easier to find:
either require 'irb/completion' or add the following to ~/.irbrc
IRB.conf[:AUTO_INDENT] = true
IRB.conf[:USE_READLINE] = true
IRB.conf[:LOAD_MODULES] = [] unless IRB.conf.key?(:LOAD_MODULES)
unless IRB.conf[:LOAD_MODULES].include?('irb/completion')
IRB.conf[:LOAD_MODULES] << 'irb/completion'
end
This is what worked for me on Mac OS 10.11.5. using rvm. Do the following :
sudo gem install bond
Create the file .irbrc in your home directory. vi ~/.irbrc
Add the following lines in the .irbrc file
require 'bond'
Bond.start
Save and close the file
Open irb and use tab key to autocomplete

Determine file type in Ruby

How does one reliably determine a file's type? File extension analysis is not acceptable. There must be a rubyesque tool similar to the UNIX file(1) command?
This is regarding MIME or content type, not file system classifications, such as directory, file, or socket.
There is a ruby binding to libmagic that does what you need. It is available as a gem named ruby-filemagic:
gem install ruby-filemagic
Require libmagic-dev.
The documentation seems a little thin, but this should get you started:
$ irb
irb(main):001:0> require 'filemagic'
=> true
irb(main):002:0> fm = FileMagic.new
=> #<FileMagic:0x7fd4afb0>
irb(main):003:0> fm.file('foo.zip')
=> "Zip archive data, at least v2.0 to extract"
irb(main):004:0>
If you're on a Unix machine try this:
mimetype = `file -Ib #{path}`.gsub(/\n/,"")
I'm not aware of any pure Ruby solutions that work as reliably as 'file'.
Edited to add: depending what OS you are running you may need to use 'i' instead of 'I' to get file to return a mime-type.
I found shelling out to be the most reliable. For compatibility on both Mac OS X and Ubuntu Linux I used:
file --mime -b myvideo.mp4
video/mp4; charset=binary
Ubuntu also prints video codec information if it can which is pretty cool:
file -b myvideo.mp4
ISO Media, MPEG v4 system, version 2
You can use this reliable method base on the magic header of the file :
def get_image_extension(local_file_path)
png = Regexp.new("\x89PNG".force_encoding("binary"))
jpg = Regexp.new("\xff\xd8\xff\xe0\x00\x10JFIF".force_encoding("binary"))
jpg2 = Regexp.new("\xff\xd8\xff\xe1(.*){2}Exif".force_encoding("binary"))
case IO.read(local_file_path, 10)
when /^GIF8/
'gif'
when /^#{png}/
'png'
when /^#{jpg}/
'jpg'
when /^#{jpg2}/
'jpg'
else
mime_type = `file #{local_file_path} --mime-type`.gsub("\n", '') # Works on linux and mac
raise UnprocessableEntity, "unknown file type" if !mime_type
mime_type.split(':')[1].split('/')[1].gsub('x-', '').gsub(/jpeg/, 'jpg').gsub(/text/, 'txt').gsub(/x-/, '')
end
end
This was added as a comment on this answer but should really be its own answer:
path = # path to your file
IO.popen(
["file", "--brief", "--mime-type", path],
in: :close, err: :close
) { |io| io.read.chomp }
I can confirm that it worked for me.
If you're using the File class, you can augment it with the following functions based on #PatrickRichie's answer:
class File
def mime_type
`file --brief --mime-type #{self.path}`.strip
end
def charset
`file --brief --mime #{self.path}`.split(';').second.split('=').second.strip
end
end
And, if you're using Ruby on Rails, you can drop this into config/initializers/file.rb and have available throughout your project.
For those who came here by the search engine, a modern approach to find the MimeType in pure ruby is to use the mimemagic gem.
require 'mimemagic'
MimeMagic.by_magic(File.open('tux.jpg')).type # => "image/jpeg"
If you feel that is safe to use only the file extension, then you can use the mime-types gem:
MIME::Types.type_for('tux.jpg') => [#<MIME::Type: image/jpeg>]
You could give shared-mime a try (gem install shared-mime-info). Requires the use ofthe Freedesktop shared-mime-info library, but does both filename/extension checks as well as "magic" checks... tried giving it a whirl myself just now but I don't have the freedesktop shared-mime-info database installed and have to do "real work," unfortunately, but it might be what you're looking for.
Pure Ruby solution using magic bytes and returning a symbol for the matching type:
https://github.com/SixArm/sixarm_ruby_magic_number_type
I wrote it, so if you have suggestions, let me know.
I recently found mimetype-fu.
It seems to be the easiest reliable solution to get a file's MIME type.
The only caveat is that on a Windows machine it only uses the file extension, whereas on *Nix based systems it works great.
The best I found so far:
http://bogomips.org/mahoro.git/
The ruby gem is well.
mime-types for ruby
You could give a go with MIME::Types for Ruby.
This library allows for the identification of a file’s likely MIME content type. The identification of MIME content type is based on a file’s filename extensions.

Resources