EzDevInfo.com

rubyzip

Offical Rubyzip repository

How to edit docx with nokogiri and rubyzip

I'm using a combination of rubyzip and nokogiri to edit a .docx file. I'm using rubyzip to unzip the .docx file and then using nokogiri to parse and change the body of the word/document.xml file but ever time I close rubyzip at the end it corrupts the file and I can't open it or repair it. I unzip the .docx file on desktop and check the word/document.xml file and the content is updated to what I changed it to but all the other files are messed up. Could someone help me with this issue? Here is my code:

require 'rubygems'  
require 'zip/zip'  
require 'nokogiri'  
zip = Zip::ZipFile.open("test.docx")  
doc = zip.find_entry("word/document.xml")  
xml = Nokogiri::XML.parse(doc.get_input_stream)  
wt = xml.root.xpath("//w:t", {"w" => "http://schemas.openxmlformats.org/wordprocessingml/2006/main"}).first  
wt.content = "New Text"  
zip.get_output_stream("word/document.xml") {|f| f << xml.to_s}  
zip.close

Source: (StackOverflow)

rails 3 and rubyzip 1.0.0 uninitialized constant Zip::ZipFile

Im attempting to open a docx file and write back into it using rubyzip 1.0.0 and rails 3.

In my gemfile I have:

gem 'rubyzip'

and the code i'm running is;

module Look

  class Generator

    def initialize(item)
      doc   = Nokogiri::XML.parse(item.to_xml)
      xslt  = Nokogiri::XSLT(File.read("<path_to_xslt_file>.xslt"))
      @outxml=xslt.transform(doc)
      zip = Zip::ZipFile.open("<path_to_docx_file>.docx")
      @outxml
    end

  end

end

While the @outxml is created correctly (I can manually add it to the docx file and see the results), I can't even begin with creating the zip file because of this...

uninitialized constant Zip::ZipFile

Having checked all the documentation and tried many combinations I'm still completely stumped.

Can anyone please tell me why this won't work?

Thanks.


Source: (StackOverflow)

Advertisements

What might explain an "invalid stored block lengths" error?

I am running a Rails (3.2.3) application with Ruby 1.9.3p194 on the basic Ubuntu lucid32 image in a Vagrant virtual box. The virtual box is running on Leopard, for what it's worth. I'm trying to use rubyzip in the application to decompress a zip archive - 2009_da_lmp.zip. Using code directly from examples in the rubyzip repository, I can confirm that I can list the archive file contents:

#f is the absolute path to 2009_da_lmp.zip (string)
Zip::ZipFile.open(f) { |zf| zf.entries[0] }  
 => 20090101_da_lmp.csv #that is indeed a file in the archive.

Using some more code from the examples in the repository, I try to get at an actual file in the archive:

Zip::ZipInputStream.open(f) { |zis|
  entry = zis.get_next_entry
  print "first line of '#{entry.name}' (#{entry.size} bytes: ) "
  puts "'#{zis.gets.chomp}'" }

=> first line of '20090101_da_lmp.csv' (826610 bytes: ) Zlib::DataError: 
   invalid stored block lengths #and a long stack trace I can provide 
                                #if that might help

The Mac OS decompression utility unzips the archive fine. I was wondering if it was some kind of encoding-related thing (my locale is set to en_US.UTF-8 because to make using PostgreSQL in dev less painful), but I don't know how to tell if that's the case. I can't find any information on what might cause this error.


Source: (StackOverflow)

rubyzip error when generating zips of images on the fly : End-of-central-directory signature not found

I'm generating a zip file from a collection of images which is then sent to the user.

I'm using code which is almost exactly the same as the example given on this page;

http://info.michael-simons.eu/2008/01/21/using-rubyzip-to-create-zip-files-on-the-fly/

It works absolutely fine on my local development box, but when I run it on my staging server, I get a zero length zipfile which has the following error when I try to open it.

'End-of-central-directory signature not found'

Obviously it's hard to troubleshoot where I'm going wrong when it works fine on my development machine!

Cheers, Graeme


Source: (StackOverflow)

How can I copy a directory inside a zip archive to a second zip archive using rubyzip?

I have a .zip archive containing several directories. Using the rubyzip gem I would like to reach into the .zip archive, copy a specified directory (and its contents) and move the directory into a second .zip archive.

Ideally I would not have to extract the contents of the first .zip archive, then re-zip them into a second archive. I'm hoping there is a way to use methods provided in the rubyzip gem.


Source: (StackOverflow)

rails 3 - LoadError (cannot load such file -- zip/zip)

I'm using rubyzip to zip a csv file so uses can download it. This works perfectly in development mode. But when I tried zipping the file on the production server (rackspace) I received the error: LoadError (cannot load such file -- zip/zip). Is it a path issue? Anyone know a fix?

The error is being called in my code on this line: require 'zip/zip'

I've tried the solution from here, but it didn't help.


Source: (StackOverflow)

rubyzip - private method `open' called for Zip::File:Class (Ruby on Rails 4)

I've added a helper method to my Application controller:

def unzip (file, destination)
    Zip::File.open(file) do |zip_file|
        zip_file.each do |f|
            f_path = File.join(destination, f.name)
            FileUtils.mkdir_p(File.dirname(f_path))
            f.extract(f_path) 
        end
    end
end

and I get the error:

private method `open' called for Zip::File:Class

When I run this in the Interactive Ruby shell, it works fine. How do I implement this on Rails 4?


Source: (StackOverflow)

Rubyzip vs native OS compression

I am wondering what would be the performance difference when zipping data using rubyzip as compared to using native os libraries for performing the compression. I am fetching data to be compressed from a URL and then using the ZipOutputStream to create the zip file. In case of native OS utilities I am thinking of using the zip tool. Would be nice to hear some pros and cons for both the approaches.


