Simple Screen Grabber in Ruby, Selenium Webdriver throws Errors - ruby

I`m having problem with implementing a simple screen grabber.
The basic script is below:
require 'selenium-webdriver'
width = 1024
height = 728
#websites = Array.new
file = open('websites.txt')
file.each_line { |line| #websites.push line }
#websites.each do |website|
d = Selenium::WebDriver.for :firefox
puts "Now going to:"+ " #{website}"
d.navigate.to website
d.execute_script %Q{
window.resizeTo(#{width}, #{height});
}
d.save_screenshot("#{website.gsub('http://', '')}"+".png")
d.quit
sleep 10
end
The exception that selenium throws:
ruby keepwatch.rb
Now going to: http://www.example.com/
/Users/Big_Bird/.rvm/gems/ruby-1.9.2-p320/gems/selenium-webdriver-2.31.0/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb:18:in `initialize': No such file or directory - www.example.com/ (Errno::ENOENT)
.png
from /Users/Big_Bird/.rvm/gems/ruby-1.9.2-p320/gems/selenium-webdriver-2.31.0/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb:18:in `open'
from /Users/Big_Bird/.rvm/gems/ruby-1.9.2-p320/gems/selenium-webdriver-2.31.0/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb:18:in `save_screenshot'
from keepwatch.rb:29:in `block in <main>'
from keepwatch.rb:22:in `each'
from keepwatch.rb:22:in `<main>'
I'll appreciate any help I can get on this matter.

Try to add path to file and remove / from the end (www.example.com/). If that does not work, try removing all points except the point between the file name and extension.
For example - d.save_screenshot("./screenshot.png")

Related

Getting "Unknown file type" in ruby

here's my code:
> !#usr/bin/ruby
require 'fileutils'
Dir.chdir "/home/john/Documents"
if (Dir.exist?("Photoshoot") === false) then
Dir.mkdir "Photoshoot"
puts "Directory: 'Photoshoot' created"
end
Dir.chdir "/run/user/1000/gvfs"
camdirs = Dir.glob('*')
numcams = camdirs.length
camnum = 0
campath = []
while camnum < numcams do
campath.push("/run/user/1000/gvfs/#{camdirs[camnum]}/DCIM")
puts campath[camnum]
camnum += 1
end
campath.each do |path|
Dir.chdir (path)
foldnum = 0
foldir = Dir.glob('*')
puts foldir
Dir.entries("#{path}/#{foldir[foldnum]}").each do |filename|
filetype = File.extname(filename)
if filetype == ".JPG"
FileUtils.mv("#{path}/#{foldir[foldnum]}/#{filename}", "/home/john/Documents/Photoshoot")
end
foldnum += 1
end
end
puts "#{numcams} cameras detected"
I'm just trying to go into some cameras I have connected and extract all the images into a file but its giving me this error. One of the things that's messing me up is that the images are stored in sub-folders under DCIM. When I just use .entries it gives me the folders the images are in as well as the images.
/usr/lib/ruby/2.3.0/fileutils.rb:1387:in `copy': unknown file type: /run/user/1000/gvfs/gphoto2:host=%5Busb%3A002%2C021%5D/DCIM//IMG_0092.JPG (RuntimeError)
from /usr/lib/ruby/2.3.0/fileutils.rb:472:in `block in copy_entry'
from /usr/lib/ruby/2.3.0/fileutils.rb:1498:in `wrap_traverse'
from /usr/lib/ruby/2.3.0/fileutils.rb:469:in `copy_entry'
from /usr/lib/ruby/2.3.0/fileutils.rb:530:in `rescue in block in mv'
from /usr/lib/ruby/2.3.0/fileutils.rb:527:in `block in mv'
from /usr/lib/ruby/2.3.0/fileutils.rb:1571:in `block in fu_each_src_dest'
from /usr/lib/ruby/2.3.0/fileutils.rb:1585:in `fu_each_src_dest0'
from /usr/lib/ruby/2.3.0/fileutils.rb:1569:in `fu_each_src_dest'
from /usr/lib/ruby/2.3.0/fileutils.rb:517:in `mv'
from /home/john/Desktop/TestExtract.rb:34:in `block (2 levels) in <main>'
from /home/john/Desktop/TestExtract.rb:31:in `each'
from /home/john/Desktop/TestExtract.rb:31:in `block in <main>'
from /home/john/Desktop/TestExtract.rb:26:in `each'
from /home/john/Desktop/TestExtract.rb:26:in `<main>'
/run/user/1000/gvfs/gphoto2:host=%5Busb%3A002%2C022%5D/DCIM
/run/user/1000/gvfs/gphoto2:host=%5Busb%3A002%2C021%5D/DCIM
/run/user/1000/gvfs/gphoto2:host=%5Busb%3A002%2C020%5D/DCIM
104___03
105___04
106___05
102___01
[Finished in 0.1s with exit code 1]
[shell_cmd: ruby "/home/john/Desktop/TestExtract.rb"]
[dir: /home/john/Desktop]
[path: /home/john/bin:/home/john/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin]
Any advice? I can't figure out what's wrong.
The reason the path to your files looks strange is because your camera storage has been mounted using FUSE. If you look very closely, you'll see that it is looking for:
/run/user/1000/gvfs/gphoto2:host=%5Busb%3A002%2C021%5D/DCIM//IMG_0092.JPG
You have two forward slashes before the final filename. Try correcting this on line 34 of your app.
If the problem still manifests then it is possible that the user running the operation in Ruby does not have permission to that filesystem or the manner in which the paths are constructed by FUSE is not compatible with Ruby FileUtils.
You can try to run:
cat /run/user/1000/gvfs/gphoto2:host=%5Busb%3A002%2C021%5D/DCIM/IMG_0092.JPG
as the same user that is running the Ruby process to ensure you have read permission to the filesystem.

