IronDigital-zippy 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +19 -0
- data/lib/zippy.rb +216 -0
- data/rails/README +18 -0
- data/rails/init.rb +23 -0
- metadata +66 -0
data/README
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Zippy.create 'awsum.zip' do |zip|
|
2
|
+
zip['README'] = 'In Soviet Russia, README READSYOU'
|
3
|
+
zip['porn.mpeg'] = File.open('rick astley - never gonna give you up.mpg')
|
4
|
+
end
|
5
|
+
|
6
|
+
Zippy.list('awsum.zip') #=> ['README', 'porn.mpeg']
|
7
|
+
|
8
|
+
Zippy.open('awsum.zip') do |zip|
|
9
|
+
zip['bin/hello_world'] = "#!/usr/bin/env ruby\n\nputs 'hello, zip world'"
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
#Your params as a zip
|
15
|
+
#It's SAAS!
|
16
|
+
require 'sinatra'
|
17
|
+
get '/' do
|
18
|
+
Zippy.new{|z| params.each{|k,v| z[k] = v } }.data
|
19
|
+
end
|
data/lib/zippy.rb
ADDED
@@ -0,0 +1,216 @@
|
|
1
|
+
require 'zip/zip'
|
2
|
+
|
3
|
+
class Zippy
|
4
|
+
|
5
|
+
include Enumerable
|
6
|
+
#extend Enumerable
|
7
|
+
|
8
|
+
|
9
|
+
#Make an archive
|
10
|
+
#Filename is optional; if none is provided, a generated, temporary
|
11
|
+
#filename will be used.
|
12
|
+
#If a block is provided, the archive is yielded
|
13
|
+
#Takes an optional second parameter which is a hash of entries that will
|
14
|
+
#be added after initialization
|
15
|
+
def initialize(entries_and_options={})
|
16
|
+
entries_and_options.each{|k,v| send("#{k}=", v) if respond_to?("#{k}=") && k.is_a?(Symbol) }
|
17
|
+
without_autocommit do
|
18
|
+
entries_and_options.each{|k,v| self[k] = v if k.is_a?(String) }
|
19
|
+
end
|
20
|
+
yield self if block_given?
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def each
|
25
|
+
zipfile.each{|e| yield e.name }
|
26
|
+
end
|
27
|
+
|
28
|
+
def size
|
29
|
+
zipfile.size
|
30
|
+
end
|
31
|
+
|
32
|
+
def empty?
|
33
|
+
size.zero?
|
34
|
+
end
|
35
|
+
|
36
|
+
#Returns the full path to all entries in the archive
|
37
|
+
def paths
|
38
|
+
map
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
#Read an entry
|
43
|
+
def [](entry)
|
44
|
+
return nil unless include?(entry)
|
45
|
+
zipfile.read(entry)
|
46
|
+
end
|
47
|
+
|
48
|
+
#Add or change an entry with the name +entry+
|
49
|
+
#+contents+ can be a string or an IO
|
50
|
+
def []=(entry, contents)
|
51
|
+
zipfile.get_output_stream entry do |s|
|
52
|
+
if contents.is_a?(String)
|
53
|
+
s.write contents
|
54
|
+
elsif contents.respond_to?(:read)
|
55
|
+
s.write contents.read(1024) until contents.eof?
|
56
|
+
elsif contents.respond_to?(:to_s)
|
57
|
+
s.write contents.to_s
|
58
|
+
else#Not sure these last two are different
|
59
|
+
s.write "#{contents}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
zipfile.commit if autocommit?
|
63
|
+
true
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
#Delete an entry
|
68
|
+
def delete(*entries)
|
69
|
+
entries.each do |entry|
|
70
|
+
zipfile.remove(entry)
|
71
|
+
end
|
72
|
+
zipfile.commit if autocommit?
|
73
|
+
entries
|
74
|
+
end
|
75
|
+
|
76
|
+
#Rename an entry
|
77
|
+
def rename(old_name, new_name)
|
78
|
+
zipfile.rename(old_name, new_name)
|
79
|
+
zipfile.commit if autocommit?
|
80
|
+
old_name
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
#Close the archive for writing
|
85
|
+
def close
|
86
|
+
write(filename)
|
87
|
+
zipfile.close
|
88
|
+
end
|
89
|
+
|
90
|
+
#Write the archive to +filename+
|
91
|
+
#If a filename is not provided, it will write
|
92
|
+
#to the default filename (self.filename)
|
93
|
+
def write(filename)
|
94
|
+
return false if empty?
|
95
|
+
zipfile.commit
|
96
|
+
unless filename == self.filename
|
97
|
+
FileUtils.cp(self.filename, filename)
|
98
|
+
end
|
99
|
+
true
|
100
|
+
end
|
101
|
+
|
102
|
+
#Returns the entire archive as a string
|
103
|
+
def data
|
104
|
+
return nil if empty?
|
105
|
+
zipfile.commit
|
106
|
+
File.read(filename)
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
def filename
|
111
|
+
@filename ||= random_filename
|
112
|
+
end
|
113
|
+
|
114
|
+
def filename=(filename)
|
115
|
+
rename_file(filename)
|
116
|
+
@filename = filename
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
def zipfile
|
121
|
+
@zipfile ||= Zip::ZipFile.new(filename, true)
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
#Create a new archive with the name +filename+, populate it
|
126
|
+
#and then close it
|
127
|
+
#
|
128
|
+
#Warning: Will overwrite existing file
|
129
|
+
def self.create(filename, options_and_entries={}, &b)
|
130
|
+
File.unlink(filename) if File.exists?(filename)
|
131
|
+
z = new({:filename => filename}.merge(options_and_entries), &b)
|
132
|
+
z.close
|
133
|
+
z
|
134
|
+
end
|
135
|
+
|
136
|
+
#Works the same as new, but require's an explicit filename
|
137
|
+
#If a block is provided, it will be closed at the end of the block
|
138
|
+
def self.open(filename, options_and_entries={})
|
139
|
+
raise(ArgumentError, "file \"#{filename}\" does not exist") unless File.exists?(filename)
|
140
|
+
z = new({:filename => filename}.merge(options_and_entries))
|
141
|
+
if block_given?
|
142
|
+
yield z
|
143
|
+
z.close
|
144
|
+
end
|
145
|
+
z
|
146
|
+
end
|
147
|
+
|
148
|
+
#Iterate each entry name _and_ its contents in the archive +filename+
|
149
|
+
def self.each(filename)
|
150
|
+
open(filename) do |zip|
|
151
|
+
zip.each do |name|
|
152
|
+
yield name, zip[name]
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
#Returns an array of entry names from the archive +filename+
|
158
|
+
#
|
159
|
+
#Zippy.list('my.zip') #=> ['foo', 'bar']
|
160
|
+
def self.list(filename)
|
161
|
+
list = nil
|
162
|
+
open(filename){|z| list = z.paths }
|
163
|
+
list
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
#Read the contents of a single entry in +filename+
|
168
|
+
def self.read(filename, entry)
|
169
|
+
content = nil
|
170
|
+
open(filename){|z| content = z[entry] }
|
171
|
+
content
|
172
|
+
end
|
173
|
+
|
174
|
+
|
175
|
+
def self.[](filename, entry=nil)
|
176
|
+
entry ? read(filename, entry) : list(filename)
|
177
|
+
end
|
178
|
+
|
179
|
+
def self.[]=(filename, entry, content)
|
180
|
+
open(filename){|z| z[entry] = content }
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
private
|
185
|
+
|
186
|
+
def random_filename
|
187
|
+
File.join(Dir.tmpdir, "zippy_#{Time.now.to_f.to_s}.zip")
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
def rename_file(new_name)
|
192
|
+
if @filename && @zipfile && File.exists?(@filename)
|
193
|
+
zipfile.close
|
194
|
+
File.rename(@filename, new_name)
|
195
|
+
end
|
196
|
+
@zipfile = nil #Force reload
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
def autocommit?
|
201
|
+
@autocommit.nil? ? true : @autocommit
|
202
|
+
end
|
203
|
+
|
204
|
+
def autocommit=(b)
|
205
|
+
@autocommit = !!b
|
206
|
+
end
|
207
|
+
|
208
|
+
def without_autocommit
|
209
|
+
ac = autocommit?
|
210
|
+
self.autocommit = false
|
211
|
+
yield
|
212
|
+
self.autocommit = ac
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
end
|
data/rails/README
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
This plugin adds a template handler for the extension "zipper", so you
|
2
|
+
could for example have a view show.zip.zipper which returns a zip file.
|
3
|
+
The view file is evaluated as Ruby, inside a Zippy.new{|zip|} block.
|
4
|
+
|
5
|
+
Example controller:
|
6
|
+
def show
|
7
|
+
@gallery = Gallery.find(params[:id])
|
8
|
+
respond_to do |format|
|
9
|
+
format.html
|
10
|
+
format.zip
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
Example view:
|
15
|
+
zip['description.txt'] = @gallery.description
|
16
|
+
@gallery.photos.each do |photo|
|
17
|
+
zip["photo_#{photo.id}.png"] = File.open(photo.url)
|
18
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'zippy'
|
2
|
+
|
3
|
+
Mime::Type.register 'application/zip', :zip
|
4
|
+
|
5
|
+
module ::ActionView
|
6
|
+
module TemplateHandlers
|
7
|
+
class Zipper < TemplateHandler
|
8
|
+
include Compilable
|
9
|
+
|
10
|
+
def compile(template)
|
11
|
+
"Zippy.new do |zip|" +
|
12
|
+
(template.respond_to?(:source) ? template.source : template) +
|
13
|
+
"end.data"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
if defined? ::ActionView::Template and ::ActionView::Template.respond_to? :register_template_handler
|
20
|
+
::ActionView::Template
|
21
|
+
else
|
22
|
+
::ActionView::Base
|
23
|
+
end.register_template_handler(:zipper, ::ActionView::TemplateHandlers::Zipper)
|
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: IronDigital-zippy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tore Darell
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-07-25 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: IronDigital-rubyzip
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.9.1
|
24
|
+
version:
|
25
|
+
description: Zippy reads and writes zip files
|
26
|
+
email: toredarell@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files: []
|
32
|
+
|
33
|
+
files:
|
34
|
+
- lib/zippy.rb
|
35
|
+
- README
|
36
|
+
- rails/init.rb
|
37
|
+
- rails/README
|
38
|
+
has_rdoc: false
|
39
|
+
homepage: http://github.com/toretore/zippy
|
40
|
+
licenses:
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
requirements: []
|
59
|
+
|
60
|
+
rubyforge_project:
|
61
|
+
rubygems_version: 1.3.5
|
62
|
+
signing_key:
|
63
|
+
specification_version: 2
|
64
|
+
summary: rubyzip for dummies
|
65
|
+
test_files: []
|
66
|
+
|