Source: (StackOverflow)

Set compression level when generating a ZIP file using RubyZip

I have a Ruby program that zips a directory tree of XML files using the rubyzip gem. My problem is that the file is starting to be heavy and I would like to increase the compression level, since compression time is not an issue.

I could not find in the rubyzip documentation a way to specify the compression level for the created ZIP file.

Anyone know how to change this setting? Is there another Ruby library that allows to specify compression level?


Source: (StackOverflow)

How to unzip password protected file via Ruby

I'd like to unzip an encrypted/password protected file via a Ruby script without dropping down to a system call. I currently use the rubyzip library to unzip files but don't see an option for working with encrypted files.

Anyone know of some code or a library that will do this?


Source: (StackOverflow)

Zipping a directory in Rails [closed]

How do i go about zipping a directory in ruby on rails? I've tried rubyzip without success. I don't need to zip the contents of the dir individually just zip the dir itself.


Source: (StackOverflow)

Opening a multipart/form-data ZIP file with rubyzip

I want to extract the files within a ZIP file I uploaded to my Rails app. The files within the ZIP file are going to be stored in the database.

I want to open the ZIP file in my action, without first having to save the file to a folder - I want to open the multipart/form-data stream with rubyzip.

It looks like rubyzip's ZipFile.open only takes a filename - not an IO stream.

What do I need to change within rubyzip, to allow me to open the zip file as a stream, like this:

Zip::ZipFile.open(params["zip_file"]) do |zip_file|
 ...
end

Thanks. Joerg


Source: (StackOverflow)

Subdirectories in Zip file using ZipOutputStream

I am creating a zip file using the technique described here:

http://info.michael-simons.eu/2008/01/21/using-rubyzip-to-create-zip-files-on-the-fly/

The client has asked that I include subdirectories in this zip file. I have searched the ZipOutputStream documentation but I see no way to include directories. Is there a way I can do this with ZipOutputStream? Should I be using a different class than ZipOutputStream?

Also, the files that I am zipping are not on the local filesystem, but are stored in a cloud service.


Source: (StackOverflow)

Rubyzip: Export zip file directly to S3 without writing tmpfile to disk?

I have this code, which writes a zip file to disk, reads it back, uploads to s3, then deletes the file:

compressed_file = some_temp_path

Zip::ZipOutputStream.open(compressed_file) do |zos|
  some_file_list.each do |file|
    zos.put_next_entry(file.some_title)
    zos.print IO.read(file.path)
  end
end # Write zip file

s3 = Aws::S3.new(S3_KEY, S3_SECRET)
bucket = Aws::S3::Bucket.create(s3, S3_BUCKET)
bucket.put("#{BUCKET_PATH}/archive.zip", IO.read(compressed_file), {}, 'authenticated-read')

File.delete(compressed_file)

This code works already but what I want is to not create the zip file anymore, to save a few steps. I was wondering if there is a way to export the zipfile data directly to s3 without having to first create a tmpfile, read it back, then delete it?


Source: (StackOverflow)

How do I get a temporary File object (of correct content-type, without writing to disk) directly from a ZipEntry (RubyZip, Paperclip, Rails 3)?

I'm currently trying to attach image files to a model directly from a zip file (i.e. without first saving them on a disk). It seems like there should be a clearer way of converting a ZipEntry to a Tempfile or File that can be stored in memory to be passed to another method or object that knows what to do with it.

Here's my code:

def extract (file = nil)
  Zip::ZipFile.open(file) { |zip_file|
    zip_file.each { |image|
      photo = self.photos.build
      # photo.image = image # this doesn't work
      # photo.image = File.open image # also doesn't work
      # photo.image = File.new image.filename
      photo.save
    }
  }
end

But the problem is that photo.image is an attachment (via paperclip) to the model, and assigning something as an attachment requires that something to be a File object. However, I cannot for the life of me figure out how to convert a ZipEntry to a File. The only way I've seen of opening or creating a File is to use a string to its path - meaning I have to extract the file to a location. Really, that just seems silly. Why can't I just extract the ZipEntry file to the output stream and convert it to a File there?

So the ultimate question: Can I extract a ZipEntry from a Zip file and turn it directly into a File object (or attach it directly as a Paperclip object)? Or am I stuck actually storing it on the hard drive before I can attach it, even though that version will be deleted in the end?

UPDATE Thanks to blueberry fields, I think I'm a little closer to my solution. Here's the line of code that I added, and it gives me the Tempfile/File that I need:

photo.image = zip_file.get_output_stream image

However, my Photo object won't accept the file that's getting passed, since it's not an image/jpeg. In fact, checking the content_type of the file shows application/x-empty. I think this may be because getting the output stream seems to append a timestamp to the end of the file, so that it ends up looking like imagename.jpg20110203-20203-hukq0n. Edit: Also, the tempfile that it creates doesn't contain any data and is of size 0. So it's looking like this might not be the answer.

So, next question: does anyone know how to get this to give me an image/jpeg file?

UPDATE:

I've been playing around with this some more. It seems output stream is not the way to go, but rather an input stream (which is which has always kind of confused me). Using get_input_stream on the ZipEntry, I get the binary data in the file. I think now I just need to figure out how to get this into a Paperclip attachment (as a File object). I've tried pushing the ZipInputStream directly to the attachment, but of course, that doesn't work. I really find it hard to believe that no one has tried to cast an extracted ZipEntry as a File. Is there some reason that this would be considered bad programming practice? It seems to me like skipping the disk write for a temp file would be perfectly acceptable and supported in something like Zip archive management.

Anyway, the question still stands:

Is there a way of converting an Input Stream to a File object (or Tempfile)? Preferably without having to write to a disk.


Source: (StackOverflow)