2

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.

Satishakumar Awati
  • 3,604
  • 1
  • 29
  • 50

2 Answers2

2

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
Chandan
  • 11,465
  • 1
  • 6
  • 25
Pelton
  • 21
  • 2
1

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

Satishakumar Awati
  • 3,604
  • 1
  • 29
  • 50