Getting "Unknown file type" in ruby - 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.

Related

Reading files in a zip archive, without unzipping the archive

I have a directory with 100+ zip files and I need to read the files inside the zip files to do some data processing, without unzipping the archive.
Is there a Ruby library to read the contents of files in zip archives, without unzipping the file?
Using rubyzip gives an error:
require 'zip'
Zip::File.open('my_zip.zip') do |zip_file|
# Handle entries one by one
zip_file.each do |entry|
# Extract to file/directory/symlink
puts "Extracting #{entry.name}"
entry.extract('here')
# Read into memory
content = entry.get_input_stream.read
end
end
Gives this error:
test.rb:12:in `block (2 levels) in <main>': undefined method `read' for Zip::NullInputStream:Module (NoMethodError)
from .gem/ruby/gems/rubyzip-1.1.6/lib/zip/entry_set.rb:42:in `call'
from .gem/ruby/gems/rubyzip-1.1.6/lib/zip/entry_set.rb:42:in `block in each'
from .gem/ruby/gems/rubyzip-1.1.6/lib/zip/entry_set.rb:41:in `each'
from .gem/ruby/gems/rubyzip-1.1.6/lib/zip/entry_set.rb:41:in `each'
from .gem/ruby/gems/rubyzip-1.1.6/lib/zip/central_directory.rb:182:in `each'
from test.rb:6:in `block in <main>'
from .gem/ruby/gems/rubyzip-1.1.6/lib/zip/file.rb:99:in `open'
from test.rb:4:in `<main>'
The Zip::NullInputStream is returned if the entry is a directory and not a file, could that be the case?
Here's a more robust variation of the code:
#!/usr/bin/env ruby
require 'rubygems'
require 'zip'
Zip::File.open('my_zip.zip') do |zip_file|
# Handle entries one by one
zip_file.each do |entry|
if entry.directory?
puts "#{entry.name} is a folder!"
elsif entry.symlink?
puts "#{entry.name} is a symlink!"
elsif entry.file?
puts "#{entry.name} is a regular file!"
# Read into memory
entry.get_input_stream { |io| content = io.read }
# Output
puts content
else
puts "#{entry.name} is something unknown, oops!"
end
end
end
I came across the same issue and checking for if entry.file?, before entry.get_input_stream.read, resolved the issue.
require 'zip'
Zip::File.open('my_zip.zip') do |zip_file|
# Handle entries one by one
zip_file.each do |entry|
# Extract to file/directory/symlink
puts "Extracting #{entry.name}"
entry.extract('here')
# Read into memory
if entry.file?
content = entry.get_input_stream.read
end
end
end

rspec bugs when trying to run rake