Zlib::BufError when using progressbar/ruby-progressbar gem

I use the following Ruby snippet to download a 8.9MB file.
require 'open-uri'
require 'net/http'
require 'uri'
def http_download_no_progress_bar(uri, filename)
uri.open(read_timeout: 500) do |file|
open filename, 'w' do |io|
file.each_line do |line|
io.write line
end
end
end
end
I want to add the progressbar gem to visualize the download process:
require 'open-uri'
require 'progressbar'
require 'net/http'
require 'uri'
def http_download_with_progressbar(uri, filename)
progressbar = nil
uri.open(
read_timeout: 500,
content_length_proc: lambda { |total|
if total && 0 < total.to_i
progressbar = ProgressBar.new("...", total)
progressbar.file_transfer_mode
end
},
progress_proc: lambda { |step|
progressbar.set step if progressbar
}
) do |file|
open filename, 'w' do |io|
file.each_line do |line|
io.write line
end
end
end
end
However, it now fails with the following error:
/home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http/response.rb:357:in `finish':
buffer error (Zlib::BufError)oooooo | 8.0MB 8.6MB/s ETA: 0:00:00
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http/response.rb:357:in `finish'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http/response.rb:262:in `ensure in inflater'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http/response.rb:262:in `inflater'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http/response.rb:274:in `read_body_0'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http/response.rb:201:in `read_body'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/open-uri.rb:328:in `block (2 levels) in open_http'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http.rb:1415:in `block (2 levels) in transport_request'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http/response.rb:162:in `reading_body'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http.rb:1414:in `block in transport_request'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http.rb:1405:in `catch'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http.rb:1405:in `transport_request'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http.rb:1378:in `request'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/open-uri.rb:319:in `block in open_http'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/net/http.rb:853:in `start'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/open-uri.rb:313:in `open_http'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/open-uri.rb:724:in `buffer_open'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/open-uri.rb:210:in `block in open_loop'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/open-uri.rb:208:in `catch'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/open-uri.rb:208:in `open_loop'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/open-uri.rb:149:in `open_uri'
from /home/user/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/open-uri.rb:704:in `open'
Meanwhile I also tried the ruby-progressbar gem:
require 'open-uri'
require 'ruby-progressbar'
require 'net/http'
require 'uri'
def http_download_with_ruby_progressbar(uri, filename)
progressbar = nil
uri.open(
read_timeout: 500,
content_length_proc: lambda { |total|
if total && 0 < total.to_i
progressbar = ProgressBar.create(title: filename, total: total)
end
},
progress_proc: lambda { |step|
progressbar.progress = step if progressbar
}
) do |file|
open filename, 'w' do |io|
file.each_line do |line|
io.write line
end
end
end
end
It fails with the same error. Here is the associated issue for the problem.
The problem is the file you are trying to download as every method works with this file: https://androidnetworktester.googlecode.com/files/1mb.txt.
The problem is that your file is larger than it says it is. The content_length_proc says that it is 8549968 bytes (8.15MB) whereas it is 101187668 bytes (96.5MB) (check with ls after downloading the file). Now I have an alternative that does not crash and gives you a progressbar:
def http_download_with_words(uri, filename)
bytes_total = nil
uri.open(
read_timeout: 500,
:content_length_proc => lambda{|content_length|
bytes_total = content_length},
:progress_proc => lambda{|bytes_transferred|
if bytes_total
# Print progress
print("\r#{bytes_transferred}/#{bytes_total}")
else
# We don’t know how much we get, so just print number
# of transferred bytes
print("\r#{bytes_transferred} (total size unknown)")
end
}
) do |file|
open filename, 'w' do |io|
file.each_line do |line|
io.write line
end
end
end
end
http_download_with_words(URI( 'http://data.wien.gv.at/daten/geo?service=WFS&request=GetFeature&version=1.1.0&typeName=ogdwien%3aBAUMOGD&srsName=EPSG:4326' ), 'temp.txt')
which is pretty self-explanatory, (seen here.)
Now the part I haven't been able to figure out is how exactly the progressbar gem is interfering with the ZLib. Most things seem to work fine inside the procs (e.g. having them print random stuff) so I assume both of these progressbars do something odd on completion that somehow messes with the transfer. I'd be very interested if anyone can figure out why that is?
In my testing when this occurred it was due to the raise in #set. As for why it results in an error in Zlib, that's not clear. Perhaps some strange exception handling in there. In my case I did "progbar.set(count) rescue nil" to get rid of the issue.

Cannot load data file in Sinatra

I created the following parser:
require "./artist"
require "./song"
require "./genre"
require "debugger"
class Parser
attr_accessor :artists, :genres, :song
attr_reader :mp3
REGEX = /(?<artist>.*)\s\-\s(?<song>.*)\s\[(?<genre>.*)\]/
def initialize(directory="data")
debugger
#mp3 = Dir.entries(directory).select {|f| !File.directory? f}
debugger
end
def parse
#mp3.map do |file|
match = REGEX.match(file)
artist = Artist.find_by_name(match[:artist]) || Artist.new.tap {|artist| artist.name = match[:artist]}
song = Song.new
song.name = match[:song]
song.genre = Genre.find_by_name(match[:genre]) || Genre.new.tap {|genre| genre.name = match[:genre]}
#debugger
artist.add_song(song)
end
end
end
a = Parser.new.parse
I tried running it by calling parser.rb in the directory, lib, where it is located. I get the following error messages:
Parser.rb:47:in `open': No such file or directory - data (Errno::ENOENT)
from parser.rb:47:in `entries'
from parser.rb:47:in `initialize'
from parser.rb:68:in `new'
from parser.rb:68:in `<main>'
This is my file structure:
Can anyone please tell me why it cannot recognize my data directory? I have been staring for a while now and cannot figure it out. It was working like 10 mins ago and I cannot remember what I change to get it all messed up.
Appreciate your feedback! Thanks
You should be able to run your example like ruby -I/lib lib/parser.rb from the directory above lib. The -I will set the "include path", such that the ruby interpreter will find the other required ruby files like (lib/)song.rb.

