rubyzip undefined method `to_binary_dos_time' for - ruby-on-rails

The below message getting logged when I try to open zip file with write mode.
Full Error Message :
undefined method `to_binary_dos_time' for 2017-05-30 15:07:21 +0530:Time
Backtrace :
["/usr/local/lib/ruby/gems/2.1.0/gems/rubyzip-0.9.9/lib/zip/zip_entry.rb:286:in `write_local_entry'",
"/usr/local/lib/ruby/gems/2.1.0/gems/rubyzip-0.9.9/lib/zip/zip_output_stream.rb:147:in `block in update_local_headers'",
"/usr/local/lib/ruby/gems/2.1.0/gems/rubyzip-0.9.9/lib/zip/zip_entry_set.rb:35:in `each'",
"/usr/local/lib/ruby/gems/2.1.0/gems/rubyzip-0.9.9/lib/zip/zip_entry_set.rb:35:in `each'",
"/usr/local/lib/ruby/gems/2.1.0/gems/rubyzip-0.9.9/lib/zip/zip_output_stream.rb:145:in `update_local_headers'",
"/usr/local/lib/ruby/gems/2.1.0/gems/rubyzip-0.9.9/lib/zip/zip_output_stream.rb:64:in `close'",
"/usr/local/lib/ruby/gems/2.1.0/gems/rubyzip-0.9.9/lib/zip/zip_output_stream.rb:50:in `ensure in open'",
"/usr/local/lib/ruby/gems/2.1.0/gems/rubyzip-0.9.9/lib/zip/zip_output_stream.rb:50:in `open'",
"/usr/local/lib/ruby/gems/2.1.0/gems/rubyzip-0.9.9/lib/zip/zip_file.rb:216:in `block in commit'",
"/usr/local/lib/ruby/gems/2.1.0/gems/rubyzip-0.9.9/lib/zip/zip_file.rb:324:in `on_success_replace'",
"/usr/local/lib/ruby/gems/2.1.0/gems/rubyzip-0.9.9/lib/zip/zip_file.rb:214:in `commit'",
"/usr/local/lib/ruby/gems/2.1.0/gems/rubyzip-0.9.9/lib/zip/zip_file.rb:242:in `close'",
"/usr/local/lib/ruby/gems/2.1.0/gems/rubyzip-0.9.9/lib/zip/zip_file.rb:92:in `open'",
"/app/zipper_job.rb:36:in `perform'",
My code is as below.
path="#{Rails.root}"
new_zip_name= "#{Time.now.to_i.to_s}"
archive = File.join(path,new_zip_name)+'.zip'
Zip::ZipFile.open(archive, 'w') do |zipfile| #Code breaking on this line
#MY Code
end
Any help appriciated!!
Thanks in advance.

Similar problem in both rubyzip and rzip, when trying to change the datetime of the zip entry to the original file datetime:
zf = Zip::File.open("myzipfile.zip", Zip::File::CREATE)
e = zf.add("myfiletozip.txt","myfiletozip.txt") # will set the zipfile date to now
e.time = File.mtime("myfiletozip.txt") # will set it to the original file's
So far so well, but when closing the zip file, the proc fails with the same error.
The problem is that "time=" creates the "extra" structure in the entry, which is then processed further, and that processing uses the missing method.
But why does it work without setting the time? The extra structure is not built, and the missing methods not used. As simple as that.
The to_binary_dos_time / date is present in the Gem: dos_time.rb
However, they seem to be incorrectly referenced by the gem procedures, in my case entry.rb
My circumvention. I simply copied the two methods into my code, extracted form the gem module dos_time.rb. And - miracle - it works. The gem procedure finds them locally and is happy.
However, this bug should be reported to the author, but i do not know how. Maybe someone can do this?
def to_binary_dos_time
(sec / 2) +
(min << 5) +
(hour << 11)
end
def to_binary_dos_date
day +
(month << 5) +
((year - 1980) << 9)
end
# source copied out of entry.rb in rubizyp gem, in my case:
# c:\Ruby27-x64\lib\ruby\gems\2.7.0\gems\rubyzip-2.3.0\lib\zip\dos_time.rb

I have created new file named config/initializers/patch.rb.
Added below code in it, this solved the issue.
Zip::DOSTime.instance_eval do
def now ; Zip::DOSTime.new() ; end
end
The patch I have taken from here

Related

Unable to use Mongoid::GridFs put to upload files

I'm just trying to use the mongoid-grid_fs gem in order to upload images and files to MongoDB.
The controller code in question currently looks like this:
grid_fs = Mongoid::GridFs
encFile = File.open(attFile)
File.open(encFile, 'wb') do |f|
f.write(encData)
end
grid_file = grid_fs.put(encFile.path)
I'm getting this error:
undefined method `destroy' for nil:NilClass
/GEMS/bundler/gems/mongoid-grid_fs-2f0e12e85a24/lib/mongoid/grid_fs.rb:150:in `put'
(eval):2:in `put'
/x/app/controllers/runtime/attachments_api_controller.rb:126:in `upload'
FYI line 126 in attachments_api_controller is the grid_fs.put line.
I'm not sure what the issue is.
I have also declared require 'mongoid/grid_fs'
I have put bindings around the issue, I can confirm that encFile.path is correct and it contains valid data.
EDIT 1: I've tried different combinations of trying to put the file like
grid_fs.put(encFile) - grid_fs.put(File.open(encFile.path)) - grid_fs.put(File.read(encFile.path)) but all of these still return the same error.

Rails 5 gem gon not recognize jbuilder file

I have implemented rails gem gon in index method and it works fine. But when I try to implement in controller#new it is not working this is my error output:
No such file or directory # rb_sysopen - app/views/cuenta_proveedors/new.json.jbuilder
but i have already create this file.
this is my controller
def new
#cuenta_proveedor = CuentaProveedor.new
#cuentas = #negocio.cuenta_proveedors.order(:created_at)
gon.jbuilder // THIS LINE CAUSE THE ERROR SHOWN BY APPLICATION TRACE
end
i have the created the file new.json.jbuiler
json.cuenta_proveedores #cuentas do |cc|
json.proveedor cc.proveedor.nombre
json.inicial cc.monto_inicial
json.saldo cc.monto_adeudado
json.observacion cc.observacion
json.token cc.token
end
Why is this happening? I can not found any logic to this error. If you need more information ask me . Thanks

rubyzip extracts empty file in activejob

I have a function in my activejob that extracts a specific file from a zip file. Following code extracted empty file.
def extract_file(from, name)
to = get_local_dest(name)
Zip::File.open(from) do |zip_file|
entry = zip_file.glob(name).first
puts entry.get_input_stream.read
entry.extract(to)
end
return to
end
I added a debugger and ran following line of code in console then the extracted file was not empty.
entry.extract(to)
Can anyone help me with this issue? Why this function is extract empty file when it runs in activejob?
your code seems to be fine. Please make sure your file is not saving again in code that proceeds.
There are chances that it extracted fine but later in code it was save again in empty form. This had happened to me in past :)
Let me know if this resolved your issue. :)