I'm trying to teach myself some ruby using the app academy tutorials and after doing the readings, installing rvm,rubygems and rspec2 when I even try to run the first most basic code (00_hello) with rake I get the whole error :
(in /home/deadpool/Documents/learn_ruby)
/home/deadpool/Documents/learn_ruby/rspec_config.rb:3:in `block in <top (required)>': undefined method `color=' for #<RSpec::Core::Configuration:0x0000000293dee0> (NoMethodError)
from /home/deadpool/.rvm/gems/ruby-2.0.0-p481/gems/rspec-core-2.0.0/lib/rspec/core.rb:67:in `configure'
from /home/deadpool/Documents/learn_ruby/rspec_config.rb:1:in `<top (required)>'
from /home/deadpool/.rvm/gems/ruby-2.0.0-p481/gems/rspec-core-2.0.0/lib/rspec/core/configuration.rb:162:in `require'
from /home/deadpool/.rvm/gems/ruby-2.0.0-p481/gems/rspec-core-2.0.0/lib/rspec/core/configuration.rb:162:in `block in requires='
from /home/deadpool/.rvm/gems/ruby-2.0.0-p481/gems/rspec-core-2.0.0/lib/rspec/core/configuration.rb:162:in `map'
from /home/deadpool/.rvm/gems/ruby-2.0.0-p481/gems/rspec-core-2.0.0/lib/rspec/core/configuration.rb:162:in `requires='
from /home/deadpool/.rvm/gems/ruby-2.0.0-p481/gems/rspec-core-2.0.0/lib/rspec/core/configuration_options.rb:22:in `block in configure'
from /home/deadpool/.rvm/gems/ruby-2.0.0-p481/gems/rspec-core-2.0.0/lib/rspec/core/configuration_options.rb:21:in `each'
from /home/deadpool/.rvm/gems/ruby-2.0.0-p481/gems/rspec-core-2.0.0/lib/rspec/core/configuration_options.rb:21:in `configure'
from /home/deadpool/.rvm/gems/ruby-2.0.0-p481/gems/rspec-core-2.0.0/lib/rspec/core/command_line.rb:17:in `run'
from /home/deadpool/.rvm/gems/ruby-2.0.0-p481/gems/rspec-core-2.0.0/lib/rspec/core/runner.rb:55:in `run_in_process'
from /home/deadpool/.rvm/gems/ruby-2.0.0-p481/gems/rspec-core-2.0.0/lib/rspec/core/runner.rb:46:in `run'
from /home/deadpool/.rvm/gems/ruby-2.0.0-p481/gems/rspec-core-2.0.0/lib/rspec/core/runner.rb:10:in `block in autorun'
rake aborted!
ruby -S bundle exec rspec -I/home/deadpool/Documents/learn_ruby/00_hello -I/home/deadpool/Documents/learn_ruby/00_hello/solution -f documentation -r ./rspec_config "/home/deadpool/Documents/learn_ruby/00_hello/hello_spec.rb" failed
/home/deadpool/.rvm/gems/ruby-2.0.0-p481/gems/rspec-core-2.0.0/lib/rspec/core/rake_task.rb:117:in `rescue in block (2 levels) in initialize'
/home/deadpool/.rvm/gems/ruby-2.0.0-p481/gems/rspec-core-2.0.0/lib/rspec/core/rake_task.rb:113:in `block (2 levels) in initialize'
/home/deadpool/.rvm/gems/ruby-2.0.0-p481/gems/rspec-core-2.0.0/lib/rspec/core/rake_task.rb:109:in `block in initialize'
Tasks: TOP => default => spec
(See full trace by running task with --trace)
I tried to google some of the errors, but with no success. I had previously another error with the rake file using rspec v2 and the current version is 3.0.0, so I had to install the older and I think it might be another setup problem. Thanks if someone can help me or direct me.
rspec_config.rb file :
RSpec.configure do |c|
c.fail_fast = true
c.color = true
end
hello.rb file:
def hello
"Hello!"
end
def greet(who)
"Hello, #{who}!"
end
UPDATE
Getting new error as :-
While I changed c.color = true to c.color_enabled = true
(in /home/deadpool/Documents/learn_ruby)
the hello function says hello (FAILED - 1)
Failures: 1) the hello function says hello Failure/Error:
Unable to find matching line from backtrace undefined method run_all' for []:Array
# /home/deadpool/.rvm/gems/ruby-2.1.2/gems/rspec-core-2.0.0/lib/rspec/core/hooks.rb:116:inrun_hook_filtered'
# /home/deadpool/.rvm/gems/ruby-2.1.2/gems/rspec-core-2.0.0/lib/rspec/core/example_group.rb:176:in eval_before_alls'
# /home/deadpool/.rvm/gems/ruby-2.1.2/gems/rspec-core-2.0.0/lib/rspec/core/example_group.rb:231:inrun'
# /home/deadpool/.rvm/gems/ruby-2.1.2/gems/rspec-core-2.0.0/lib/rspec/core/command_line.rb:26:in block (2 levels) in run'
# /home/deadpool/.rvm/gems/ruby-2.1.2/gems/rspec-core-2.0.0/lib/rspec/core/command_line.rb:26:inmap'
# /home/deadpool/.rvm/gems/ruby-2.1.2/gems/rspec-core-2.0.0/lib/rspec/core/command_line.rb:26:in block in run'
# /home/deadpool/.rvm/gems/ruby-2.1.2/gems/rspec-core-2.0.0/lib/rspec/core/reporter.rb:11:inreport'
# /home/deadpool/.rvm/gems/ruby-2.1.2/gems/rspec-core-2.0.0/lib/rspec/core/command_line.rb:23:in run'
# /home/deadpool/.rvm/gems/ruby-2.1.2/gems/rspec-core-2.0.0/lib/rspec/core/runner.rb:55:inrun_in_process'
# /home/deadpool/.rvm/gems/ruby-2.1.2/gems/rspec-core-2.0.0/lib/rspec/core/runner.rb:46:in run'
# /home/deadpool/.rvm/gems/ruby-2.1.2/gems/rspec-core-2.0.0/lib/rspec/core/runner.rb:10:inblock in autorun'
UPDATE
hello_spec.rb file :
require "hello"
describe "the hello function" do
it "says hello" do
hello.should == "Hello!"
end
end
describe "the greet function" do
it "says hello to someone" do
greet("Alice").should == "Hello, Alice!"
end
it "says hello to someone else" do
greet("Bob").should == "Hello, Bob!"
end
end
UPDATE
So, I updated rspec to v3.0.0 and changed Rakefile gem 'rspec', '~>3.0.0' and c.color = true back. Everything is working now(getting some deprecation warnings, but nothing critical), getting the output that is in the tutorial. Guess I just had to updae my rspec and change the version in the Rakefile. Thank you so much :)
Your error log is showing you are in rspec-core-2.0.0 version and your error is saying -
rspec_config.rb:3:in `block in <top (required)>': undefined method `color=' for
#<RSpec::Core::Configuration:0x0000000293dee0> (NoMethodError)
Now Deprecate config options confirms that below versions of 2.99.0.rc1 / 2014-05-18 or 2.99.0 methods were - #color_enabled, #color_enabled= and #color?. Which are changed since 2.99.0 to #color, #color= and #color_enabled?.
I got the information from the changelog as I linked -
Deprecate #color_enabled, #color_enabled= and #color? in favour of #color, #color= and #color_enabled? output. (Jon Rowe)
Thus you need to write as
RSpec.configure do |c|
c.fail_fast = true
c.color_enabled = true
end
Regarding your new error, I found it as a bug undefined methodrun_all' for []:Array`. Which has been fixed in this patch. Check this Rspec issue.
My suggestion use Rspec 3.0, at least you will be happy. In this case revert the color_enabled to color.
Hope this would help you.