`block in non_options': file not found: (ArgumentError)

I'm trying to open browser url based on argument passed to script. Hence I wrote following ruby code:
require 'selenium-webdriver'
require 'test/unit'
class TestTitle < Test::Unit::TestCase
def setup
$driver = Selenium::WebDriver.for :firefox
if ARGV[0] == 'google'
$driver.get 'http://www.google.com'
elsif ARGV[0] == 'twitter'
$driver.get 'http://www.twitter.com'
end
end
def test_title
puts $driver.title
end
def teardown
$driver.quit
end
end
When I passed argument: ruby test.rb 'google', it results into following error:
c:/Ruby193/lib/ruby/1.9.1/test/unit.rb:167:in `block in non_options': file not found: google (ArgumentError)
from c:/Ruby193/lib/ruby/1.9.1/test/unit.rb:146:in `map!'
from c:/Ruby193/lib/ruby/1.9.1/test/unit.rb:146:in `non_options'
from c:/Ruby193/lib/ruby/1.9.1/test/unit.rb:207:in `non_options'
from c:/Ruby193/lib/ruby/1.9.1/test/unit.rb:52:in `process_args'
from c:/Ruby193/lib/ruby/1.9.1/minitest/unit.rb:891:in `_run'
from c:/Ruby193/lib/ruby/1.9.1/minitest/unit.rb:884:in `run'
from c:/Ruby193/lib/ruby/1.9.1/test/unit.rb:21:in `run'
from c:/Ruby193/lib/ruby/1.9.1/test/unit.rb:326:in `block (2 levels) in autorun'
from c:/Ruby193/lib/ruby/1.9.1/test/unit.rb:27:in `run_once'
from c:/Ruby193/lib/ruby/1.9.1/test/unit.rb:325:in `block in autorun'
Please help me understand what I'm doing wrong.
It appears that test-unit (as of 1.9.1) grabs command line options in its GlobOptions module. You are using ARGV[0] to pass browser name, but it thinks you're passing a file name. A workaround is to capture the value of ARGV[0] and then clear it before your test case runs:
browser = ARGV[0]
ARGV[0] = nil