Invalid argument # rb_sysopen in Ruby on Rails application

I know this is the common question in this forum, but I tried last nearly 4 hours one by one not working for me. Worked before another method & another resource but not in this method.
Error below:
Invalid argument # rb_sysopen - https://example.s3.amazonaws.com/uploads/Data.pdf
When I use like below: Static File
#file = File.open("#{Rails.root}/public/Data.pdf")
Then
File.new(#file)
That is working but when like below:
Dynamic File
#file = File.open("#{papers.paper.url}") #=> output url: https://example.s3.amazonaws.com/uploads/Data.pdf
Then
File.new(#file)
That is showing error. I have tried string like w w+ r r+ etc.
What I'm doing wrong with this code?
Thanks

Carrierwave & Zipfiles: Using an extracted file as a version

Something I'm not getting about the version process...
I have a zip file with a file inside, and I want to upload the file as a "version" of the zip:
Uploader:
version :specificFile do
process :extract_file
end
def extract_file
file = nil
Zip::ZipFile.open(current_path) do |zip_file|
file = zip_file.select{|f| f.name.match(/specificFile/)}.first
zip_file.extract(file, "tmp/" + file.name.gsub("/", "-")){ true }
end
File.open("tmp/" + file.name.gsub("/", "-"))
end
Usage:
=link_to "Specific File", instance.uploader.specificFile.url
Only this just nets me two copies of the zip. Clearly, there's something I'm missing about how version / process works, and I haven't been able to find documentation that actually explains the magic.
So how do I do this, and what am I missing?
This provided the "why", although it took a bit to understand:
How do you create a new file in a CarrierWave process?
To rephrase, when you go to create a version, carrierwave makes a copy of the file and then passes the process the file path. When the process exits, carrierwave will upload the contents of that path - not the file the process returns, which is what I thought was going on.
Working code:
version :specificFile do
process :extract_file
def full_filename (for_file = model.logo.file)
"SpecificFile.ext"
end
end
def extract_plist
file = nil
Zip::ZipFile.open(current_path) do |zip_file|
file = zip_file.select{|f| f.name.match(/specificFile/)}.first
zip_file.extract(file, "tmp/" + file.name.gsub("/", "-")){ true }
end
File.delete(current_path)
FileUtils.cp("tmp/" + file.name.gsub("/", "-"), current_path)
end
So, to make what I want to happen, happen, I:
Tell carrierwave to use a particular filename. I'm using a hardcoded value but you should be able to use whatever you want.
Overwrite the contents of current_path with the contents you want under the version name. In my case, I can't just overwrite the zip while I'm "in it" (I think), so I make a copy of the file I care about and overwrite the zip via File and FileUtils.
PS - It would be nice to avoid the duplication of the zip, but it doesn't look like you can tell carrierwave to skip the duplication.

Resources