Undefined method each in Ruby Regexp task

I have series of zip files under #workingdir, and am trying to unzip the files that match #Regexp, and print the lines from them.
require 'zip/zip'
#workingdir = '/my/dir/structure/*.zip'
#Regexp = '/yup:maybe.*nope/i'
Dir.glob(#workingdir) do |zips|
Zip::ZipFile.open(zips) do |file|
file.each do |search|
tempFile = file.read(search)
tempFile.each do |line|
if (line =~ #Regexp ) then
p line
end
end
end
end
end
Below is the error message from IRB:
NoMethodError: undefined method `each' for #<String:0x0000000168bf40>
from (irb):70:in `block (3 levels) in irb_binding'
from /var/lib/gems/1.9.1/gems/rubyzip2-2.0.2/lib/zip/zip.rb:1122:in `each'
from /var/lib/gems/1.9.1/gems/rubyzip2-2.0.2/lib/zip/zip.rb:1122:in `each'
from /var/lib/gems/1.9.1/gems/rubyzip2-2.0.2/lib/zip/zip.rb:1265:in `each'
from (irb):68:in `block (2 levels) in irb_binding'
from /var/lib/gems/1.9.1/gems/rubyzip2-2.0.2/lib/zip/zip.rb:1381:in `open'
from (irb):67:in `block in irb_binding'
from (irb):66:in `glob'
from (irb):66
from /usr/bin/irb:12:in `<main>'
I tried tempFile.grep, and received the same error, except that grep was an undefined method. I believe I need to define a class.
Turns out my code had two problems. 1) My regular expression was being processed as a string (I should not have used the quotes). 2) Seeing as it runs fine otherwise on Ruby 1.8.7, I suspect the is a difference in how 1.8.7 and 1.9.1 process the 'each' method. If anyone has additional insights, I'm more than happy to hear them. The code below works fine on 1.8.7:
require 'zip/zip'
#workingdir = '/my/dir/structure/*.zip'
#Regexp = /regexp/i
Dir.glob(#workingdir) do |zips|
Zip::ZipFile.open(zips) do |file|
file.each do |search|
tempFile = file.read(search)
tempFile.each do |line|
if (line =~ #Regexp) then
puts zips + ': ' + line.chomp
end
end
end
end
end
Thanks again everyone!

Serenity-odt under ruby 2.0 Encoding::CompatibilityError

Here is an issue: serenity-gem works perfectly under ruby 1.8.7 but something happens under ruby 2.0.0p195. While using the same template and ruby-code it gives me the following error:
incompatible character encodings: ASCII-8BIT and UTF-8 (Encoding::CompatibilityError)
/home/michael/.rvm/gems/ruby-2.0.0-p195/gems/serenity-odt-0.2.1/lib/serenity/generator.rb:5:in `render_odt'
/home/michael/.rvm/gems/ruby-2.0.0-p195/gems/serenity-odt-0.2.1/lib/serenity/odteruby.rb:17:in `eval'
/home/michael/.rvm/gems/ruby-2.0.0-p195/gems/serenity-odt-0.2.1/lib/serenity/odteruby.rb:17:in `evaluate'
/home/michael/.rvm/gems/ruby-2.0.0-p195/gems/serenity-odt-0.2.1/lib/serenity/template.rb:19:in `block (2 levels) in process'
/home/michael/.rvm/gems/ruby-2.0.0-p195/gems/serenity-odt-0.2.1/lib/serenity/template.rb:16:in `each'
/home/michael/.rvm/gems/ruby-2.0.0-p195/gems/serenity-odt-0.2.1/lib/serenity/template.rb:16:in `block in process'
/home/michael/.rvm/gems/ruby-2.0.0-p195/gems/rubyzip-0.9.9/lib/zip/zip_file.rb:90:in `open'
/home/michael/.rvm/gems/ruby-2.0.0-p195/gems/serenity-odt-0.2.1/lib/serenity/template.rb:15:in `process'
/home/michael/.rvm/gems/ruby-2.0.0-p195/gems/serenity-odt-0.2.1/lib/serenity/generator.rb:5:in `render_odt'
This solutions have no effect for me: github, stackoverflow.
My environment: Ubuntu 12.04.2 LTS x86_64 3.2.0-49-generic, rvm 1.21.2.
Fixed by adding string content = content.force_encoding('UTF-8') in /home/michael/.rvm/gems/ruby-2.0.0-p195/gems/serenity-odt-0.2.1/lib/serenity/template.rb
def process context
tmpfiles = []
Zip::ZipFile.open(#template) do |zipfile|
%w(content.xml styles.xml).each do |xml_file|
content = zipfile.read(xml_file)
content = content.force_encoding('UTF-8')
odteruby = OdtEruby.new(XmlReader.new(content))
out = odteruby.evaluate(context)
tmpfiles << (file = Tempfile.new("serenity"))
file << out
file.close
zipfile.replace(xml_file, file.path)
end
end
end
I got the inspiration from here.

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