error related to REXML

I'm not sure it's REXML or ruby issue.
But this is happening when I work with REXML.
The program below should access elements of each xml file in the directory.
#!/usr/bin/ruby -w
require 'rexml/document'
include REXML
p "Current directory was: " + Dir.pwd
Dir.chdir("/home/askar/xml_files1") {
p "Now we're in: " + Dir.pwd
if File.exist?(Dir.pwd)
xml_files = Dir.glob("ShipmentRequest*.xml")
Dir.foreach(Dir.pwd) do |file|
xmlfile = File.new(file)
xmldoc = Document.new(xmlfile)
end
else
puts "It's empty"
end
}
When I run:
ruby import_xml.rb
Errors:
"Current directory was: /home/askar/Dropbox/rails_studio/xml_to_mysql"
"Now we're in: /home/askar/xml_files1"
There're 6226 files in the folder...
/home/askar/.rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/rexml/source.rb:148:in `read': Is a directory - . (Errno::EISDIR)
from /home/askar/.rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/rexml/source.rb:148:in `initialize'
from /home/askar/.rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/rexml/source.rb:14:in `new'
from /home/askar/.rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/rexml/source.rb:14:in `create_from'
from /home/askar/.rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/rexml/parsers/baseparser.rb:127:in `stream='
from /home/askar/.rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/rexml/parsers/baseparser.rb:116:in `initialize'
from /home/askar/.rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/rexml/parsers/treeparser.rb:9:in `new'
from /home/askar/.rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/rexml/parsers/treeparser.rb:9:in `initialize'
from /home/askar/.rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/rexml/document.rb:245:in `new'
from /home/askar/.rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/rexml/document.rb:245:in `build'
from /home/askar/.rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/rexml/document.rb:43:in `initialize'
from import_xml.rb:20:in `new'
from import_xml.rb:20:in `block (2 levels) in <main>'
from import_xml.rb:17:in `foreach'
from import_xml.rb:17:in `block in <main>'
from import_xml.rb:8:in `chdir'
from import_xml.rb:8:in `<main>'
When I comment out:
#xmldoc = Document.new(xmlfile)
it's not giving errors.
Folder /home/askar/xml_files1 contains only 3 xml files.
I'm using Linux Mint Nadia and
ruby -v
ruby 1.9.3p429 (2013-05-15 revision 40747) [x86_64-linux]
If you noticed, for some reason, error shows ruby 1.9.1. Is this an issue?
I think #halfelf is correct here. The API docs say that Dir.foreach will iterate over every entry in the directory - and in Unix, that includes the two directories . and ...
A couple lines before your Dir.foreach call, you use glob to build an array of files called xml_files. What happens if you iterate over that in your loop instead?
Just a guess: Not everything returned by Dir.foreach(Dir.pwd) is a file that can be read. Some of them are directories.
Using Nokogiri, here's how I'd write this:
#!/usr/bin/ruby -w
require 'nokogiri'
DIRNAME = "/home/askar/xml_files1"
puts "Current directory is: #{ Dir.pwd }"
Dir.chdir(DIRNAME) do
puts "Now in: #{ DIRNAME }"
xml_files = Dir.glob("ShipmentRequest*.xml")
if xml_files.empty?
puts "#{ DIRNAME } is empty."
else
xml_files.each do |file|
doc = Nokogiri::XML(open(file))
# ... do something with the doc ...
end
end
end

Resources